Atlas源码剖析(十)

SQL语句的解析和自动分表

解析SQL语句:

GPtrArray* sql_parse(network_mysqld_con* con, GPtrArray* tokens) {
//1. 解析库名和表名
gint db, table;
    guint sql_type = get_table_index(tokens, &db, &table);
    if (table == -1) return NULL;

    //2. 解析列
    gchar* table_name = NULL;
    if (db == -1) {
        table_name = g_strdup_printf("%s.%s", 
                             con->client->default_db->str,
                             ((sql_token*)tokens->pdata[table])->text->str);
    } else {
        table_name = g_strdup_printf("%s.%s",
                             ((sql_token*)tokens->pdata[db])->text->str,
                             ((sql_token*)tokens->pdata[table])->text->str);
    }

    db_table_t* dt = g_hash_table_lookup(con->config->dt_table, table_name);
    if (dt == NULL) {
        g_free(table_name);
        return NULL;
    }

    GArray* columns = get_column_index(tokens, table_name,
                              dt->column_name, sql_type, table+1);
    g_free(table_name);
    if (columns->len == 0) { 
        g_array_free(columns, TRUE);
        return NULL;
    }    

    //3. 拼接SQL
    GPtrArray* sqls = combine_sql(tokens, table, columns, dt->table_num);
    g_array_free(columns, TRUE);
    return sqls;
}



解析库名和表名的函数get_table_index,分为三种情况:

a、当为select或delete语句时,则找到下一个token ‘from’,在from后面的字面值token则为库名和表名;

   SQL select语法:

            SELECT列名称 FROM 表名称

   SQL delete语法:

            DELETEFROM 表名称 WHERE 列名称 = 值

b、当为update语句时,则从头寻找在token ‘set’之前的字面值token,其为库名和表名;

   SQL update语法:

            UPDATE表名称 SET 列名称 = 新值 WHERE 列名称 = 某值

c、当为insert或replace语句时,则从头寻找在token ‘value’或‘values’之前的字面值token,其为库名和表名;

   SQL insert语法:

            INSERTINTO 表名称 VALUES (值1, 值2,....)

INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

   SQL replace语法:

            replaceinto tbl_name(col_name, ...) values(...)

              replace into tbl_name(col_name,...) select ...

              replace into tbl_name setcol_name=value, ...

guint get_table_index(GPtrArray* tokens, gint* d, gint* t) {
*d = *t = -1;

sql_token** ts = (sql_token**)(tokens->pdata);
guint len = tokens->len;

    guint i = 1, j;
    while (ts[i]->token_id == TK_COMMENT && ++i < len);
    sql_token_id token_id = ts[i]->token_id;

    if (token_id == TK_SQL_SELECT || token_id == TK_SQL_DELETE) {
        for (; i < len; ++i) {
            if (ts[i]->token
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值