SQLのブロックコメント終端がバックスラッシュエスケープできるか軽く調べてみた(PostgreSQL, MySQL, SQLite3)

仕様・ソースコードレベルまでは調べてなくて実際の挙動を見ただけ。

ブロックコメント終端は2文字あるので、この3パターンを確認すればよさそう。
(1) \*/
(2) *\/
(3) \*\/

結果

コメント終端として認識される or 認識されない

|          | PostgreSQL | MySQL    | SQLite3  |
| -------- | ---------- | -------- | -------- |
| (1) \*/  | される     | される   | される   |
| (2) *\/  | されない   | されない | されない |
| (3) \*\/ | されない   | されない | されない |

当初は「バックスラッシュでエスケープできるか?」という観点で見ていたが、この結果を見ると
「(2) と (3) のパターンだとバックスラッシュでエスケープできる」
のではなく、単純に "*/" を探す動きになっていると考えられる。

(2) と (3) のパターンは * と / の間に余計な文字が入っているので、コメント終端とは見なされない(間に挟まっているのがバックスラッシュであるかどうかも関係ない)のではないかと。

以下、使ったクエリと確認手順のログ。

テスト用クエリ

$ cat -A block_1.sql
select 11, /*22\*/ 33 */ 44;$
--------------------------------
$ cat -A block_2.sql
select 11, /*22*\/ 33 */ 44;$
--------------------------------
$ cat -A block_3.sql
select 11, /*22\*\/ 33 */ 44;$
--------------------------------

どうせなのでついでに行末コメント末尾にバックスラッシュなパターンも見てみた。

$ cat -A single_1.sql
-- foo\$
select 12;$
--------------------------------

PostgreSQL

$ docker run -d --rm -v $(pwd):/work --name postgres postgres:10.5
27d2bb5fa4bd0f44869fab5104e5c63271db194ffe30da58e743da323f2a8d2f
--------------------------------

$ docker exec -it postgres psql -U postgres -f /work/block_1.sql
psql:/work/block_1.sql:1: ERROR:  operator does not exist: integer */ integer
LINE 1: select 11, /*22\*/ 33 */ 44;
                              ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

--------------------------------
$ docker exec -it postgres psql -U postgres -f /work/block_2.sql
 ?column? | ?column? 
----------+----------
       11 |       44
(1 row)

--------------------------------
$ docker exec -it postgres psql -U postgres -f /work/block_3.sql
 ?column? | ?column? 
----------+----------
       11 |       44
(1 row)

--------------------------------
$ docker exec -it postgres psql -U postgres -f /work/single_1.sql
 ?column? 
----------
       12
(1 row)
--------------------------------

MySQL

$ docker run -d --rm -v$(pwd):/work --name mysql -e MYSQL_ROOT_PASSWORD=fdsa mysql:5.7.23
--------------------------------

起動が完了するまで少し待ってから

$ docker exec -it mysql /bin/bash -c 'MYSQL_PWD=fdsa /usr/bin/mysql -uroot < /work/block_1.sql'
ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/ 44' at line 1
--------------------------------
$ docker exec -it mysql /bin/bash -c 'MYSQL_PWD=fdsa /usr/bin/mysql -uroot < /work/block_2.sql'
11	44
11	44
--------------------------------
$ docker exec -it mysql /bin/bash -c 'MYSQL_PWD=fdsa /usr/bin/mysql -uroot < /work/block_3.sql'
11	44
11	44
--------------------------------
$ docker exec -it mysql /bin/bash -c 'MYSQL_PWD=fdsa /usr/bin/mysql -uroot < /work/single_1.sql'
12
12
--------------------------------

SQLite3

※見やすくなるように適宜改行を追加しています

$ sqlite3 
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.

sqlite> select 11, /*22\*/ 33 */ 44;
Error: near "/": syntax error

sqlite> select 11, /*22*\/ 33 */ 44;
11|44

sqlite> select 11, /*22\*\/ 33 */ 44;
11|44

sqlite> -- foo\
sqlite> select 12;
12