SHOW CREATE TABLEの実行

調べてみました。

SQLコマンドの処理ではおなじみのmysql_execute_command関数ですが、SHOW CREATE TABLEについてはSQLCOM_SHOW_CREATEというコマンドが用意されています。(SHOW系のコマンドはinformation_schemaデータベースへのSELECT文に変換されるケースが多いですがこの場合は違うということです。)

SQLCOM_SHOW_CREATEの場合、mysqld_show_create関数が呼ばれます。

#0  mysqld_show_create (thd=0x9aba7c0, table_list=0x9af3580) at sql_show.cc:387
#1  0x08229e6f in mysql_execute_command (thd=0x9aba7c0) at sql_parse.cc:3373
#2  0x0822fce5 in mysql_parse (thd=0x9aba7c0, inBuf=0x9af34f8 "show create table t1", length=20, found_semicolon=0xb23a61e0) at sql_parse.cc:6139
#3  0x08231e33 in dispatch_command (command=COM_QUERY, thd=0x9aba7c0, packet=0x9aeb4c9 "show create table t1", packet_length=21) at sql_parse.cc:1821
#4  0x0823321b in do_command (thd=0x9aba7c0) at sql_parse.cc:1595
#5  0x082342c1 in handle_one_connection (arg=0x9aba7c0) at sql_parse.cc:1206
#6  0x00d0d302 in start_thread () from /lib/i686/nosegneg/libpthread.so.0
#7  0x001df38e in clone () from /lib/i686/nosegneg/libc.so.6

mysqld_show_create関数では対象のテーブルがviewの場合などのいくつかの配慮を行い、実体テーブルに対してはさらにstore_create_info関数を呼び出して"SHOW CREATE TABLE"の結果を作ります。

 store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)

table_listに書かれたテーブルのスキーマを文字列にしてpacketに書き込む感じです。

そしてズバリ!

  {
    KEY_PART_INFO *key_part= key_info->key_part;
    bool found_primary=0;
    packet->append(STRING_WITH_LEN(",\n  "));

    if (i == primary_key && !strcmp(key_info->name, primary_key_name))
    {
      found_primary=1;
      packet->append(STRING_WITH_LEN("PRIMARY "));
    }
    else if (key_info->flags & HA_NOSAME)
      packet->append(STRING_WITH_LEN("UNIQUE "));
    else if (key_info->flags & HA_FULLTEXT)
      packet->append(STRING_WITH_LEN("FULLTEXT "));
    else if (key_info->flags & HA_SPATIAL)
      packet->append(STRING_WITH_LEN("SPATIAL "));
    packet->append(STRING_WITH_LEN("KEY "));

    if (!found_primary)
     append_identifier(thd, packet, key_info->name, strlen(key_info->name));

    if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
        !limited_mysql_mode && !foreign_db_mode)
    {
      if (key_info->algorithm == HA_KEY_ALG_BTREE)
        packet->append(STRING_WITH_LEN(" USING BTREE"));

      if (key_info->algorithm == HA_KEY_ALG_HASH)
        packet->append(STRING_WITH_LEN(" USING HASH"));

      // +BAR: send USING only in non-default case: non-spatial rtree                                                                                                       
      if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
          !(key_info->flags & HA_SPATIAL))
        packet->append(STRING_WITH_LEN(" USING RTREE"));

      // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY                                                                                                         
    }

ここでsennaポインタがある場合にsen_index_infoを呼んで追記するように弄ればよさそうですね^^