diff options
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 410 |
1 files changed, 253 insertions, 157 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4fb1b2e8c84..01f474a73fb 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -58,10 +58,11 @@ #include "lock.h" // MYSQL_OPEN_IGNORE_FLUSH #include "debug_sync.h" #include "keycaches.h" - +#include "ha_sequence.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" #endif + enum enum_i_s_events_fields { ISE_EVENT_CATALOG= 0, @@ -130,6 +131,8 @@ static void get_cs_converted_string_value(THD *thd, #endif static int show_create_view(THD *thd, TABLE_LIST *table, String *buff); +static int show_create_sequence(THD *thd, TABLE_LIST *table_list, + String *packet); static const LEX_STRING *view_algorithm(TABLE_LIST *table); @@ -1169,12 +1172,19 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, } /* TODO: add environment variables show when it become possible */ - if (thd->lex->only_view && !table_list->view) + if (thd->lex->table_type == TABLE_TYPE_VIEW && !table_list->view) { my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, table_list->table_name, "VIEW"); goto exit; } + else if (thd->lex->table_type == TABLE_TYPE_SEQUENCE && + table_list->table->s->table_type != TABLE_TYPE_SEQUENCE) + { + my_error(ER_WRONG_OBJECT, MYF(0), + table_list->db, table_list->table_name, "SEQUENCE"); + goto exit; + } buffer->length(0); @@ -1183,6 +1193,8 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, if ((table_list->view ? show_create_view(thd, table_list, buffer) : + thd->lex->table_type == TABLE_TYPE_SEQUENCE ? + show_create_sequence(thd, table_list, buffer) : show_create_table(thd, table_list, buffer, NULL, WITHOUT_DB_NAME))) goto exit; @@ -1761,6 +1773,179 @@ static void append_create_options(THD *thd, String *packet, packet->append(STRING_WITH_LEN(" */")); } +/** + Add table options to end of CREATE statement + + @param schema_table 1 if schema table + @param sequence 1 if sequence. If sequence, we flush out options + not relevant for sequences. +*/ + +static void add_table_options(THD *thd, TABLE *table, + Table_specification_st *create_info_arg, + bool schema_table, bool sequence, + String *packet) +{ + sql_mode_t sql_mode= thd->variables.sql_mode; + TABLE_SHARE *share= table->s; + handlerton *hton; + HA_CREATE_INFO create_info; + bool check_options= (!(sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) && + !create_info_arg); + +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (table->part_info) + hton= table->part_info->default_engine_type; + else +#endif + hton= table->file->ht; + + bzero((char*) &create_info, sizeof(create_info)); + /* Allow update_create_info to update row type, page checksums and options */ + create_info.row_type= share->row_type; + create_info.page_checksum= share->page_checksum; + create_info.options= share->db_create_options; + table->file->update_create_info(&create_info); + + /* + IF check_create_info + THEN add ENGINE only if it was used when creating the table + */ + if (!create_info_arg || + (create_info_arg->used_fields & HA_CREATE_USED_ENGINE)) + { + LEX_STRING *engine_name= table->file->engine_name(); + + if (sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) + packet->append(STRING_WITH_LEN(" TYPE=")); + else + packet->append(STRING_WITH_LEN(" ENGINE=")); + + packet->append(engine_name->str, engine_name->length); + } + + if (sequence) + goto end_options; + + /* + Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column, + and NEXT_ID > 1 (the default). We must not print the clause + for engines that do not support this as it would break the + import of dumps, but as of this writing, the test for whether + AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=... + is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT)) + Because of that, we do not explicitly test for the feature, + but may extrapolate its existence from that of an AUTO_INCREMENT column. + */ + + if (create_info.auto_increment_value > 1) + { + packet->append(STRING_WITH_LEN(" AUTO_INCREMENT=")); + packet->append_ulonglong(create_info.auto_increment_value); + } + + if (share->table_charset && !(sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) && + share->table_type != TABLE_TYPE_SEQUENCE) + { + /* + IF check_create_info + THEN add DEFAULT CHARSET only if it was used when creating the table + */ + if (!create_info_arg || + (create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) + { + packet->append(STRING_WITH_LEN(" DEFAULT CHARSET=")); + packet->append(share->table_charset->csname); + if (!(share->table_charset->state & MY_CS_PRIMARY)) + { + packet->append(STRING_WITH_LEN(" COLLATE=")); + packet->append(table->s->table_charset->name); + } + } + } + + if (share->min_rows) + { + packet->append(STRING_WITH_LEN(" MIN_ROWS=")); + packet->append_ulonglong(share->min_rows); + } + + if (share->max_rows && !schema_table && !sequence) + { + packet->append(STRING_WITH_LEN(" MAX_ROWS=")); + packet->append_ulonglong(share->max_rows); + } + + if (share->avg_row_length) + { + packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH=")); + packet->append_ulonglong(share->avg_row_length); + } + + if (create_info.options & HA_OPTION_PACK_KEYS) + packet->append(STRING_WITH_LEN(" PACK_KEYS=1")); + if (create_info.options & HA_OPTION_NO_PACK_KEYS) + packet->append(STRING_WITH_LEN(" PACK_KEYS=0")); + if (share->db_create_options & HA_OPTION_STATS_PERSISTENT) + packet->append(STRING_WITH_LEN(" STATS_PERSISTENT=1")); + if (share->db_create_options & HA_OPTION_NO_STATS_PERSISTENT) + packet->append(STRING_WITH_LEN(" STATS_PERSISTENT=0")); + if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_ON) + packet->append(STRING_WITH_LEN(" STATS_AUTO_RECALC=1")); + else if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_OFF) + packet->append(STRING_WITH_LEN(" STATS_AUTO_RECALC=0")); + if (share->stats_sample_pages != 0) + { + packet->append(STRING_WITH_LEN(" STATS_SAMPLE_PAGES=")); + packet->append_ulonglong(share->stats_sample_pages); + } + + /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */ + if (create_info.options & HA_OPTION_CHECKSUM) + packet->append(STRING_WITH_LEN(" CHECKSUM=1")); + if (create_info.page_checksum != HA_CHOICE_UNDEF) + { + packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM=")); + packet->append(ha_choice_values[create_info.page_checksum], 1); + } + if (create_info.options & HA_OPTION_DELAY_KEY_WRITE) + packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1")); + if (create_info.row_type != ROW_TYPE_DEFAULT) + { + packet->append(STRING_WITH_LEN(" ROW_FORMAT=")); + packet->append(ha_row_type[(uint) create_info.row_type]); + } + if (share->transactional != HA_CHOICE_UNDEF) + { + packet->append(STRING_WITH_LEN(" TRANSACTIONAL=")); + packet->append(ha_choice_values[(uint) share->transactional], 1); + } + if (share->table_type == TABLE_TYPE_SEQUENCE) + packet->append(STRING_WITH_LEN(" SEQUENCE=1")); + if (table->s->key_block_size) + { + packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE=")); + packet->append_ulonglong(table->s->key_block_size); + } + table->file->append_create_info(packet); + +end_options: + if (share->comment.length) + { + packet->append(STRING_WITH_LEN(" COMMENT=")); + append_unescaped(packet, share->comment.str, share->comment.length); + } + if (share->connect_string.length) + { + packet->append(STRING_WITH_LEN(" CONNECTION=")); + append_unescaped(packet, share->connect_string.str, share->connect_string.length); + } + append_create_options(thd, packet, share->option_list, check_options, + hton->table_options); + append_directory(thd, packet, "DATA", create_info.data_file_name); + append_directory(thd, packet, "INDEX", create_info.index_file_name); +} + /* Build a CREATE TABLE statement for a table. @@ -1790,7 +1975,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, enum_with_db_name with_db_name) { List<Item> field_list; - char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH]; + char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH]; const char *alias; String type; String def_value; @@ -1798,9 +1983,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, uint primary_key; KEY *key_info; TABLE *table= table_list->table; - handler *file= table->file; TABLE_SHARE *share= table->s; - HA_CREATE_INFO create_info; sql_mode_t sql_mode= thd->variables.sql_mode; bool foreign_db_mode= sql_mode & (MODE_POSTGRESQL | MODE_ORACLE | MODE_MSSQL | MODE_DB2 | @@ -1811,8 +1994,8 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, !foreign_db_mode; bool check_options= !(sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS) && !create_info_arg; - handlerton *hton; my_bitmap_map *old_map; + handlerton *hton; int error= 0; DBUG_ENTER("show_create_table"); DBUG_PRINT("enter",("table: %s", table->s->table_name.str)); @@ -1822,7 +2005,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, hton= table->part_info->default_engine_type; else #endif - hton= file->ht; + hton= table->file->ht; restore_record(table, s->default_values); // Get empty record @@ -1971,12 +2154,6 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, } key_info= table->key_info; - bzero((char*) &create_info, sizeof(create_info)); - /* Allow update_create_info to update row type, page checksums and options */ - create_info.row_type= share->row_type; - create_info.page_checksum= share->page_checksum; - create_info.options= share->db_create_options; - file->update_create_info(&create_info); primary_key= share->primary_key; for (uint i=0 ; i < share->keys ; i++,key_info++) @@ -2043,10 +2220,10 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, to the CREATE TABLE statement */ - if ((for_str= file->get_foreign_key_create_info())) + if ((for_str= table->file->get_foreign_key_create_info())) { packet->append(for_str, strlen(for_str)); - file->free_foreign_key_create_info(for_str); + table->file->free_foreign_key_create_info(for_str); } /* Add table level check constraints */ @@ -2073,146 +2250,9 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, packet->append(STRING_WITH_LEN("\n)")); if (show_table_options) - { - /* - IF check_create_info - THEN add ENGINE only if it was used when creating the table - */ - if (!create_info_arg || - (create_info_arg->used_fields & HA_CREATE_USED_ENGINE)) - { - if (sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) - packet->append(STRING_WITH_LEN(" TYPE=")); - else - packet->append(STRING_WITH_LEN(" ENGINE=")); - packet->append(hton_name(hton)); - } - - /* - Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column, - and NEXT_ID > 1 (the default). We must not print the clause - for engines that do not support this as it would break the - import of dumps, but as of this writing, the test for whether - AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=... - is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT)) - Because of that, we do not explicitly test for the feature, - but may extrapolate its existence from that of an AUTO_INCREMENT column. - */ - - if (create_info.auto_increment_value > 1) - { - char *end; - packet->append(STRING_WITH_LEN(" AUTO_INCREMENT=")); - end= longlong10_to_str(create_info.auto_increment_value, buff,10); - packet->append(buff, (uint) (end - buff)); - } - - if (share->table_charset && !(sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))) - { - /* - IF check_create_info - THEN add DEFAULT CHARSET only if it was used when creating the table - */ - if (!create_info_arg || - (create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) - { - packet->append(STRING_WITH_LEN(" DEFAULT CHARSET=")); - packet->append(share->table_charset->csname); - if (!(share->table_charset->state & MY_CS_PRIMARY)) - { - packet->append(STRING_WITH_LEN(" COLLATE=")); - packet->append(table->s->table_charset->name); - } - } - } - - if (share->min_rows) - { - char *end; - packet->append(STRING_WITH_LEN(" MIN_ROWS=")); - end= longlong10_to_str(share->min_rows, buff, 10); - packet->append(buff, (uint) (end- buff)); - } - - if (share->max_rows && !table_list->schema_table) - { - char *end; - packet->append(STRING_WITH_LEN(" MAX_ROWS=")); - end= longlong10_to_str(share->max_rows, buff, 10); - packet->append(buff, (uint) (end - buff)); - } - - if (share->avg_row_length) - { - char *end; - packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH=")); - end= longlong10_to_str(share->avg_row_length, buff,10); - packet->append(buff, (uint) (end - buff)); - } - - if (create_info.options & HA_OPTION_PACK_KEYS) - packet->append(STRING_WITH_LEN(" PACK_KEYS=1")); - if (create_info.options & HA_OPTION_NO_PACK_KEYS) - packet->append(STRING_WITH_LEN(" PACK_KEYS=0")); - if (share->db_create_options & HA_OPTION_STATS_PERSISTENT) - packet->append(STRING_WITH_LEN(" STATS_PERSISTENT=1")); - if (share->db_create_options & HA_OPTION_NO_STATS_PERSISTENT) - packet->append(STRING_WITH_LEN(" STATS_PERSISTENT=0")); - if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_ON) - packet->append(STRING_WITH_LEN(" STATS_AUTO_RECALC=1")); - else if (share->stats_auto_recalc == HA_STATS_AUTO_RECALC_OFF) - packet->append(STRING_WITH_LEN(" STATS_AUTO_RECALC=0")); - if (share->stats_sample_pages != 0) - { - char *end; - packet->append(STRING_WITH_LEN(" STATS_SAMPLE_PAGES=")); - end= longlong10_to_str(share->stats_sample_pages, buff, 10); - packet->append(buff, (uint) (end - buff)); - } + add_table_options(thd, table, create_info_arg, + table_list->schema_table != 0, 0, packet); - /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */ - if (create_info.options & HA_OPTION_CHECKSUM) - packet->append(STRING_WITH_LEN(" CHECKSUM=1")); - if (create_info.page_checksum != HA_CHOICE_UNDEF) - { - packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM=")); - packet->append(ha_choice_values[create_info.page_checksum], 1); - } - if (create_info.options & HA_OPTION_DELAY_KEY_WRITE) - packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1")); - if (create_info.row_type != ROW_TYPE_DEFAULT) - { - packet->append(STRING_WITH_LEN(" ROW_FORMAT=")); - packet->append(ha_row_type[(uint) create_info.row_type]); - } - if (share->transactional != HA_CHOICE_UNDEF) - { - packet->append(STRING_WITH_LEN(" TRANSACTIONAL=")); - packet->append(ha_choice_values[(uint) share->transactional], 1); - } - if (table->s->key_block_size) - { - char *end; - packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE=")); - end= longlong10_to_str(table->s->key_block_size, buff, 10); - packet->append(buff, (uint) (end - buff)); - } - table->file->append_create_info(packet); - if (share->comment.length) - { - packet->append(STRING_WITH_LEN(" COMMENT=")); - append_unescaped(packet, share->comment.str, share->comment.length); - } - if (share->connect_string.length) - { - packet->append(STRING_WITH_LEN(" CONNECTION=")); - append_unescaped(packet, share->connect_string.str, share->connect_string.length); - } - append_create_options(thd, packet, share->option_list, check_options, - hton->table_options); - append_directory(thd, packet, "DATA", create_info.data_file_name); - append_directory(thd, packet, "INDEX", create_info.index_file_name); - } #ifdef WITH_PARTITION_STORAGE_ENGINE { if (table->part_info && @@ -2423,6 +2463,55 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff) } +static int show_create_sequence(THD *thd, TABLE_LIST *table_list, + String *packet) +{ + TABLE *table= table_list->table; + SEQUENCE *seq= table->s->sequence; + LEX_STRING alias; + sql_mode_t sql_mode= thd->variables.sql_mode; + bool foreign_db_mode= sql_mode & (MODE_POSTGRESQL | MODE_ORACLE | + MODE_MSSQL | MODE_DB2 | + MODE_MAXDB | MODE_ANSI); + bool show_table_options= !(sql_mode & MODE_NO_TABLE_OPTIONS) && + !foreign_db_mode; + + if (lower_case_table_names == 2) + { + alias.str= table->alias.c_ptr(); + alias.length= table->alias.length(); + } + else + alias= table->s->table_name; + + packet->append(STRING_WITH_LEN("CREATE SEQUENCE ")); + append_identifier(thd, packet, alias.str, alias.length); + packet->append(STRING_WITH_LEN(" start with ")); + packet->append_longlong(seq->start); + packet->append(STRING_WITH_LEN(" minvalue ")); + packet->append_longlong(seq->min_value); + packet->append(STRING_WITH_LEN(" maxvalue ")); + packet->append_longlong(seq->max_value); + packet->append(STRING_WITH_LEN(" increment by ")); + packet->append_longlong(seq->increment); + if (seq->cache) + { + packet->append(STRING_WITH_LEN(" cache ")); + packet->append_longlong(seq->cache); + } + else + packet->append(STRING_WITH_LEN(" nocache")); + if (seq->cycle) + packet->append(STRING_WITH_LEN(" cycle")); + else + packet->append(STRING_WITH_LEN(" nocycle")); + + if (show_table_options) + add_table_options(thd, table, 0, 0, 1, packet); + return 0; +} + + /**************************************************************************** Return info about all processes returns for each thread: thread id, user, host, db, command, info @@ -4143,7 +4232,8 @@ static void get_table_engine_for_i_s(THD *thd, char *buf, TABLE_LIST *tl, char path[FN_REFLEN]; build_table_filename(path, sizeof(path) - 1, db->str, table->str, reg_ext, 0); - if (dd_frm_type(thd, path, &engine_name) == FRMTYPE_TABLE) + bool is_sequence; + if (dd_frm_type(thd, path, &engine_name, &is_sequence) == TABLE_TYPE_NORMAL) tl->option= engine_name.str; } } @@ -4360,10 +4450,14 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, { CHARSET_INFO *cs= system_charset_info; handlerton *hton; - if (ha_table_exists(thd, db_name->str, table_name->str, &hton)) + bool is_sequence; + if (ha_table_exists(thd, db_name->str, table_name->str, &hton, + &is_sequence)) { if (hton == view_pseudo_hton) table->field[3]->store(STRING_WITH_LEN("VIEW"), cs); + else if (is_sequence) + table->field[3]->store(STRING_WITH_LEN("SEQUENCE"), cs); else table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); } @@ -5041,7 +5135,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, String str(option_buff,sizeof(option_buff), system_charset_info); TABLE *show_table= tables->table; TABLE_SHARE *share= show_table->s; - handler *file= show_table->file; + handler *file= show_table->db_stat ? show_table->file : 0; handlerton *tmp_db_type= share->db_type(); #ifdef WITH_PARTITION_STORAGE_ENGINE bool is_partitioned= FALSE; @@ -5051,6 +5145,8 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs); else if (share->tmp_table) table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs); + else if (share->table_type == TABLE_TYPE_SEQUENCE) + table->field[3]->store(STRING_WITH_LEN("SEQUENCE"), cs); else table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs); |