接着上一篇,继续研究
废话不多说,直接gdb进入unpack_row
插入的数据是:
insert into xx values(1,2,"sdf",13,"sss");
可以看到,row_data行数据中是乱码,对下面的代码进行分析后可以得出:
1.首先进行偏移:
size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
其中bitmap_bits_set(cols) 为列的个数
uchar const *pack_ptr= row_data + master_null_byte_count
(gdb) p pack_ptr
$149 = (const uchar *) 0x1e9e80f1 "\001"
打印:
(gdb) p pack_ptr[0]
$150 = 1 '\001'
(gdb) p pack_ptr[1]
$151 = 0 '\0'
其中1为插入的第一列数据,以'\0'结束,为了验证我们的想法,继续打印:
(gdb) p pack_ptr[2]
$152 = 0 '\0'
(gdb) p pack_ptr[3]
$153 = 0 '\0'
(gdb) p pack_ptr[4]
$154 = 2 '\002'
(gdb) p pack_ptr[5]
$155 = 0 '\0'
可见当向后偏移到第一个非‘\0’位置时,表示的是第二列的数据‘2’
那么对字符串,这里是如何处理的呢?
(gdb) p pack_ptr[8]
$158 = 3 '\003'
(gdb) p pack_ptr[9]
$159 = 115 's'
(gdb) p pack_ptr[9]@3
$160 = "sdf"
挨着上次的跳过\0,我们可以看到对于字符串,首先有一个数字来表示字符串的长度,然后紧跟着相应的字符串
接着看下一个数字13:
(gdb) p row_data[13]
$219 = 13 '\r'
这个数字紧挨着上一个字符串之后,这表明列数据无需用''\0'间隔
三个字节的'\0'后,下一个字符串:
(gdb) p row_data[17]
$223 = 3 '\003'
(gdb) p row_data[18]
$224 = 115 's'
(gdb) p row_data[19]
$225 = 115 's'
(gdb) p row_data[20]
$226 = 115 's'
(gdb) p row_data[21]
$227 = 0 '\0'
同样的,row_data[17]表示其后字符串的长度,然后跟着'sss'
基于上述分析,我们可以推测:
1.'\0'是用来填充字节的
2.列数据与列数据之间除了'\0'没有其他填充
3.对于字符串,会记录其数据的字节数
那么对于值为NULL的情况该如何处理呢?
插入数据:insert into xx values(1,2,"sdf",NULL,"sss");
(gdb) p row_data[1]
$232 = 1 '\001'
(gdb) p row_data[2]
$233 = 0 '\0'
(gdb) p row_data[3]
$234 = 0 '\0'
(gdb) p row_data[4]
$235 = 0 '\0'
(gdb) p row_data[5]
$236 = 2 '\002'
(gdb) p row_data[6]
$237 = 0 '\0'
(gdb) p row_data[8]
$238 = 0 '\0'
(gdb) p row_data[9]
$239 = 3 '\003'
(gdb) p row_data[10]
$240 = 115 's'
(gdb) p row_data[11]
$241 = 100 'd'
(gdb) p row_data[12]
$242 = 102 'f'
(gdb) p row_data[13]
$243 = 3 '\003'
(gdb) p row_data[14]
$244 = 115 's'
(gdb) p row_data[15]
$245 = 115 's'
(gdb) p row_data[16]
$246 = 115 's'
我们可以看到,值为NULL时,在行数据中是不存在的,那么何时才知道我们该忽略某个值为NULL的列呢??
简单的实验了一下,null值似乎记录在row_data的第一个字节内:
例如:
当输入为:insert into xx values(1,NULL,NULL,NULL,"ssss");
row_data[0] = 238
二进制:1110 1110
当输入为:insert into xx values(1,NULL,NULL,15,"ssss");
row_data[0]=230
二进制:1110 0110
猜测如下:
第一个字节的低5位代表5个列。高位为最后一个列,低位为第一个列。
当值为1时,表示该值为NULL,在解析行数据时,可以忽略,
当值为0时,则表示该列数据不为空,可以从行数据中解析得到。
下一步:证实上述猜想!!!!