mysql 加1函数_探索MYSQL源代码–添加一个函数

我们来为MySQL添加一个函数,名为show disk_usage

mysql> show disk_usage;

+----------+-----------+

| Database | Size (Kb) |

+----------+-----------+

| test_row | 120400 |

+----------+-----------+

1 row in set (0.00 sec)

要修改新的函数,涉及到词法分析,我们先来修改sql/lex.h文件。

找到static SYMBOL symbols[] 这个结构体,添加一个”DISK_USAGE”这个词法,效果如下

{ "DISK", SYM(DISK_SYM)},

/*start*/

{ "DISK_USAGE", SYM(DISK_USAGE_SYM)},

/*end */

{ "DISTINCT", SYM(DISTINCT)}

于是词法分析的时候会DISK_USAGE这个词法当做一个token转化为内部枚举DISK_USAGE_SYM。

有新的词法,我们为新词法添加新语法,我们来修改sql/yacc.yy文件。

来到token区域,添加一个token,名字于lex.h一样,这样语法分析器bison才能知晓词法分析器flex传过来的token对应的枚举。

%token DISK_SYM

/*start*/

%token DISK_USAGE_SYM

/*end*/

%token DISTINCT

继续添加发现show disk_usage()语法匹配之后的行为

搜索关键字show: 添加新的行为

show:

/*start*/

SHOW DISK_USAGE_SYM

{

LEX *lex = Lex;

sql_command = SQLCOM_SHOW_DISK_USAGE;

}

| /*end*/

SHOW

到这里为止词法语法部分添加完毕。

SQLCOM_SHOW_DISK_USAGE产生什么效果呢,需要指向具体的函数。

在添加具体函数之前,还需要让SQLCOM_SHOW_DISK_USAGE成为一个合法的sql_command,我们需要修改sql/sql_lex.h。找到关键字enum enum_sql_command, 把SQLCOM_SHOW_DISK_USAGE作为一个enum添加进去

SQLCOM_SHOW_PROFILE,

SQLCOM_SHOW_PROFILES,

/*start*/

SQLCOM_SHOW_DISK_USAGE,

/*end*/

/*

When a command is added here, be sure it's also added in mysqld.cc

in "struct show_var_st status_vars[]= {" ...

*/

/* This should be the last !!! */

SQLCOM_END

};

接着还要在sql/mysqld.cc 里再添加一遍, 找到关键字SHOW_VAR com_status_vars[]= {

{"show_authors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},

/*start*/

{"show_disk_usage", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DISK_USAGE]), SHOW_LONG_STATUS},

/*end*/

{"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},

不添加这部会出现编译时的ASSERT错误。

接着把SQLCOM_DISK_USAGE指向具体函数, 修改sql/sql_parse.cc,关键字mysql_execute_command

switch (lex->sql_command) {

/*start*/

case SQLCOM_SHOW_DISK_USAGE:

res = show_disk_usage_command(thd);

break;

/*end*/

case SQLCOM_SHOW_EVENTS:

好了终于指向了具体的函数show_disk_usage_command(),我们接着来实现这个函数。

在sql/mysql_priv.h添加一个申明

bool mysqld_help (THD *thd, const char *text);

/*start*/

bool show_disk_usage_command(THD *thd);

/* end */

void calc_sum_of_all_status(STATUS_VAR *to);

在sql/sql_show.cc添加一个具体的实现

bool show_disk_usage_command(THD *thd)

{

DBUG_ENTER("show_disk_usage");

List field_list;

List dbs;

Protocol *protocol = thd->protocol;

/*set fields*/

field_list.push_back(new Item_empty_string("Database", 50));

field_list.push_back(new Item_empty_string("Size (Kb)", 30));

if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS|Protocol::SEND_EOF))

DBUG_RETURN(TRUE);

/*set data*/

protocol->prepare_for_resend();

protocol->store("test_row", system_charset_info);

protocol->store("1024000", system_charset_info);

if (protocol->write())

DBUG_RETURN(TRUE);

my_eof(thd);

DBUG_RETURN(FALSE);

}

/*end*/

bool mysqld_show_authors(THD *thd)

make clean; make;make install

好了,效果就可以看到了

mysql> show disk_usage;

+----------+-----------+

| Database | Size (Kb) |

+----------+-----------+

| test_row | 1024 |

+----------+-----------+

1 row in set (0.00 sec)

ps : 部分参考expert mysql

for douban: doubanclaimfdd64e647e42d240

觉得文章有用?立即:

和朋友一起 共学习 共进步!

猜您喜欢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值