PostgreSQL にバグレポートをした話

## はじめに

みなさんは RDBMS を使っていますか？この記事を読んでいる方であれば使っていることが多いと思います。
RDBMS って、アプリケーション一式の中でも、一番堅牢で、最後の砦的なイメージがありますよね。つまり、最初から RDBMS のバグを疑うという事はあまりなく、だいたいは自分の書いたコードが間違っているという事が多いわけです。
この記事は、そんな RDBMS のバグを発見してしまって、じゃあどうする、と途方に暮れていたところ、コミュニティの協力のもと、バグレポートをしたという話です。以下は詳細です

## どういうバグか

ある日、同僚から「なんか集計が合わないんじゃが......」という報告が上がってきました。再現条件つきだったので、試してみると以下のような状態になっていて、確かに集計が合ってない......

### まず、適当なテーブルを作成して行を挿入する

- `temp_values` は全部で 3,000,000 件

```sql
CREATE TEMP TABLE temp_values (
  id serial,
  target_id integer,
  date date
);
CREATE INDEX index_temp_values_target_id ON temp_values (target_id);

INSERT INTO temp_values (target_id, date)
SELECT id, '2016-04-01'::date + (random() * generate_series(1, 100))::integer
  FROM (SELECT generate_series(1, 30000)) AS sub(id);
-- INSERT 0 3000000

VACUUM ANALYZE temp_values;

CREATE TEMP TABLE temp_targets (
  target_id integer,
  label text
);
INSERT INTO temp_targets(target_id, label)
select t.id, row_number() OVER(PARTITION BY t.id)::text
from (values (14933), (14905), (14931), (14975), (14888), (14891), (14894), (14895), (14892), (14923), (14887), (14890), (14935), (18757), (14964), (14962), (24524), (14936), (17858), (14937), (23071), (14896), (17856), (14906), (14918), (14971), (17020), (14972), (17025), (17026), (14977), (14978), (14897), (14907), (14919), (20832), (14953), (14947), (14955), (14951), (18452), (14954), (21373), (14945), (14949), (20771), (24556), (24418), (26738), (22856), (23542), (24557), (24419), (26440), (22857), (17859), (23543), (14921), (14976), (14946), (14952), (14974), (14909), (14922), (14966), (14941), (14903), (2316), (14938), (2520), (14934), (14942), (14939), (14910), (14924), (14965), (14963), (26443), (26441), (26442), (18462), (18463), (18464), (18465), (18470), (18466), (18467), (18468), (18469), (18453), (18454), (18455), (18456), (18461), (18457), (18458), (18459), (18460), (14898), (14911), (14925), (14912), (14926), (14915), (14929), (21487), (17018), (27184), (23753), (14916), (21488), (17857), (27185), (23754), (14930), (14904), (14917), (20180), (14932), (14913), (14927), (14970), (14959), (14960), (14902), (22855), (14899), (14943), (14944), (14969), (14968), (18668), (14950), (17160), (14914), (14928), (14948), (14956), (14958), (18756), (14957), (14900), (14901), (14908), (14920), (14967), (14889), (14893), (2313), (14940), (25908), (25909), (25912), (18473), (25910), (25911), (16898), (25851), (16899), (16904), (16900), (16901), (16902), (16903), (20772), (17019), (17021), (16905), (16906), (16907), (16908), (16909), (16910), (16911), (17022), (16912), (16913), (18471), (18472), (16922), (21374), (16917), (16914), (17023), (16915), (16916), (21375), (16918), (16919), (16920), (16921), (20773), (17024), (25852), (25853), (25854), (25855), (25856), (26739), (25857), (25858), (25859), (25875), (26444), (25879), (25865), (25864), (25860), (25861), (25862), (25863), (25866), (25867), (25868), (25869), (25870), (25871), (25872), (25873), (25874), (25876), (25877), (25878), (25880), (25881), (25882), (25883), (25884), (26740), (25885), (25886), (25887), (25903), (26445), (25907), (25893), (25892), (25888), (25889), (25890), (25891), (25894), (25895), (25896), (25897), (25898), (25899), (25900), (25901), (25902), (25904), (25905), (25906), (14961), (14933), (14905), (14931), (14975), (14888), (14891), (14894), (14895), (14892), (14923), (14887), (14890), (14935), (18757), (14964), (14962), (24524), (14936), (17858), (14937), (23071), (14896), (17856), (14906), (14918), (14897), (14907), (14919), (20832), (14953), (14947), (14955), (14951), (18452), (14954), (21373), (14945), (14949), (20771), (24556), (24418), (26738), (22856), (23542), (24557), (24419), (26440), (22857), (17859), (23543), (14921), (14946), (14952), (14974), (14909), (14922), (14966), (14941), (14903), (2316), (14938), (2520), (14934), (14942), (14939), (14910), (14924), (14965), (14963), (26443), (26441), (26442), (18462), (18463), (18464), (18465), (18470), (18466), (18467), (18468), (18469), (18453), (18454), (18455), (18456), (18461), (18457), (18458), (18459), (18460), (14898), (14911), (14925), (14912), (14926), (14915), (14929), (21487), (17018), (27184), (23753), (14916), (21488), (17857), (27185), (23754), (14930), (14904), (14917), (20180), (14932), (14913), (14927), (14970), (14959), (14960), (14902), (22855), (14899), (14943), (14944), (14969), (14968), (18668), (14950), (17160), (14914), (14928), (14948), (14956), (14958), (18756), (14957), (14900), (14901), (14908), (14920), (14967), (14889), (14893), (2313), (14940), (14961)) AS t(id);
```

### temp_targets は 254 件です

```sql
SELECT COUNT(DISTINCT target_id)
  FROM temp_targets ;
-- 254
```

### 254 種類の target_id で IN を使って絞り込みます

- target_id ごとに 100 件入っているので、25,400 件あるはずです

```sql
SELECT COUNT(DISTINCT temp_values.id)
  FROM temp_values
 WHERE temp_values.target_id IN (14933, 14905, 14931, 14975, 14888, 14891, 14894, 14895, 14892, 14923, 14887, 14890, 14935, 18757, 14964, 14962, 24524, 14936, 17858, 14937, 23071, 14896, 17856, 14906, 14918, 14971, 17020, 14972, 17025, 17026, 14977, 14978, 14897, 14907, 14919, 20832, 14953, 14947, 14955, 14951, 18452, 14954, 21373, 14945, 14949, 20771, 24556, 24418, 26738, 22856, 23542, 24557, 24419, 26440, 22857, 17859, 23543, 14921, 14976, 14946, 14952, 14974, 14909, 14922, 14966, 14941, 14903, 2316, 14938, 2520, 14934, 14942, 14939, 14910, 14924, 14965, 14963, 26443, 26441, 26442, 18462, 18463, 18464, 18465, 18470, 18466, 18467, 18468, 18469, 18453, 18454, 18455, 18456, 18461, 18457, 18458, 18459, 18460, 14898, 14911, 14925, 14912, 14926, 14915, 14929, 21487, 17018, 27184, 23753, 14916, 21488, 17857, 27185, 23754, 14930, 14904, 14917, 20180, 14932, 14913, 14927, 14970, 14959, 14960, 14902, 22855, 14899, 14943, 14944, 14969, 14968, 18668, 14950, 17160, 14914, 14928, 14948, 14956, 14958, 18756, 14957, 14900, 14901, 14908, 14920, 14967, 14889, 14893, 2313, 14940, 25908, 25909, 25912, 18473, 25910, 25911, 16898, 25851, 16899, 16904, 16900, 16901, 16902, 16903, 20772, 17019, 17021, 16905, 16906, 16907, 16908, 16909, 16910, 16911, 17022, 16912, 16913, 18471, 18472, 16922, 21374, 16917, 16914, 17023, 16915, 16916, 21375, 16918, 16919, 16920, 16921, 20773, 17024, 25852, 25853, 25854, 25855, 25856, 26739, 25857, 25858, 25859, 25875, 26444, 25879, 25865, 25864, 25860, 25861, 25862, 25863, 25866, 25867, 25868, 25869, 25870, 25871, 25872, 25873, 25874, 25876, 25877, 25878, 25880, 25881, 25882, 25883, 25884, 26740, 25885, 25886, 25887, 25903, 26445, 25907, 25893, 25892, 25888, 25889, 25890, 25891, 25894, 25895, 25896, 25897, 25898, 25899, 25900, 25901, 25902, 25904, 25905, 25906, 14961, 14933, 14905, 14931, 14975, 14888, 14891, 14894, 14895, 14892, 14923, 14887, 14890, 14935, 18757, 14964, 14962, 24524, 14936, 17858, 14937, 23071, 14896, 17856, 14906, 14918, 14897, 14907, 14919, 20832, 14953, 14947, 14955, 14951, 18452, 14954, 21373, 14945, 14949, 20771, 24556, 24418, 26738, 22856, 23542, 24557, 24419, 26440, 22857, 17859, 23543, 14921, 14946, 14952, 14974, 14909, 14922, 14966, 14941, 14903, 2316, 14938, 2520, 14934, 14942, 14939, 14910, 14924, 14965, 14963, 26443, 26441, 26442, 18462, 18463, 18464, 18465, 18470, 18466, 18467, 18468, 18469, 18453, 18454, 18455, 18456, 18461, 18457, 18458, 18459, 18460, 14898, 14911, 14925, 14912, 14926, 14915, 14929, 21487, 17018, 27184, 23753, 14916, 21488, 17857, 27185, 23754, 14930, 14904, 14917, 20180, 14932, 14913, 14927, 14970, 14959, 14960, 14902, 22855, 14899, 14943, 14944, 14969, 14968, 18668, 14950, 17160, 14914, 14928, 14948, 14956, 14958, 18756, 14957, 14900, 14901, 14908, 14920, 14967, 14889, 14893, 2313, 14940, 14961);
-- 25400
```

### 254 種類の target_id が入ったテーブルを JOIN します

- これも、やはり 25,400 件になるはずです

```sql
SELECT COUNT(DISTINCT temp_values.id)
  FROM temp_values
  JOIN temp_targets USING (target_id);
-- 25400
```

### であれば、WHERE と JOIN を組み合わせても、同じ結果になるはず

```sql
SELECT COUNT(DISTINCT temp_values.id)
  FROM temp_values
  JOIN temp_targets USING (target_id)
 WHERE temp_values.target_id IN (14933, 14905, 14931, 14975, 14888, 14891, 14894, 14895, 14892, 14923, 14887, 14890, 14935, 18757, 14964, 14962, 24524, 14936, 17858, 14937, 23071, 14896, 17856, 14906, 14918, 14971, 17020, 14972, 17025, 17026, 14977, 14978, 14897, 14907, 14919, 20832, 14953, 14947, 14955, 14951, 18452, 14954, 21373, 14945, 14949, 20771, 24556, 24418, 26738, 22856, 23542, 24557, 24419, 26440, 22857, 17859, 23543, 14921, 14976, 14946, 14952, 14974, 14909, 14922, 14966, 14941, 14903, 2316, 14938, 2520, 14934, 14942, 14939, 14910, 14924, 14965, 14963, 26443, 26441, 26442, 18462, 18463, 18464, 18465, 18470, 18466, 18467, 18468, 18469, 18453, 18454, 18455, 18456, 18461, 18457, 18458, 18459, 18460, 14898, 14911, 14925, 14912, 14926, 14915, 14929, 21487, 17018, 27184, 23753, 14916, 21488, 17857, 27185, 23754, 14930, 14904, 14917, 20180, 14932, 14913, 14927, 14970, 14959, 14960, 14902, 22855, 14899, 14943, 14944, 14969, 14968, 18668, 14950, 17160, 14914, 14928, 14948, 14956, 14958, 18756, 14957, 14900, 14901, 14908, 14920, 14967, 14889, 14893, 2313, 14940, 25908, 25909, 25912, 18473, 25910, 25911, 16898, 25851, 16899, 16904, 16900, 16901, 16902, 16903, 20772, 17019, 17021, 16905, 16906, 16907, 16908, 16909, 16910, 16911, 17022, 16912, 16913, 18471, 18472, 16922, 21374, 16917, 16914, 17023, 16915, 16916, 21375, 16918, 16919, 16920, 16921, 20773, 17024, 25852, 25853, 25854, 25855, 25856, 26739, 25857, 25858, 25859, 25875, 26444, 25879, 25865, 25864, 25860, 25861, 25862, 25863, 25866, 25867, 25868, 25869, 25870, 25871, 25872, 25873, 25874, 25876, 25877, 25878, 25880, 25881, 25882, 25883, 25884, 26740, 25885, 25886, 25887, 25903, 26445, 25907, 25893, 25892, 25888, 25889, 25890, 25891, 25894, 25895, 25896, 25897, 25898, 25899, 25900, 25901, 25902, 25904, 25905, 25906, 14961, 14933, 14905, 14931, 14975, 14888, 14891, 14894, 14895, 14892, 14923, 14887, 14890, 14935, 18757, 14964, 14962, 24524, 14936, 17858, 14937, 23071, 14896, 17856, 14906, 14918, 14897, 14907, 14919, 20832, 14953, 14947, 14955, 14951, 18452, 14954, 21373, 14945, 14949, 20771, 24556, 24418, 26738, 22856, 23542, 24557, 24419, 26440, 22857, 17859, 23543, 14921, 14946, 14952, 14974, 14909, 14922, 14966, 14941, 14903, 2316, 14938, 2520, 14934, 14942, 14939, 14910, 14924, 14965, 14963, 26443, 26441, 26442, 18462, 18463, 18464, 18465, 18470, 18466, 18467, 18468, 18469, 18453, 18454, 18455, 18456, 18461, 18457, 18458, 18459, 18460, 14898, 14911, 14925, 14912, 14926, 14915, 14929, 21487, 17018, 27184, 23753, 14916, 21488, 17857, 27185, 23754, 14930, 14904, 14917, 20180, 14932, 14913, 14927, 14970, 14959, 14960, 14902, 22855, 14899, 14943, 14944, 14969, 14968, 18668, 14950, 17160, 14914, 14928, 14948, 14956, 14958, 18756, 14957, 14900, 14901, 14908, 14920, 14967, 14889, 14893, 2313, 14940, 14961);
-- EXPECT 25400, but RESULT 25300 on 9.5 and 9.6
```

- が、ダメ！
- なぜか、PostgreSQL 9.5.2, 9.5.3, 9.6.0 では 100 件減る！
- そんなことってある？

## とりあえず

- まず、いろんな人から情報を聞きたいところですが、今起きている状況を簡単に試せるように、Docker で環境を作ってみました -> [strange_postgresql_9_5](https://github.com/yancya/strange_postgresql_9_5)
- Docker を使えば、いろんなバージョンの PostgreSQL をサクサク試すことができて便利です

## Twitter

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【緩募】 <a href="https://t.co/h225mE1ZiP">https://t.co/h225mE1ZiP</a><br>PostgreSQL 9.4 と 9.5 で結果が変わってしまう件で死んでます… どなたか、原因がピンと来たら教えて下さい…</p>&mdash; yancya (@yancya) <a href="https://twitter.com/yancya/status/737195728309649408">2016年5月30日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

- Twitter で緩募したら、一時間くらいで急所を言い当てる人が現れて凄かったです

<img width="505" alt="スクリーンショット_2016_12_17_14_22.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/87740974-ee1e-3701-8148-4ffdf711d7fe.png">

```sql
set enable_mergejoin to off;

SELECT COUNT(DISTINCT temp_values.id)
  FROM temp_values
  JOIN temp_targets USING (target_id)
 WHERE temp_values.target_id IN (14933, 14905, 14931, 14975, 14888, 14891, 14894, 14895, 14892, 14923, 14887, 14890, 14935, 18757, 14964, 14962, 24524, 14936, 17858, 14937, 23071, 14896, 17856, 14906, 14918, 14971, 17020, 14972, 17025, 17026, 14977, 14978, 14897, 14907, 14919, 20832, 14953, 14947, 14955, 14951, 18452, 14954, 21373, 14945, 14949, 20771, 24556, 24418, 26738, 22856, 23542, 24557, 24419, 26440, 22857, 17859, 23543, 14921, 14976, 14946, 14952, 14974, 14909, 14922, 14966, 14941, 14903, 2316, 14938, 2520, 14934, 14942, 14939, 14910, 14924, 14965, 14963, 26443, 26441, 26442, 18462, 18463, 18464, 18465, 18470, 18466, 18467, 18468, 18469, 18453, 18454, 18455, 18456, 18461, 18457, 18458, 18459, 18460, 14898, 14911, 14925, 14912, 14926, 14915, 14929, 21487, 17018, 27184, 23753, 14916, 21488, 17857, 27185, 23754, 14930, 14904, 14917, 20180, 14932, 14913, 14927, 14970, 14959, 14960, 14902, 22855, 14899, 14943, 14944, 14969, 14968, 18668, 14950, 17160, 14914, 14928, 14948, 14956, 14958, 18756, 14957, 14900, 14901, 14908, 14920, 14967, 14889, 14893, 2313, 14940, 25908, 25909, 25912, 18473, 25910, 25911, 16898, 25851, 16899, 16904, 16900, 16901, 16902, 16903, 20772, 17019, 17021, 16905, 16906, 16907, 16908, 16909, 16910, 16911, 17022, 16912, 16913, 18471, 18472, 16922, 21374, 16917, 16914, 17023, 16915, 16916, 21375, 16918, 16919, 16920, 16921, 20773, 17024, 25852, 25853, 25854, 25855, 25856, 26739, 25857, 25858, 25859, 25875, 26444, 25879, 25865, 25864, 25860, 25861, 25862, 25863, 25866, 25867, 25868, 25869, 25870, 25871, 25872, 25873, 25874, 25876, 25877, 25878, 25880, 25881, 25882, 25883, 25884, 26740, 25885, 25886, 25887, 25903, 26445, 25907, 25893, 25892, 25888, 25889, 25890, 25891, 25894, 25895, 25896, 25897, 25898, 25899, 25900, 25901, 25902, 25904, 25905, 25906, 14961, 14933, 14905, 14931, 14975, 14888, 14891, 14894, 14895, 14892, 14923, 14887, 14890, 14935, 18757, 14964, 14962, 24524, 14936, 17858, 14937, 23071, 14896, 17856, 14906, 14918, 14897, 14907, 14919, 20832, 14953, 14947, 14955, 14951, 18452, 14954, 21373, 14945, 14949, 20771, 24556, 24418, 26738, 22856, 23542, 24557, 24419, 26440, 22857, 17859, 23543, 14921, 14946, 14952, 14974, 14909, 14922, 14966, 14941, 14903, 2316, 14938, 2520, 14934, 14942, 14939, 14910, 14924, 14965, 14963, 26443, 26441, 26442, 18462, 18463, 18464, 18465, 18470, 18466, 18467, 18468, 18469, 18453, 18454, 18455, 18456, 18461, 18457, 18458, 18459, 18460, 14898, 14911, 14925, 14912, 14926, 14915, 14929, 21487, 17018, 27184, 23753, 14916, 21488, 17857, 27185, 23754, 14930, 14904, 14917, 20180, 14932, 14913, 14927, 14970, 14959, 14960, 14902, 22855, 14899, 14943, 14944, 14969, 14968, 18668, 14950, 17160, 14914, 14928, 14948, 14956, 14958, 18756, 14957, 14900, 14901, 14908, 14920, 14967, 14889, 14893, 2313, 14940, 14961);
-- 25400
```

- 確かに、`set enable_mergejoin to off;` とすると直る
- ええええ...... ええええ......
- これにより `set enable_mergejoin to off;` すると直るという情報が増えました

## チャット（Slack）

- Twitter もいいですが、もっと詳しそうな人たちに相談したいですよね。PostgreSQL の事で困ったら、Slack がおすすめです
- JPUG（日本 PostgreSQL ユーザ会）の Slack は[こちら](https://postgresql-hackers-jp.herokuapp.com)から登録して入室することができます

<img width="773" alt="Slack_-_postgresql-jp 5.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/98aa8580-1e4b-7624-0273-382bf2f2259d.png">
<img width="769" alt="Slack_-_postgresql-jp 4.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/aaad1d95-39e8-a351-a9a7-0ede84534b87.png">
<img width="763" alt="Banners_and_Alerts_と_Slack_-_postgresql-jp.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/5e258c59-2fa9-16e7-1fd3-7df06e365f1c.png">
<img width="744" alt="Banners_and_Alerts_と_Slack_-_postgresql-jp 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/213efe0a-2226-cdb1-fa5d-f54b6ced948b.png">

### レポートは英語で書かないといけませんが、経験豊富な人たちがいろいろ教えてくれます

<img width="756" alt="Slack_-_postgresql-jp 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/9c9c8ec3-39fd-1525-95cc-cef3cb3b0407.png">

### 報告した

<img width="435" alt="Slack_-_postgresql-jp 6.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/62669767-312b-998c-af2d-8a02154fe265.png">

- [当該レポート](https://www.postgresql.org/message-id/20160601065921.30388.33069@wrigleys.postgresql.org)


### レポートしたらすぐに修正パッチがコミットされました。PostgreSQL 開発者たち凄い

- そして「なんか壊れてるっぽいっす」って報告しただけなのに名前が載って恐縮です

<img width="631" alt="Slack_-_postgresql-jp 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/58c5ca61-8ff9-ff87-68cf-db7a898f391a.png">

- [当該コミット](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=7392eed7c2a327eb1b496f30a64be33404bcf82e)

### 直ったバージョンがリリースされた
 
<img width="755" alt="Slack_-_postgresql-jp.png" src="https://qiita-image-store.s3.amazonaws.com/0/9513/b6a00207-bea3-384e-593f-68829d24c967.png">

## まとめ

- RDBMS であっても、希にバグがあることがある
- 詳しそうな人たちがいる溜まり場で相談してみよう
- バグレポートをすると、開発者がシュッと直してくれて凄い
- バグレポートはそんなに大変じゃないので、再現条件をピピッと作って報告すると良い
- 別にコントリビュートマンにならなくてもいいが、自分でぶち当たったバグについてレポートするくらいなら、わしにもできるので、今後も機会があったらやっていきたい

## おまけ

- あ、すごい偶然なんですけど、今日、わしの誕生日です。毎年、みなさまのおかげで生かされております。[毎度どうもありがとうございます](http://yancya.jp/hoshi_wish)