实现自己的数据库驱动——MySQL协议Result Set包解析(六)

前言

上一篇中当执行了INSERT、UPDATE or ALTER TABLE操作时,会生成对应的OK/Error包。而我们这篇要说明的是SELECT结果Result Set的解析。Result Set会涉及到了多个不同结构的包,有Column_Count、Column_DefEOFRow

Result Set包简析

用一张图片来简单解析一下每个包的具体作用。

你想输入的替代文字

从上图来看,客户端发送一个select的com_query包之后,DB会按照下列步骤返回:

1.返回一个 Protocol::LengthEncodedInteger ,其中数据为column_count.(该表的显示返回中字段的个数)

2.接下来会跟column_count个Protocol::ColumnDefinition 包(对每一个字段的说明).

3.再读取一个eof包表示ColumnDefinition包流结束.

4.读取n个Row包,Row含有请求的数据值。

6.如果读到任何一个error包之后,从此读取结束,抛出错误.

7.或者你读取到了第二个eof包,按照正常顺序这里就会结束了. 但是:

如果eof包中的status & SERVER_MORE_RESULT_EXISTS不为0,表明还有ResultSet,则返回到步骤1,开始读取下一个ResultSet.

Column_count Packet

该包前四个字节表示的包的字节长度以及包的序列号。后面存放的是一个类型为LengthEncodeInteger表示结果中含有几个列。Number of fields显示该返回字段有2列。

你想输入的替代文字

Column_def Packet

该包前四个字节表示的包的字节长度以及包的序列号。后四字节为以下内容。

相对包内容的位置 长度(字节) 名称 描述
0 不定长 catalog 目录,通常为def
不定长 不定长 schema 操作的数据库
不定长 不定长 table 操作的虚拟表名
不定长 不定长 org_table 操作的物理表名
不定长 不定长 name 虚拟列字段名
不定长 不定长 org_name 物理列字段名
不定长 0x0c length of fixed-length fields 以下字段长度
不定长 2 character 列字符集
不定长 4 length 字段最大长度
不定长 1 type 字段类型
不定长 2 flags 标志
不定长 1 decimals ??
不定长 2 预留字节数 预留字节数

以下是Wireshark对column_def的解析截图。

你想输入的替代文字

EOF Packet

相对包内容的位置 长度(字节) 名称 描述
0 1 包头标识 0xFE 代表这是一个EOF 包
1 2 警告数 上次命令引起的警告数
3 2 服务器状态 服务器状态

以下是Wireshark的数据截图。

你想输入的替代文字

Row Packet

Row Data含着的是我们需要获取的数据,一个Result Set包里面包含着多个Row Data结构。每一个值前面有长度字节值,可以帮助我们区分开不同的列。

相对包内容的位置 长度(字节) 名称 描述
0 不定 length 这个字段的数据长度
不定 不定 value 这个字段的值

Wireshark显示Row的数据,虽然只显示了text,但是点击十六进制的数据,还是能看到length的数据。

你想输入的替代文字