Loading...
墨滴

公众号:offer多多

2021/11/08  阅读:58  主题:橙心

OceanBase 数据库大赛:唯一索引 思路分析

OceanBase 数据库大赛:一次插入多条数据

大家好,我是小王 完整地址:

https://static.app.yinxiang.com/embedded-web/profile/#/join?guid=56dad3cf-b366-4b36-a2b5-e39017860967&spaceOwnerId=8226829&channel=copylink&shardId=s39&ownerId=8226829


下面是记录过程 大家可以不看。

共享信息:

  • 自动测试:

https://jgithub.com/hnwyllmm/miniob_test/issues/1

https://github.com/oceanbase/miniob.git

  • 比赛题目: https://github.com/OceanBase-Partner/lectures-on-dbms-implementation/blob/main/miniob-topics.md

  • mimiob代码

https://github.com/OceanBase-Partner/lectures-on-dbms-implementation/blob/main/miniob-introduction.md

  • 报名地址

https://open.oceanbase.com/competition/index

最少知识

  1. 第二篇:编译原理之lex,yacc学习
  • https://courses.cs.washington.edu/courses/cse322/07au/slides/lec25.pdf

  • http://dinosaur.compilertools.net/

  • http://dinosaur.compilertools.net/bison/bison_6.html#SEC42

-https://github.com/oceanbase/miniob.git

思路分析

题目:一次插入多条数据

问题:插入一个记录 怎么提交了2次。感觉这么复杂 1 第一次:已经插入完成 record_handler_->insert_record() 插入到DiskBufferPool中去了。

  1. 第二次: 在事务提交阶段:记录事务号
  • current_trx->commit();
  1. 可能会滚(没写) void end_trx_if_need(Session *session, Trx *trx, bool all_right)

问4:题目:一次插入多条数据。

问:你们yyac表示怎么修改的? 我啥我这样写 ,多个()的value,为啥认为是一个()value呢?

这样递归定义哪里有问题?

271e18ae03ee62481ac41a92d334abcb.png
271e18ae03ee62481ac41a92d334abcb.png
377f7a94ed942ad75a210fda92747bf1.png
377f7a94ed942ad75a210fda92747bf1.png

上来追加方式,而不是直接修改,导致错误 耽误2天时间。

  • 自己写好了代码,但是测试不对? parse_defs.h 可以跟踪。

  • 如何判断插入多个记录?

  1. 自己解析后,根据number产生不确定 30分钟没进展。
  • 根据题目 可以支持输入多个values,自己感觉不好实现

难点:降低为之支持2个values ,然后看测试结果

  • 新增一个结构怎么处理

/Users/wangchuanyi/code/miniob_tag/miniob/src/observer/sql/parser/parse_defs.h

  1. 有人对yacc调试过吗? 一次插入多条数据

用二维矩阵存储内容,每个values 内容,row+1 虽然+1,但是解析时候不起作用? 最后都解析第一行了。

代码阅读

代码实现:

  • LOG_ERROR("insert_record rc=%d:%s", rc, strrc(rc));

一次插入多个记录,插入提交

char *record_data; RC rc = make_record(value_num, values, record_data);

  • current_trx->commit();

case Operation::Type::INSERT:

RC Table::commit_insert(Trx *trx, const RID &rid)

回答4:

#### select_attr -->  attr_list
select_attr:
    | ID attr_list {
   RelAttr attr;
   relation_attr_init(&attr, NULL, $1);
   selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
  }
        
 
 
 attr_list:
    /* empty */
    | COMMA ID attr_list {
   RelAttr attr;
   relation_attr_init(&attr, NULL, $2);
   selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
        // CONTEXT->ssql->sstr.selection.attributes[CONTEXT->select_length].relation_name = NULL;
        // CONTEXT->ssql->sstr.selection.attributes[CONTEXT->select_length++].attribute_name=$2;
      }
  • 默认代码
000588f3e7c7e6582c1bd2e805fad91d.png
000588f3e7c7e6582c1bd2e805fad91d.png
INSERT INTO ID VALUES LBRACE value value_list RBRACE SEMICOLON 
  • SEMICOLON 是分号。

  • LBRACE value value_list RBRACE 插入一个value

    31cc40971e5b498ecab347d8024ea867.png
    31cc40971e5b498ecab347d8024ea867.png
typedef struct ParserContext {
  Query * ssql;
  size_t select_length;
  size_t condition_length;
  size_t from_length;
  size_t value_length;
  Value values[MAX_NUM];
  Condition conditions[MAX_NUM];
  CompOp comp;
 char id[MAX_NUM];
} ParserContext;


insert_stmt

  • 如果是多个呢【这个题目的内容】

  • 不回了,看where怎么定义的

  1. 别人都是对同一个对象追加操作,我是对不同对象怎办

插入一行记录

case SCF_INSERT:

const Inserts &inserts = sql->sstr.insertion;

// struct of insert typedef struct { char *relation_name; // Relation to insert into size_t value_num; // Length of values Value values[MAX_NUM]; // values to insert } Inserts;

//不太敢修改Inserts改为集合结构 //我新增一个同样的结构 typedef struct { char *relation_name; // Relation to insert into size_t value_num; // Length of values Value values[MAX_NUM]; // values to insert } InsertLeft;

  • 这个题目有点快做不下去,想放弃的感觉,我看book 15分钟。 )

  • case SCF_INSERT:

参考 update实现

// struct of craete_table
typedef struct {
  char *relation_name;           // Relation name
  size_t attribute_count;        // Length of attribute
  AttrInfo attributes[MAX_NUM];  // attributes
} CreateTable;

create_table_append_attribute

 void create_table_append_attribute(CreateTable *create_table, AttrInfo *attr_info)
  {
    create_table->attributes[create_table->attribute_count++] = *attr_info;
  }
  
  
create_table_append_attribute(&CONTEXT->ssql->sstr.create_table, &attribute);


union Queries {
  Selects selection;
  Inserts insertion;
  Deletes deletion;
  Updates update;
  CreateTable create_table;
  DropTable drop_table;
  CreateIndex create_index;
  DropIndex drop_index;
  DescTable desc_table;
  LoadData load_data;
  char *errors;
};

 | MIN LBRACE ID RBRACE attr_list {
   RelAttr attr;
   attr.funtype=FUN_MIN;
   relation_attr_init(&attr, NULL,$3);
   selects_append_attribute(&CONTEXT->ssql->sstr.selection, &attr);
  }
4 参考 selects_append_attribute实现
 void selects_append_attribute(Selects *selects, RelAttr *rel_attr)
  {
    selects->attributes[selects->attr_num++] = *rel_attr;
  }

调试

  • insert.sh

#!/bin/bash
sqls='
drop table t;
drop index unique_index_01 on t;
create table t(id int, age int,name char,birthday date,money float);
create unique index unique_index_01 on t(id);
## 测试
insert into t values(1,11, "a","2021-3-1",1.2),(2,22, "c","2021-3-2",2.2);
insert into t values(3,33, "c","2021-3-3",3.2);

'



>test.tmp
echo -n "$sqls" | while read line
do
echo "$line"
echo -n "$line" | ../obclient | sed -e "s/miniob > //"
echo "------------------------------"
done >>test.tmp

  • gdb
flex lex_sql.l

bison -d -b yacc_sql yacc_sql.y


breakpoint set --file default_storage_stage.cpp --line 180


breakpoint set --file parse.cpp --line 259



测试日志

  1. 插入10列,为什么变成10列呢 解析脚本有问题 inserts_init_appends rows=0,left_num=2,type=3,value_num=10

  2. view watchpoints insert

insert: result file difference(`-` is yours and `+` is base)
 2. ERROR
 INSERT INTO INSERT_TABLE VALUES (4,'N4',1,1),(1,1,1);
-SUCCESS
+FAILURE
 INSERT INTO INSERT_TABLE VALUES (4,'N4',1,1),(1,1,1,1);
-SUCCESS
+FAILURE

公众号:offer多多

2021/11/08  阅读:58  主题:橙心

作者介绍

公众号:offer多多