mysql insert - Jokacer/Learn GitHub Wiki

MySQL手册:MySQL手册

COPY_INFO:此类封装了数据更改操作。

有三种这样的操作。

  1. 插入语句:INSERT INTO .. VALUES
  2. 更新语句:UPDATE<table> SET ...
  3. 删除语句:此类不用于delete语句,因此尚未进行处理。

对于输入进行赋默认值等处理

插入操作流程为:

storage/csv/ha_tina.h

TINA_SHARE:表的对象引用结构,用于共享记录表的名称、大小、状态等信息

ha_tina:继承handler类,实现父类中的函数以完成引擎功能,包括实现:write_row()update_row()delete_row()等其中write_row()用于插入(insert)数据

storage/csv/ha_tina.cc

在数据insert过程中,该引擎需要实现write_row(uchar *buf)函数,实现代码如下:

int ha_tina::write_row(uchar *buf) {
  int size;
  DBUG_ENTER("ha_tina::write_row");

  if (share->crashed) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);//表出现故障,需要修复

  ha_statistic_increment(&System_status_var::ha_write_count);
  //在增加写操作计数,在更新、搜索表之类的操作下也会有类似的函数调用

  size = encode_quote(buf);//对输入进行编码,成为可引用格式

  if (!share->tina_write_opened)
    if (init_tina_writer()) DBUG_RETURN(-1);//判断文件是否有问题,若文件无法打开则标记为crash并退出

  /* use pwrite, as concurrent reader could have changed the position */
  if (mysql_file_write(share->tina_write_filedes,
                       pointer_cast<const uchar *>(buffer.ptr()), size,
                       MYF(MY_WME | MY_NABP)))
    DBUG_RETURN(-1);//虽然说是使用pwrite,但调用的是write函数

  /* update local copy of the max position to see our own changes */
  local_saved_data_file_length += size;//更新最大读取位置

  /* update shared info */
  mysql_mutex_lock(&share->mutex);//加锁更新共享结构信息
  share->rows_recorded++;
  /* update status for the log tables */
  if (share->is_log_table) update_status();//更新共享结构,is_log_table成员变量
  mysql_mutex_unlock(&share->mutex);

  stats.records++;
  DBUG_RETURN(0);
}

encode_quote(uchar *):将输入字符串编码成可引用的字符串,比如将"转换为\\",将\r转换为\\r,将\\转换成\\\\,将\n转换成\\n,并在字符串首尾添加"符号,记录位图,并返回最终字符串长度

int ha_tina::encode_quote(uchar *) {
  char attribute_buffer[1024];
  String attribute(attribute_buffer, sizeof(attribute_buffer), &my_charset_bin);

  my_bitmap_map *org_bitmap = dbug_tmp_use_all_columns(table, table->read_set);
  buffer.length(0);

  for (Field **field = table->field; *field; field++) {
    const char *ptr;
    const char *end_ptr;
    const bool was_null = (*field)->is_null();

    /*
      assistance for backwards compatibility in production builds.
      note: this will not work for ENUM columns.
    */
    if (was_null) {
      (*field)->set_default();
      (*field)->set_notnull();
    }

    (*field)->val_str(&attribute, &attribute);

    if (was_null) (*field)->set_null();

    if ((*field)->str_needs_quotes()) {
      ptr = attribute.ptr();
      end_ptr = attribute.length() + ptr;

      buffer.append('"');

      for (; ptr < end_ptr; ptr++) {
        if (*ptr == '"') {
          buffer.append('\\');
          buffer.append('"');
        } else if (*ptr == '\r') {
          buffer.append('\\');
          buffer.append('r');
        } else if (*ptr == '\\') {
          buffer.append('\\');
          buffer.append('\\');
        } else if (*ptr == '\n') {
          buffer.append('\\');
          buffer.append('n');
        } else
          buffer.append(*ptr);
      }
      buffer.append('"');
    } else {
      buffer.append(attribute);
    }

    buffer.append(',');
  }
  // Remove the comma, add a line feed
  buffer.length(buffer.length() - 1);
  buffer.append('\n');

  dbug_tmp_restore_column_map(table->read_set, org_bitmap);
  return (buffer.length());
}
⚠️ **GitHub.com Fallback** ⚠️