同一SQLに対する、mysqlのバージョンによる動作の違い

最近のmysqlで、ASで作ったエイリアス名に1重引用符を付けてORDER BY指定したときの動作が変わりました。
DBサーバを移行してmysqlのバージョンを新しくしたら、PHPコード内のSQL動作結果が変わっていてびっくりしました。

具体例は以下、
[SQL]
$ mysql -u root mysql # mysql-server: 5.0.27
mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY cnt desc;
+—–+
| cnt |
+—–+
| 4 |
| 1 |
+—–+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY ‘cnt’ desc;
+—–+
| cnt |
+—–+
| 4 |
| 1 |
+—–+
2 rows in set (0.00 sec)
— cntも’cnt’も同じ動作
[/SQL]

[SQL]
$ mysql -u root mysql # mysql-server: 5.0.45
mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY cnt desc;
+—–+
| cnt |
+—–+
| 4 |
| 1 |
+—–+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) AS cnt FROM user
mysql> GROUP BY User ORDER BY ‘cnt’ desc;
+—–+
| cnt |
+—–+
| 1 |
| 4 |
+—–+
2 rows in set (0.00 sec)
— cntと’cnt’で違う動作
[/SQL]

ORDER BY ‘cnt’の ‘cnt’部分を文字列リテラルとみなすか、識別子とみなすかの差ですね。

IA-32のjmp, call命令でTrapするGDBスクリプト

jmp/call命令の実行直前までプログラムを進めるGDBスクリプトです。
こういう用途に使えるGDBコマンドがないようなので、自分で作りました。
必要な方はご自由に使ってください。
script.gdb

使い方は以下の通り、

$ gdb a.out
(gdb) source script.gdb
(gdb) break main
(gdb) run
# main関数でbreak

(gdb) run_until_call_jmp
# main関数内のcall or jmp命令直前で停止

jmp,call命令のop codeの調べ方

IA-32命令セットにおける、JMP, CALLのオペコードは下記の通りになりますIA-32 インテル アーキテクチャ・ソフトウェア・ディベロッパーズ・マニュアル 中巻より抜粋。http://www.intel.com/jp/download/index.htm

JMP命令のオペコード
callオペコード

cb、cw、cd、cpは、オペコードの後に続く1,2,4,6バイトの値です。
jmpやcall命令では、jmp/call先のアドレス値を表しています。

/2とか/3とかっていうのは、ModR/Mバイトのdigit(= op codeの一部) 上記マニュアルの2章(特に2.4~2.6)参照を表してます。
op codeの一部なので、当然、命令を判定する際にdigitのチェックが必要です。

digitは/0~/7まであり、ModR/Mバイトの下位3bitに対応します。

例えば32bitの絶対間接nearジャンプのオペコードは下記になります。

16進表記:  FF /4
2進表記 :  11111111 xxxxx100

xxxxxの部分の値によって、ジャンプ先のアドレス値として参照するレジスタ/メモリアドレスが変化します。
例えば、eaxレジスタに格納されたアドレス値へジャンプする場合は、xxxxx=11000 です。

こんな感じで命令のop codeを調べて実装したのが上記のGDBスクリプトです。
スクリプトを改造する時の参考にしてください。