mysql read rnd next_16.9.6. 实施rnd_next()函数

16.9.6. 实施rnd_next()函数

完成表的初始化操作后,MySQL服务器将调用处理程序的1次,直至满足了服务器的搜索条件或到达文件结尾为止,在后一种情况下,处理程序将返回HA_ERR_END_OF_FILE。

rnd_next()函数有一个名为*buf的单字节数组参数。对于*buf参数,必须按内部MySQL格式用表行的内容填充它。

服务器采用了三种数据格式:固定长度行,可变长度行,以及具有BLOB指针的可变长度行。对于每种格式,各列将按照它们由CREATE

TABLE语句定义的顺序显示(表定义保存在.frm文件中,优化程序和处理程序均能从相同的源,即TABLE结构,访问表的元数据)。

每种格式以每列1比特的"NULL bitmap"开始。对于含6个列的表,其bitmap为1字节,对于含9~16列的表,其bitmap为2字节,依此类推。要想指明特定的值是NULL,应将该列NULL位设置为1。

当NULL bitmap逐个进入列后,每列将具有MySQL手册的“MySQL数据类型”一节中指定的大小。在服务器中,列的数据类型定义在sql/field.cc文件中。对于固定长度行格式,列将简单地逐个放置。对于可变长度行,VARCHAR列将被编码为1字节长,后跟字符串。对于具有BLOB列的可变长度行,每个blob由两部分表示:首先是表示BLOB实际大小的整数,然后是指向内存中BLOB的指针。

在任何表处理程序中从rnd_next()开始,可找到行转换(或“包装”)的示例。例如,在ha_tina.cc中,find_current_row()内的代码给出了使用TABLE结构(由表指向的)和字符串对象(命名缓冲)包装字符数据(来自CSV文件)的方法。将行写回磁盘需要反向转换,从内部格式解包。

下述示例来自CSV存储引擎:

int ha_tina::rnd_next(byte *buf)

{

DBUG_ENTER("ha_tina::rnd_next");

statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status);

current_position= next_position;

if (!share->mapped_file)

DBUG_RETURN(HA_ERR_END_OF_FILE);

if (HA_ERR_END_OF_FILE == find_current_row(buf) )

DBUG_RETURN(HA_ERR_END_OF_FILE);

records++;

DBUG_RETURN(0);

}

对于从内部行格式到CSV行格式的转换,它是在find_current_row()函数中执行的。

int ha_tina::find_current_row(byte *buf)

{

byte *mapped_ptr= (byte *)share->mapped_file + current_position;

byte *end_ptr;

DBUG_ENTER("ha_tina::find_current_row");

/* EOF should be counted as new line */

if ((end_ptr=  find_eoln(share->mapped_file, current_position,

share->file_stat.st_size)) == 0)

DBUG_RETURN(HA_ERR_END_OF_FILE);

for (Field **field=table->field ; *field ; field++)

{

buffer.length(0);

mapped_ptr++; // Increment past the first quote

for(;mapped_ptr != end_ptr; mapped_ptr++)

{

// Need to convert line feeds!

if (*mapped_ptr == '"' &&

(((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) ||

(mapped_ptr == end_ptr -1 )))

{

mapped_ptr += 2; // Move past the , and the "

break;

}

if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1))

{

mapped_ptr++;

if (*mapped_ptr == 'r')

buffer.append('\r');

else if (*mapped_ptr == 'n' )

buffer.append('\n');

else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"'))

buffer.append(*mapped_ptr);

else  /* This could only happed with an externally created file */

{

buffer.append('\\');

buffer.append(*mapped_ptr);

}

}

else

buffer.append(*mapped_ptr);

}

(*field)->store(buffer.ptr(), buffer.length(), system_charset_info);

}

next_position= (end_ptr - share->mapped_file)+1;

/* Maybe use \N for null? */

memset(buf, 0, table->s->null_bytes); /* We do not implement nulls! */

DBUG_RETURN(0);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值