べにやまぶろぐ

技術寄りの話を書くつもり

Mac でコーディングする人は「スマート引用符とスマートダッシュ」を OFF にしようという話

突然ですが問題です。

下記の一見同じに見える二つのクエリ、実は意味が異なるのですがその違いがわかりますでしょうか?

-- クエリ1
SELECT * FROM customers
WHERE customer_id IN ('0001', '0002', '0003', '0004');

-- クエリ2
SELECT * FROM customers
WHERE customer_id IN ('0001’, ’0002', '0003', '0004');

これでわかったらかなりの選球眼の持ち主です。

それでは試しにシンタックスハイライトをかけてみましょう。

-- クエリ1
SELECT * FROM customers
WHERE customer_id IN ('0001', '0002', '0003', '0004');

-- クエリ2
SELECT * FROM customers
WHERE customer_id IN ('0001’, ’0002', '0003', '0004');

いかがでしょうか?これでもよく見ないとわからないと思います。

正解は、クエリ1の customer_id の一致条件が 00010002000300044パターンなのに対し、クエリ2は 0001’, ’0002000300043パターンだということです。よく見るとクエリ2の IN 句内の最初のカンマが文字列の一部になっているのがわかると思います。

明らかに意図したクエリになっていないのですが、なぜそもそもこんなことが起きるかというと問題は Mac 標準の入力サポート機能にありました。

「システム環境設定」から「キーボード」を開くと「ユーザ辞書」のタブ内に「スマート引用符とスマートダッシュを使用」という項目があります。

f:id:beniyama:20150924232105p:plain

これが ON になっているとテキストエディタなどで SQL を編集した際に勝手にシングルクォーテーションや二重引用符を変換されてしまい、予期せぬ意味のクエリになってしまう可能性があります。

https://support.apple.com/kb/PH14294?locale=ja_JP&viewlocale=ja_JP によれば

まっすぐな引用符を体裁上適切な(「丸い」)引用符に自動的に置き換えます。

とあります。体裁上は適切かもしれませんがコーディング上は不適切なわけです。

自分のケースでは軽く Evernote 上でコピペと編集を繰り返しているうちに、上述のようなエラーにはならないんだけど意味が違うクエリが生まれてしまいました。検算して初めて問題と原因に気づいたので軽く冷や汗かきました。

ちょっとしたクエリなどは手元のエディタで編集して〜とやりたくなりますが、Mac を使われる場合はその前に一度キーボードの設定を見直そうというお話でした。

参考)