25 #include "rpl_handler.h" 
   26 #include "sql_cache.h"                    
   28 #include "sql_table.h"                    
   29 #include "sql_parse.h"                           
   34 #include "rpl_filter.h" 
   35 #include <myisampack.h> 
   36 #include "transaction.h" 
   38 #include "probes_mysql.h" 
   44 #ifdef WITH_PARTITION_STORAGE_ENGINE 
   45 #include "ha_partition.h" 
   58 inline double log2(
double x)
 
   60   return (log(x) / M_LN2);
 
   73 #define BITMAP_STACKBUF_SIZE (128/8) 
   76   { HA_KEY_ALG_UNDEF, 0, {NullS, 0}, {NullS, 0}, 
true };
 
   81 ulong total_ha_2pc= 0;
 
   83 ulong savepoint_alloc_size= 0;
 
   87   { C_STRING_WITH_LEN(
"INNOBASE") },  { C_STRING_WITH_LEN(
"INNODB") },
 
   88   { C_STRING_WITH_LEN(
"NDB") },       { C_STRING_WITH_LEN(
"NDBCLUSTER") },
 
   89   { C_STRING_WITH_LEN(
"HEAP") },      { C_STRING_WITH_LEN(
"MEMORY") },
 
   90   { C_STRING_WITH_LEN(
"MERGE") },     { C_STRING_WITH_LEN(
"MRG_MYISAM") },
 
   94 const char *ha_row_type[] = {
 
   95   "", 
"FIXED", 
"DYNAMIC", 
"COMPRESSED", 
"REDUNDANT", 
"COMPACT",
 
  100 const char *tx_isolation_names[] =
 
  101 { 
"READ-UNCOMMITTED", 
"READ-COMMITTED", 
"REPEATABLE-READ", 
"SERIALIZABLE",
 
  103 TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,
"",
 
  104                                tx_isolation_names, NULL};
 
  108 const char *ha_legacy_type_name(legacy_db_type legacy_type)
 
  112   case DB_TYPE_UNKNOWN:
 
  113     return "DB_TYPE_UNKNOWN";
 
  114   case DB_TYPE_DIAB_ISAM:
 
  115     return "DB_TYPE_DIAB_ISAM";
 
  117     return "DB_TYPE_HASH";
 
  119     return "DB_TYPE_MISAM";
 
  121     return "DB_TYPE_PISAM";
 
  122   case DB_TYPE_RMS_ISAM:
 
  123     return "DB_TYPE_RMS_ISAM";
 
  125     return "DB_TYPE_HEAP";
 
  127     return "DB_TYPE_ISAM";
 
  128   case DB_TYPE_MRG_ISAM:
 
  129     return "DB_TYPE_MRG_ISAM";
 
  131     return "DB_TYPE_MYISAM";
 
  132   case DB_TYPE_MRG_MYISAM:
 
  133     return "DB_TYPE_MRG_MYISAM";
 
  134   case DB_TYPE_BERKELEY_DB:
 
  135     return "DB_TYPE_BERKELEY_DB";
 
  137     return "DB_TYPE_INNODB";
 
  139     return "DB_TYPE_GEMINI";
 
  140   case DB_TYPE_NDBCLUSTER:
 
  141     return "DB_TYPE_NDBCLUSTER";
 
  142   case DB_TYPE_EXAMPLE_DB:
 
  143     return "DB_TYPE_EXAMPLE_DB";
 
  144   case DB_TYPE_ARCHIVE_DB:
 
  145     return "DB_TYPE_ARCHIVE_DB";
 
  147     return "DB_TYPE_CSV_DB";
 
  148   case DB_TYPE_FEDERATED_DB:
 
  149     return "DB_TYPE_FEDERATED_DB";
 
  150   case DB_TYPE_BLACKHOLE_DB:
 
  151     return "DB_TYPE_BLACKHOLE_DB";
 
  152   case DB_TYPE_PARTITION_DB:
 
  153     return "DB_TYPE_PARTITION_DB";
 
  155     return "DB_TYPE_BINLOG";
 
  157     return "DB_TYPE_SOLID";
 
  159     return "DB_TYPE_PBXT";
 
  160   case DB_TYPE_TABLE_FUNCTION:
 
  161     return "DB_TYPE_TABLE_FUNCTION";
 
  162   case DB_TYPE_MEMCACHE:
 
  163     return "DB_TYPE_MEMCACHE";
 
  165     return "DB_TYPE_FALCON";
 
  167     return "DB_TYPE_MARIA";
 
  168   case DB_TYPE_PERFORMANCE_SCHEMA:
 
  169     return "DB_TYPE_PERFORMANCE_SCHEMA";
 
  171     return "DB_TYPE_DYNAMIC";
 
  206   {(
const char *)NULL, (
const char *)NULL} 
 
  213 static const char **known_system_databases= NULL;
 
  214 static const char **ha_known_system_databases();
 
  217 static my_bool system_databases_handlerton(THD *unused, 
plugin_ref plugin,
 
  221 static my_bool check_engine_system_table_handlerton(THD *unused,
 
  232   const char *table_name;                     
 
  233   bool is_sql_layer_system_table;             
 
  234   legacy_db_type db_type;                     
 
  236   enum enum_sys_tbl_chk_status
 
  239     NOT_KNOWN_SYSTEM_TABLE,
 
  249     SUPPORTED_SYSTEM_TABLE
 
  256   if (thd->variables.table_plugin)
 
  257     return thd->variables.table_plugin;
 
  258   return my_plugin_lock(thd, &global_system_variables.table_plugin);
 
  283 static plugin_ref ha_default_temp_plugin(THD *thd)
 
  285   if (thd->variables.temp_table_plugin)
 
  286     return thd->variables.temp_table_plugin;
 
  287   return my_plugin_lock(thd, &global_system_variables.temp_table_plugin);
 
  304   plugin_ref plugin= ha_default_temp_plugin(thd);
 
  331   if (thd && !my_charset_latin1.coll->strnncoll(&my_charset_latin1,
 
  332                            (
const uchar *)name->str, name->length,
 
  333                            (
const uchar *)STRING_WITH_LEN(
"DEFAULT"), 0))
 
  334     return is_temp_table ? 
 
  335       ha_default_plugin(thd) : ha_default_temp_plugin(thd);
 
  337   if ((plugin= my_plugin_lock_by_name(thd, name, MYSQL_STORAGE_ENGINE_PLUGIN)))
 
  340     if (!(hton->flags & HTON_NOT_USER_SELECTABLE))
 
  346     plugin_unlock(thd, plugin);
 
  352   for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
 
  354     if (!my_strnncoll(&my_charset_latin1,
 
  355                       (
const uchar *)name->str, name->length,
 
  356                       (
const uchar *)table_alias->str, table_alias->length))
 
  358       name= table_alias + 1;
 
  374     return my_plugin_lock(thd, plugin);
 
  376     return my_plugin_lock(thd, &plugin);
 
  383 handlerton *ha_resolve_by_legacy_type(THD *thd, 
enum legacy_db_type db_type)
 
  387   case DB_TYPE_DEFAULT:
 
  390     if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
 
  391         (plugin= ha_lock_engine(thd, installed_htons[db_type])))
 
  394   case DB_TYPE_UNKNOWN:
 
  404                           bool no_substitute, 
bool report_error)
 
  406   handlerton *hton= ha_resolve_by_legacy_type(thd, database_type);
 
  407   if (ha_storage_engine_is_enabled(hton))
 
  414       const char *engine_name= ha_resolve_storage_engine_name(hton);
 
  415       my_error(ER_FEATURE_DISABLED,MYF(0),engine_name,engine_name);
 
  420   (void) RUN_HOOK(transaction, after_rollback, (thd, FALSE));
 
  422   switch (database_type) {
 
  423   case DB_TYPE_MRG_ISAM:
 
  424     return ha_resolve_by_legacy_type(thd, DB_TYPE_MRG_MYISAM);
 
  437   DBUG_ENTER(
"get_new_handler");
 
  438   DBUG_PRINT(
"enter", (
"alloc: 0x%lx", (
long) alloc));
 
  440   if (db_type && db_type->state == SHOW_OPTION_YES && db_type->create)
 
  442     if ((file= db_type->create(db_type, share, alloc)))
 
  455 #ifdef WITH_PARTITION_STORAGE_ENGINE 
  459   DBUG_ENTER(
"get_ha_partition");
 
  460   if ((partition= 
new ha_partition(partition_hton, part_info)))
 
  462     if (partition->initialize_partition(current_thd->mem_root))
 
  472     my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), 
 
  475   DBUG_RETURN(((
handler*) partition));
 
  480 static const char **handler_errmsgs;
 
  483 static const char **get_handler_errmsgs()
 
  485   return handler_errmsgs;
 
  501 #define SETMSG(nr, msg) handler_errmsgs[(nr) - HA_ERR_FIRST]= (msg) 
  505   if (! (handler_errmsgs= (
const char**) my_malloc(HA_ERR_ERRORS * 
sizeof(
char*),
 
  506                                                    MYF(MY_WME | MY_ZEROFILL))))
 
  510   SETMSG(HA_ERR_KEY_NOT_FOUND,          ER_DEFAULT(ER_KEY_NOT_FOUND));
 
  511   SETMSG(HA_ERR_FOUND_DUPP_KEY,         ER_DEFAULT(ER_DUP_KEY));
 
  512   SETMSG(HA_ERR_RECORD_CHANGED,         
"Update wich is recoverable");
 
  513   SETMSG(HA_ERR_WRONG_INDEX,            
"Wrong index given to function");
 
  514   SETMSG(HA_ERR_CRASHED,                ER_DEFAULT(ER_NOT_KEYFILE));
 
  515   SETMSG(HA_ERR_WRONG_IN_RECORD,        ER_DEFAULT(ER_CRASHED_ON_USAGE));
 
  516   SETMSG(HA_ERR_OUT_OF_MEM,             
"Table handler out of memory");
 
  517   SETMSG(HA_ERR_NOT_A_TABLE,            
"Incorrect file format '%.64s'");
 
  518   SETMSG(HA_ERR_WRONG_COMMAND,          
"Command not supported");
 
  519   SETMSG(HA_ERR_OLD_FILE,               ER_DEFAULT(ER_OLD_KEYFILE));
 
  520   SETMSG(HA_ERR_NO_ACTIVE_RECORD,       
"No record read in update");
 
  521   SETMSG(HA_ERR_RECORD_DELETED,         
"Intern record deleted");
 
  522   SETMSG(HA_ERR_RECORD_FILE_FULL,       ER_DEFAULT(ER_RECORD_FILE_FULL));
 
  523   SETMSG(HA_ERR_INDEX_FILE_FULL,        
"No more room in index file '%.64s'");
 
  524   SETMSG(HA_ERR_END_OF_FILE,            
"End in next/prev/first/last");
 
  525   SETMSG(HA_ERR_UNSUPPORTED,            ER_DEFAULT(ER_ILLEGAL_HA));
 
  526   SETMSG(HA_ERR_TO_BIG_ROW,             
"Too big row");
 
  527   SETMSG(HA_WRONG_CREATE_OPTION,        
"Wrong create option");
 
  528   SETMSG(HA_ERR_FOUND_DUPP_UNIQUE,      ER_DEFAULT(ER_DUP_UNIQUE));
 
  529   SETMSG(HA_ERR_UNKNOWN_CHARSET,        
"Can't open charset");
 
  530   SETMSG(HA_ERR_WRONG_MRG_TABLE_DEF,    ER_DEFAULT(ER_WRONG_MRG_TABLE));
 
  531   SETMSG(HA_ERR_CRASHED_ON_REPAIR,      ER_DEFAULT(ER_CRASHED_ON_REPAIR));
 
  532   SETMSG(HA_ERR_CRASHED_ON_USAGE,       ER_DEFAULT(ER_CRASHED_ON_USAGE));
 
  533   SETMSG(HA_ERR_LOCK_WAIT_TIMEOUT,      ER_DEFAULT(ER_LOCK_WAIT_TIMEOUT));
 
  534   SETMSG(HA_ERR_LOCK_TABLE_FULL,        ER_DEFAULT(ER_LOCK_TABLE_FULL));
 
  535   SETMSG(HA_ERR_READ_ONLY_TRANSACTION,  ER_DEFAULT(ER_READ_ONLY_TRANSACTION));
 
  536   SETMSG(HA_ERR_LOCK_DEADLOCK,          ER_DEFAULT(ER_LOCK_DEADLOCK));
 
  537   SETMSG(HA_ERR_CANNOT_ADD_FOREIGN,     ER_DEFAULT(ER_CANNOT_ADD_FOREIGN));
 
  538   SETMSG(HA_ERR_NO_REFERENCED_ROW,      ER_DEFAULT(ER_NO_REFERENCED_ROW_2));
 
  539   SETMSG(HA_ERR_ROW_IS_REFERENCED,      ER_DEFAULT(ER_ROW_IS_REFERENCED_2));
 
  540   SETMSG(HA_ERR_NO_SAVEPOINT,           
"No savepoint with that name");
 
  541   SETMSG(HA_ERR_NON_UNIQUE_BLOCK_SIZE,  
"Non unique key block size");
 
  542   SETMSG(HA_ERR_NO_SUCH_TABLE,          
"No such table: '%.64s'");
 
  543   SETMSG(HA_ERR_TABLE_EXIST,            ER_DEFAULT(ER_TABLE_EXISTS_ERROR));
 
  544   SETMSG(HA_ERR_NO_CONNECTION,          
"Could not connect to storage engine");
 
  545   SETMSG(HA_ERR_TABLE_DEF_CHANGED,      ER_DEFAULT(ER_TABLE_DEF_CHANGED));
 
  546   SETMSG(HA_ERR_FOREIGN_DUPLICATE_KEY,  
"FK constraint would lead to duplicate key");
 
  547   SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE,    ER_DEFAULT(ER_TABLE_NEEDS_UPGRADE));
 
  548   SETMSG(HA_ERR_TABLE_READONLY,         ER_DEFAULT(ER_OPEN_AS_READONLY));
 
  549   SETMSG(HA_ERR_AUTOINC_READ_FAILED,    ER_DEFAULT(ER_AUTOINC_READ_FAILED));
 
  550   SETMSG(HA_ERR_AUTOINC_ERANGE,         ER_DEFAULT(ER_WARN_DATA_OUT_OF_RANGE));
 
  551   SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER_DEFAULT(ER_TOO_MANY_CONCURRENT_TRXS));
 
  552   SETMSG(HA_ERR_INDEX_COL_TOO_LONG,     ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG));
 
  553   SETMSG(HA_ERR_INDEX_CORRUPT,          ER_DEFAULT(ER_INDEX_CORRUPT));
 
  554   SETMSG(HA_FTS_INVALID_DOCID,          
"Invalid InnoDB FTS Doc ID");
 
  555   SETMSG(HA_ERR_TABLE_IN_FK_CHECK,      ER_DEFAULT(ER_TABLE_IN_FK_CHECK));
 
  556   SETMSG(HA_ERR_TABLESPACE_EXISTS,      
"Tablespace already exists");
 
  557   SETMSG(HA_ERR_FTS_EXCEED_RESULT_CACHE_LIMIT,  
"FTS query exceeds result cache limit");
 
  560   return my_error_register(get_handler_errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
 
  572 static int ha_finish_errors(
void)
 
  574   const char    **errmsgs;
 
  577   if (! (errmsgs= my_error_unregister(HA_ERR_FIRST, HA_ERR_LAST)))
 
  587   DBUG_ENTER(
"ha_finalize_handlerton");
 
  596   case SHOW_OPTION_DISABLED:
 
  598   case SHOW_OPTION_YES:
 
  599     if (installed_htons[hton->db_type] == hton)
 
  600       installed_htons[hton->db_type]= NULL;
 
  605     hton->panic(hton, HA_PANIC_CLOSE);
 
  607   if (plugin->plugin->deinit)
 
  613     DBUG_PRINT(
"info", (
"Deinitializing plugin: '%s'", plugin->name.str));
 
  614     if (plugin->plugin->deinit(NULL))
 
  616       DBUG_PRINT(
"warning", (
"Plugin '%s' deinit function returned error.",
 
  626   if (hton->slot != HA_SLOT_UNDEF)
 
  629     DBUG_ASSERT(hton2plugin[hton->slot] == plugin);
 
  630     DBUG_ASSERT(hton->slot < MAX_HA);
 
  631     hton2plugin[hton->slot]= NULL;
 
  644   DBUG_ENTER(
"ha_initialize_handlerton");
 
  645   DBUG_PRINT(
"plugin", (
"initialize plugin: '%s'", plugin->name.str));
 
  648                                 MYF(MY_WME | MY_ZEROFILL));
 
  652     sql_print_error(
"Unable to allocate memory for plugin '%s' handlerton.",
 
  654     goto err_no_hton_memory;
 
  657   hton->slot= HA_SLOT_UNDEF;
 
  660   if (plugin->plugin->init && plugin->plugin->init(hton))
 
  662     sql_print_error(
"Plugin '%s' init function returned error.",
 
  671   DBUG_PRINT(
"info", (
"hton->state=%d", hton->state));
 
  672   switch (hton->state) {
 
  675   case SHOW_OPTION_YES:
 
  680       if (hton->db_type <= DB_TYPE_UNKNOWN ||
 
  681           hton->db_type >= DB_TYPE_DEFAULT ||
 
  682           installed_htons[hton->db_type])
 
  684         int idx= (int) DB_TYPE_FIRST_DYNAMIC;
 
  686         while (idx < (
int) DB_TYPE_DEFAULT && installed_htons[idx])
 
  689         if (idx == (
int) DB_TYPE_DEFAULT)
 
  691           sql_print_warning(
"Too many storage engines!");
 
  694         if (hton->db_type != DB_TYPE_UNKNOWN)
 
  695           sql_print_warning(
"Storage engine '%s' has conflicting typecode. " 
  696                             "Assigning value %d.", plugin->plugin->name, idx);
 
  697         hton->db_type= (
enum legacy_db_type) idx;
 
  705       DBUG_PRINT(
"plugin", (
"total_ha: %lu", total_ha));
 
  706       for (fslot= 0; fslot < total_ha; fslot++)
 
  708         if (!hton2plugin[fslot])
 
  711       if (fslot < total_ha)
 
  715         if (total_ha >= MAX_HA)
 
  717           sql_print_error(
"Too many plugins loaded. Limit is %lu. " 
  718                           "Failed on '%s'", (ulong) MAX_HA, plugin->name.str);
 
  721         hton->slot= total_ha++;
 
  723       installed_htons[hton->db_type]= hton;
 
  724       tmp= hton->savepoint_offset;
 
  725       hton->savepoint_offset= savepoint_alloc_size;
 
  726       savepoint_alloc_size+= tmp;
 
  727       hton2plugin[hton->slot]=plugin;
 
  734     hton->state= SHOW_OPTION_DISABLED;
 
  743   switch (hton->db_type) {
 
  750   case DB_TYPE_PARTITION_DB:
 
  751     partition_hton= hton;
 
  764   if (plugin->plugin->deinit)
 
  765     (void) plugin->plugin->deinit(NULL);
 
  777   DBUG_ENTER(
"ha_init");
 
  779   DBUG_ASSERT(total_ha < MAX_HA);
 
  785   opt_using_transactions= total_ha>(ulong)opt_bin_log;
 
  786   savepoint_alloc_size+= 
sizeof(SAVEPOINT);
 
  793   known_system_databases= ha_known_system_databases();
 
  801   DBUG_ENTER(
"ha_end");
 
  809   if (ha_finish_errors())
 
  815 static my_bool dropdb_handlerton(THD *unused1, 
plugin_ref plugin,
 
  819   if (hton->state == SHOW_OPTION_YES && hton->drop_database)
 
  820     hton->drop_database(hton, (
char *)path);
 
  825 void ha_drop_database(
char* path)
 
  827   plugin_foreach(NULL, dropdb_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, path);
 
  831 static my_bool closecon_handlerton(THD *thd, 
plugin_ref plugin,
 
  839   if (hton->state == SHOW_OPTION_YES && thd_get_ha_data(thd, hton))
 
  841     if (hton->close_connection)
 
  842       hton->close_connection(hton, thd);
 
  844     thd_set_ha_data(thd, hton, NULL);
 
  856   plugin_foreach(thd, closecon_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
 
 1168   Ha_trx_info *ha_info;
 
 1169   DBUG_ENTER(
"trans_register_ha");
 
 1170   DBUG_PRINT(
"enter",(
"%s", all ? 
"all" : 
"stmt"));
 
 1174     trans= &thd->transaction.all;
 
 1175     thd->server_status|= SERVER_STATUS_IN_TRANS;
 
 1176     if (thd->tx_read_only)
 
 1177       thd->server_status|= SERVER_STATUS_IN_TRANS_READONLY;
 
 1178     DBUG_PRINT(
"info", (
"setting SERVER_STATUS_IN_TRANS"));
 
 1181     trans= &thd->transaction.stmt;
 
 1183   ha_info= thd->ha_data[ht_arg->slot].ha_info + (all ? 1 : 0);
 
 1185   if (ha_info->is_started())
 
 1188   ha_info->register_ha(trans, ht_arg);
 
 1190   trans->no_2pc|=(ht_arg->prepare==0);
 
 1191   if (thd->transaction.xid_state.xid.is_null())
 
 1192     thd->transaction.xid_state.xid.set(thd->query_id);
 
 1205   THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
 1206   Ha_trx_info *ha_info= trans->ha_list;
 
 1207   DBUG_ENTER(
"ha_prepare");
 
 1211     for (; ha_info; ha_info= ha_info->next())
 
 1215       status_var_increment(thd->status_var.ha_prepare_count);
 
 1218         if ((err= ht->prepare(ht, thd, all)))
 
 1220           my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
 
 1221           ha_rollback_trans(thd, all);
 
 1228         push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
 
 1229                             ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
 
 1230                             ha_resolve_storage_engine_name(ht));
 
 1259 ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list,
 
 1263   unsigned rw_ha_count= 0;
 
 1264   Ha_trx_info *ha_info;
 
 1266   for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
 
 1268     if (ha_info->is_trx_read_write())
 
 1273       Ha_trx_info *ha_info_all= &thd->ha_data[ha_info->ht()->slot].ha_info[1];
 
 1274       DBUG_ASSERT(ha_info != ha_info_all);
 
 1282       if (ha_info_all->is_started()) 
 
 1283         ha_info_all->coalesce_trx_with(ha_info);
 
 1285     else if (rw_ha_count > 1)
 
 1326   THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
 
 1334   bool is_real_trans= all || thd->transaction.all.ha_list == 0;
 
 1335   Ha_trx_info *ha_info= trans->ha_list;
 
 1336   DBUG_ENTER(
"ha_commit_trans");
 
 1338   DBUG_PRINT(
"info", (
"all=%d thd->in_sub_stmt=%d ha_info=%p is_real_trans=%d",
 
 1339                       all, thd->in_sub_stmt, ha_info, is_real_trans));
 
 1346   DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||
 
 1347               trans == &thd->transaction.stmt);
 
 1349   if (thd->in_sub_stmt)
 
 1366     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
 1371   bool release_mdl= 
false;
 
 1378     DBUG_EXECUTE_IF(
"crash_commit_before", DBUG_SUICIDE(););
 
 1382       thd->stmt_map.close_transient_cursors();
 
 1384     rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all);
 
 1385     trans->rw_ha_count= rw_ha_count;
 
 1387     rw_trans= is_real_trans && (rw_ha_count > 0);
 
 1389     if (rw_trans && !ignore_global_read_lock)
 
 1399       mdl_request.
init(MDL_key::COMMIT, 
"", 
"", MDL_INTENTION_EXCLUSIVE,
 
 1402       DBUG_PRINT(
"debug", (
"Acquire MDL commit lock"));
 
 1403       if (thd->mdl_context.acquire_lock(&mdl_request,
 
 1404                                         thd->variables.lock_wait_timeout))
 
 1406         ha_rollback_trans(thd, all);
 
 1411       DEBUG_SYNC(thd, 
"ha_commit_trans_after_acquire_commit_lock");
 
 1416         !(thd->security_ctx->master_access & SUPER_ACL) &&
 
 1419       my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--read-only");
 
 1420       ha_rollback_trans(thd, all);
 
 1425     if (!trans->no_2pc && (rw_ha_count > 1))
 
 1426       error= tc_log->
prepare(thd, all);
 
 1428   if (error || (error= tc_log->
commit(thd, all)))
 
 1430     ha_rollback_trans(thd, all);
 
 1434   DBUG_EXECUTE_IF(
"crash_commit_after", DBUG_SUICIDE(););
 
 1436   if (release_mdl && mdl_request.
ticket)
 
 1444     DBUG_PRINT(
"debug", (
"Releasing MDL commit lock"));
 
 1445     thd->mdl_context.release_lock(mdl_request.
ticket);
 
 1449     thd->transaction.cleanup();
 
 1475   THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
 1476   Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
 
 1477   DBUG_ENTER(
"ha_commit_low");
 
 1481     for (; ha_info; ha_info= ha_info_next)
 
 1485       if ((err= ht->commit(ht, thd, all)))
 
 1487         my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
 
 1490       status_var_increment(thd->status_var.ha_commit_count);
 
 1491       ha_info_next= ha_info->next();
 
 1496     trans->rw_ha_count= 0;
 
 1499 #ifdef HAVE_QUERY_CACHE 
 1500       if (thd->transaction.changed_tables)
 
 1501         query_cache.invalidate(thd->transaction.changed_tables);
 
 1507     thd->transaction.cleanup();
 
 1513   thd->transaction.flags.commit_low= 
false;
 
 1514   if (run_after_commit)
 
 1518       (void) RUN_HOOK(transaction, after_commit, (thd, all));
 
 1519     thd->transaction.flags.run_hooks= 
false;
 
 1525 int ha_rollback_low(THD *thd, 
bool all)
 
 1527   THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
 1528   Ha_trx_info *ha_info= trans->ha_list, *ha_info_next;
 
 1535       thd->stmt_map.close_transient_cursors();
 
 1537     for (; ha_info; ha_info= ha_info_next)
 
 1541       if ((err= ht->rollback(ht, thd, all)))
 
 1543         my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
 
 1546       status_var_increment(thd->status_var.ha_rollback_count);
 
 1547       ha_info_next= ha_info->next();
 
 1552     trans->rw_ha_count= 0;
 
 1559   if (all && thd->transaction_rollback_request &&
 
 1560       thd->transaction.xid_state.xa_state != XA_NOTR)
 
 1561     thd->transaction.xid_state.rm_error= thd->get_stmt_da()->sql_errno();
 
 1563   (void) RUN_HOOK(transaction, after_rollback, (thd, all));
 
 1568 int ha_rollback_trans(THD *thd, 
bool all)
 
 1572   THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
 1587   bool is_real_trans= all || thd->transaction.all.ha_list == NULL;
 
 1588   DBUG_ENTER(
"ha_rollback_trans");
 
 1594   DBUG_ASSERT(thd->transaction.stmt.ha_list == NULL ||
 
 1595               trans == &thd->transaction.stmt);
 
 1597   if (thd->in_sub_stmt)
 
 1607     my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
 1616     thd->transaction.cleanup();
 
 1618     thd->transaction_rollback_request= FALSE;
 
 1637   thd->transaction.stmt.dbug_unsafe_rollback_flags(
"stmt");
 
 1638   thd->transaction.all.dbug_unsafe_rollback_flags(
"all");
 
 1640   if (is_real_trans && thd->transaction.all.cannot_safely_rollback() &&
 
 1641       !thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
 
 1642     thd->transaction.push_unsafe_rollback_warnings(thd);
 
 1652 static my_bool xacommit_handlerton(THD *unused1, 
plugin_ref plugin,
 
 1656   if (hton->state == SHOW_OPTION_YES && hton->recover)
 
 1658     hton->commit_by_xid(hton, ((
struct xahton_st *)arg)->xid);
 
 1664 static my_bool xarollback_handlerton(THD *unused1, 
plugin_ref plugin,
 
 1668   if (hton->state == SHOW_OPTION_YES && hton->recover)
 
 1670     hton->rollback_by_xid(hton, ((
struct xahton_st *)arg)->xid);
 
 1677 int ha_commit_or_rollback_by_xid(THD *thd, 
XID *xid, 
bool commit)
 
 1683   plugin_foreach(NULL, commit ? xacommit_handlerton : xarollback_handlerton,
 
 1684                  MYSQL_STORAGE_ENGINE_PLUGIN, &xaop);
 
 1697 static char* xid_to_str(
char *
buf, 
XID *xid)
 
 1704     uchar c=(uchar)xid->
data[i];
 
 1706     bool is_next_dig= FALSE;
 
 1707     if (i < XIDDATASIZE)
 
 1709       char ch= xid->
data[i+1];
 
 1710       is_next_dig= (ch >= 
'0' && ch <=
'9');
 
 1721     if (c < 32 || c > 126)
 
 1729       if (c > 077 || is_next_dig)
 
 1730         *s++=_dig_vec_lower[c >> 6];
 
 1731       if (c > 007 || is_next_dig)
 
 1732         *s++=_dig_vec_lower[(c >> 3) & 7];
 
 1733       *s++=_dig_vec_lower[c & 7];
 
 1737       if (c == 
'\'' || c == 
'\\')
 
 1766   int len, found_foreign_xids, found_my_xids;
 
 1772 static my_bool xarecover_handlerton(THD *unused, 
plugin_ref plugin,
 
 1779   if (hton->state == SHOW_OPTION_YES && hton->recover)
 
 1781     while ((got= hton->recover(hton, info->list, info->len)) > 0 )
 
 1783       sql_print_information(
"Found %d prepared transaction(s) in %s",
 
 1784                             got, ha_resolve_storage_engine_name(hton));
 
 1785       for (
int i=0; i < got; i ++)
 
 1787         my_xid x=info->list[
i].get_my_xid();
 
 1791           char buf[XIDDATASIZE*4+6]; 
 
 1792           sql_print_information(
"ignore xid %s", xid_to_str(buf, info->list+i));
 
 1794           xid_cache_insert(info->list+i, XA_PREPARED);
 
 1795           info->found_foreign_xids++;
 
 1800           info->found_my_xids++;
 
 1804         if (info->commit_list ?
 
 1805             my_hash_search(info->commit_list, (uchar *)&x, 
sizeof(x)) != 0 :
 
 1806             tc_heuristic_recover == TC_HEURISTIC_RECOVER_COMMIT)
 
 1809           char buf[XIDDATASIZE*4+6]; 
 
 1810           sql_print_information(
"commit xid %s", xid_to_str(buf, info->list+i));
 
 1812           hton->commit_by_xid(hton, info->list+i);
 
 1817           char buf[XIDDATASIZE*4+6]; 
 
 1818           sql_print_information(
"rollback xid %s",
 
 1819                                 xid_to_str(buf, info->list+i));
 
 1821           hton->rollback_by_xid(hton, info->list+i);
 
 1824       if (got < info->len)
 
 1831 int ha_recover(
HASH *commit_list)
 
 1834   DBUG_ENTER(
"ha_recover");
 
 1835   info.found_foreign_xids= info.found_my_xids= 0;
 
 1836   info.commit_list= commit_list;
 
 1837   info.dry_run= (info.commit_list==0 && tc_heuristic_recover==0);
 
 1841   DBUG_ASSERT(info.commit_list==0 || tc_heuristic_recover==0);
 
 1843   DBUG_ASSERT(info.dry_run || total_ha_2pc>(ulong)opt_bin_log);
 
 1845   if (total_ha_2pc <= (ulong)opt_bin_log)
 
 1848   if (info.commit_list)
 
 1849     sql_print_information(
"Starting crash recovery...");
 
 1851 #ifndef WILL_BE_DELETED_LATER 
 1856   DBUG_ASSERT(total_ha_2pc == (ulong) opt_bin_log+1); 
 
 1857   tc_heuristic_recover= TC_HEURISTIC_RECOVER_ROLLBACK; 
 
 1861   for (info.len= MAX_XID_LIST_SIZE ; 
 
 1862        info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2)
 
 1864     info.list=(
XID *)my_malloc(info.len*
sizeof(
XID), MYF(0));
 
 1868     sql_print_error(ER(ER_OUTOFMEMORY),
 
 1869                     static_cast<int>(info.len*
sizeof(
XID)));
 
 1873   plugin_foreach(NULL, xarecover_handlerton, 
 
 1874                  MYSQL_STORAGE_ENGINE_PLUGIN, &info);
 
 1877   if (info.found_foreign_xids)
 
 1878     sql_print_warning(
"Found %d prepared XA transactions", 
 
 1879                       info.found_foreign_xids);
 
 1880   if (info.dry_run && info.found_my_xids)
 
 1882     sql_print_error(
"Found %d prepared transactions! It means that mysqld was " 
 1883                     "not shut down properly last time and critical recovery " 
 1884                     "information (last binlog or %s file) was manually deleted " 
 1885                     "after a crash. You have to start mysqld with " 
 1886                     "--tc-heuristic-recover switch to commit or rollback " 
 1887                     "pending transactions.",
 
 1888                     info.found_my_xids, opt_tc_log_file);
 
 1891   if (info.commit_list)
 
 1892     sql_print_information(
"Crash recovery finished.");
 
 1910   DBUG_ENTER(
"mysql_xa_recover");
 
 1912   field_list.push_back(
new Item_int(NAME_STRING(
"formatID"), 0, MY_INT32_NUM_DECIMAL_DIGITS));
 
 1913   field_list.push_back(
new Item_int(NAME_STRING(
"gtrid_length"), 0, MY_INT32_NUM_DECIMAL_DIGITS));
 
 1914   field_list.push_back(
new Item_int(NAME_STRING(
"bqual_length"), 0, MY_INT32_NUM_DECIMAL_DIGITS));
 
 1918                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
 1922   while ((xs= (XID_STATE*) my_hash_element(&xid_cache, i++)))
 
 1924     if (xs->xa_state==XA_PREPARED)
 
 1926       protocol->prepare_for_resend();
 
 1927       protocol->store_longlong((longlong)xs->xid.formatID, FALSE);
 
 1928       protocol->store_longlong((longlong)xs->xid.gtrid_length, FALSE);
 
 1929       protocol->store_longlong((longlong)xs->xid.bqual_length, FALSE);
 
 1930       protocol->
store(xs->xid.data, xs->xid.gtrid_length+xs->xid.bqual_length,
 
 1932       if (protocol->write())
 
 1974   for (info= thd->transaction.stmt.ha_list; info; info= info->next())
 
 1977     if (hton && hton->release_temporary_latches)
 
 1978         hton->release_temporary_latches(hton, thd);
 
 1983 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
 
 1986   THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
 
 1987                                         &thd->transaction.all);
 
 1988   Ha_trx_info *ha_info, *ha_info_next;
 
 1990   DBUG_ENTER(
"ha_rollback_to_savepoint");
 
 1993   trans->rw_ha_count= 0;
 
 1998   for (ha_info= sv->ha_list; ha_info; ha_info= ha_info->next())
 
 2003     DBUG_ASSERT(ht->savepoint_set != 0);
 
 2004     if ((err= ht->savepoint_rollback(ht, thd,
 
 2005                                      (uchar *)(sv+1)+ht->savepoint_offset)))
 
 2007       my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
 
 2010     status_var_increment(thd->status_var.ha_savepoint_rollback_count);
 
 2011     trans->no_2pc|= ht->prepare == 0;
 
 2017   for (ha_info= trans->ha_list; ha_info != sv->ha_list;
 
 2018        ha_info= ha_info_next)
 
 2022     if ((err= ht->rollback(ht, thd, !thd->in_sub_stmt)))
 
 2024       my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
 
 2027     status_var_increment(thd->status_var.ha_rollback_count);
 
 2028     ha_info_next= ha_info->next();
 
 2031   trans->ha_list= sv->ha_list;
 
 2035 int ha_prepare_low(THD *thd, 
bool all)
 
 2038   THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
 
 2039   Ha_trx_info *ha_info= trans->ha_list;
 
 2040   DBUG_ENTER(
"ha_prepare_low");
 
 2044     for (; ha_info && !error; ha_info= ha_info->next())
 
 2053       if (!ha_info->is_trx_read_write())
 
 2055       if ((err= ht->prepare(ht, thd, all)))
 
 2057         my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
 
 2060       status_var_increment(thd->status_var.ha_prepare_count);
 
 2062     DBUG_EXECUTE_IF(
"crash_commit_after_prepare", DBUG_SUICIDE(););
 
 2077   THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
 
 2078                                         &thd->transaction.all);
 
 2079   Ha_trx_info *ha_info= trans->ha_list;
 
 2080   DBUG_ENTER(
"ha_savepoint");
 
 2082   for (; ha_info; ha_info= ha_info->next())
 
 2087     if (! ht->savepoint_set)
 
 2089       my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), 
"SAVEPOINT");
 
 2093     if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset)))
 
 2095       my_error(ER_GET_ERRNO, MYF(0), err);
 
 2098     status_var_increment(thd->status_var.ha_savepoint_count);
 
 2104   sv->ha_list= trans->ha_list;
 
 2109 int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
 
 2112   Ha_trx_info *ha_info= sv->ha_list;
 
 2113   DBUG_ENTER(
"ha_release_savepoint");
 
 2115   for (; ha_info; ha_info= ha_info->next())
 
 2121     if (!ht->savepoint_release)
 
 2123     if ((err= ht->savepoint_release(ht, thd,
 
 2124                                     (uchar *)(sv+1) + ht->savepoint_offset)))
 
 2126       my_error(ER_GET_ERRNO, MYF(0), err);
 
 2134 static my_bool snapshot_handlerton(THD *thd, 
plugin_ref plugin,
 
 2138   if (hton->state == SHOW_OPTION_YES &&
 
 2139       hton->start_consistent_snapshot)
 
 2141     hton->start_consistent_snapshot(hton, thd);
 
 2142     *((
bool *)arg)= 
false;
 
 2147 int ha_start_consistent_snapshot(THD *thd)
 
 2151   plugin_foreach(thd, snapshot_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &warn);
 
 2158     push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
 
 2159                  "This MySQL server does not support any " 
 2160                  "consistent-read capable storage engine");
 
 2165 static my_bool flush_handlerton(THD *thd, 
plugin_ref plugin,
 
 2169   if (hton->state == SHOW_OPTION_YES && hton->flush_logs && 
 
 2170       hton->flush_logs(hton))
 
 2178   if (db_type == NULL)
 
 2180     if (plugin_foreach(NULL, flush_handlerton,
 
 2181                           MYSQL_STORAGE_ENGINE_PLUGIN, 0))
 
 2186     if (db_type->state != SHOW_OPTION_YES ||
 
 2187         (db_type->flush_logs && db_type->flush_logs(db_type)))
 
 2220   if (lower_case_table_names != 2 || (file->
ha_table_flags() & HA_FILE_BASED))
 
 2223   for (i= 0; i <= mysql_tmpdir_list.max; i++)
 
 2225     if (is_prefix(path, mysql_tmpdir_list.list[i]))
 
 2230   if (tmp_path != path)
 
 2231     strmov(tmp_path, path);
 
 2237   my_casedn_str(files_charset_info, tmp_path + mysql_data_home_len);
 
 2251   virtual bool handle_condition(THD *thd,
 
 2253                                 const char* sqlstate,
 
 2254                                 Sql_condition::enum_warning_level 
level,
 
 2257   char buff[MYSQL_ERRMSG_SIZE];
 
 2262 Ha_delete_table_error_handler::
 
 2263 handle_condition(THD *,
 
 2266                  Sql_condition::enum_warning_level,
 
 2272   strmake(buff, msg, 
sizeof(buff)-1);
 
 2282                     const char *db, 
const char *alias, 
bool generate_warning)
 
 2285   char tmp_path[FN_REFLEN];
 
 2289   DBUG_ENTER(
"ha_delete_table");
 
 2291   memset(&dummy_table, 0, 
sizeof(dummy_table));
 
 2292   memset(&dummy_share, 0, 
sizeof(dummy_share));
 
 2293   dummy_table.s= &dummy_share;
 
 2296   if (table_type == NULL ||
 
 2297       ! (file=get_new_handler((
TABLE_SHARE*)0, thd->mem_root, table_type)))
 
 2298     DBUG_RETURN(ENOENT);
 
 2312     dummy_share.path.str= (
char*) path;
 
 2313     dummy_share.path.length= strlen(path);
 
 2314     dummy_share.db.str= (
char*) db;
 
 2315     dummy_share.db.length= strlen(db);
 
 2316     dummy_share.table_name.str= (
char*) alias;
 
 2317     dummy_share.table_name.length= strlen(alias);
 
 2318     dummy_table.alias= alias;
 
 2320     file->change_table_ptr(&dummy_table, &dummy_share);
 
 2322     thd->push_internal_handler(&ha_delete_table_error_handler);
 
 2325     thd->pop_internal_handler();
 
 2331     push_warning(thd, Sql_condition::WARN_LEVEL_WARN, error,
 
 2332                 ha_delete_table_error_handler.buff);
 
 2336 #ifdef HAVE_PSI_TABLE_INTERFACE 
 2337   if (likely(error == 0))
 
 2341       (temp_table, db, strlen(db), alias, strlen(alias));
 
 2353   handler *new_handler= get_new_handler(table->s, mem_root, ht);
 
 2357   if (new_handler->set_ha_share_ref(ha_share))
 
 2365   if (!(new_handler->ref= (uchar*) alloc_root(mem_root,
 
 2372   if (new_handler->
ha_open(table, name, table->db_stat,
 
 2373                            HA_OPEN_IGNORE_IF_LOCKED))
 
 2385 void handler::ha_statistic_increment(ulonglong 
SSV::*
offset)
 const 
 2387   status_var_increment(table->in_use->status_var.*offset);
 
 2390 void **handler::ha_data(THD *thd)
 const 
 2392   return thd_ha_data(thd, ht);
 
 2395 THD *handler::ha_thd(
void)
 const 
 2397   DBUG_ASSERT(!table || !table->in_use || table->in_use == current_thd);
 
 2398   return (table && table->in_use) ? table->in_use : current_thd;
 
 2401 void handler::unbind_psi()
 
 2403 #ifdef HAVE_PSI_TABLE_INTERFACE 
 2404   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 2405   DBUG_ASSERT(inited == NONE);
 
 2410   PSI_TABLE_CALL(unbind_table)(
m_psi);
 
 2414 void handler::rebind_psi()
 
 2416 #ifdef HAVE_PSI_TABLE_INTERFACE 
 2417   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 2418   DBUG_ASSERT(inited == NONE);
 
 2424   m_psi= PSI_TABLE_CALL(rebind_table)(share_psi, 
this, 
m_psi);
 
 2430   return share->
m_psi;
 
 2444   DBUG_ENTER(
"handler::ha_open");
 
 2446              (
"name: %s  db_type: %d  db_stat: %d  mode: %d  lock_test: %d",
 
 2447               name, ht->db_type, table_arg->db_stat, mode,
 
 2451   DBUG_ASSERT(table->s == table_share);
 
 2452   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 2453   DBUG_PRINT(
"info", (
"old m_lock_type: %d F_UNLCK %d", m_lock_type, F_UNLCK));
 
 2454   DBUG_ASSERT(alloc_root_inited(&table->
mem_root));
 
 2456   if ((error=open(name,mode,test_if_locked)))
 
 2458     if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
 
 2459         (table->db_stat & HA_TRY_READ_ONLY))
 
 2461       table->db_stat|=HA_READ_ONLY;
 
 2462       error=open(name,O_RDONLY,test_if_locked);
 
 2468     DBUG_PRINT(
"error",(
"error: %d  errno: %d",error,errno));
 
 2472     DBUG_ASSERT(
m_psi == NULL);
 
 2473     DBUG_ASSERT(table_share != NULL);
 
 2474 #ifdef HAVE_PSI_TABLE_INTERFACE 
 2480     if (!(test_if_locked & HA_OPEN_NO_PSI_CALL))
 
 2487     if (table->s->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
 
 2488       table->db_stat|=HA_READ_ONLY;
 
 2489     (void) 
extra(HA_EXTRA_NO_READCHECK);        
 
 2492     if (!ref && !(ref= (uchar*) alloc_root(&table->
mem_root, 
 
 2496       error=HA_ERR_OUT_OF_MEM;
 
 2500     cached_table_flags= table_flags();
 
 2512   DBUG_ENTER(
"handler::ha_close");
 
 2513 #ifdef HAVE_PSI_TABLE_INTERFACE 
 2514   PSI_TABLE_CALL(close_table)(
m_psi);
 
 2518   DBUG_ASSERT(
m_psi == NULL);
 
 2519   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 2520   DBUG_ASSERT(inited == NONE);
 
 2521   DBUG_RETURN(close());
 
 2538   DBUG_EXECUTE_IF(
"ha_index_init_fail", 
return HA_ERR_TABLE_DEF_CHANGED;);
 
 2540   DBUG_ENTER(
"ha_index_init");
 
 2541   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2542               m_lock_type != F_UNLCK);
 
 2543   DBUG_ASSERT(inited == NONE);
 
 2544   if (!(result= index_init(idx, sorted)))
 
 2547   DBUG_RETURN(result);
 
 2561   DBUG_ENTER(
"ha_index_end");
 
 2563   DBUG_ASSERT(table->open_by_handler ||
 
 2564               table_share->tmp_table != NO_TMP_TABLE ||
 
 2565               m_lock_type != F_UNLCK);
 
 2566   DBUG_ASSERT(inited == INDEX);
 
 2569   DBUG_RETURN(index_end());
 
 2586   DBUG_EXECUTE_IF(
"ha_rnd_init_fail", 
return HA_ERR_TABLE_DEF_CHANGED;);
 
 2588   DBUG_ENTER(
"ha_rnd_init");
 
 2589   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2590               m_lock_type != F_UNLCK);
 
 2591   DBUG_ASSERT(inited == NONE || (inited == RND && scan));
 
 2592   inited= (result= rnd_init(scan)) ? NONE : RND;
 
 2594   DBUG_RETURN(result);
 
 2608   DBUG_ENTER(
"ha_rnd_end");
 
 2610   DBUG_ASSERT(table->open_by_handler ||
 
 2611               table_share->tmp_table != NO_TMP_TABLE ||
 
 2612               m_lock_type != F_UNLCK);
 
 2613   DBUG_ASSERT(inited == RND);
 
 2616   DBUG_RETURN(rnd_end());
 
 2633   DBUG_ENTER(
"handler::ha_rnd_next");
 
 2634   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2635               m_lock_type != F_UNLCK);
 
 2636   DBUG_ASSERT(inited == RND);
 
 2640   DBUG_RETURN(result);
 
 2658   DBUG_ENTER(
"handler::ha_rnd_pos");
 
 2659   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2660               m_lock_type != F_UNLCK);
 
 2665     { result= 
rnd_pos(buf, pos); })
 
 2666   DBUG_RETURN(result);
 
 2694                                key_part_map keypart_map,
 
 2695                                enum ha_rkey_function find_flag)
 
 2698   DBUG_ENTER(
"handler::ha_index_read_map");
 
 2699   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2700               m_lock_type != F_UNLCK);
 
 2701   DBUG_ASSERT(inited == INDEX);
 
 2705   DBUG_RETURN(result);
 
 2708 int handler::ha_index_read_last_map(uchar *buf, 
const uchar *key,
 
 2709                                     key_part_map keypart_map)
 
 2712   DBUG_ENTER(
"handler::ha_index_read_last_map");
 
 2713   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2714               m_lock_type != F_UNLCK);
 
 2715   DBUG_ASSERT(inited == INDEX);
 
 2719   DBUG_RETURN(result);
 
 2730                                    key_part_map keypart_map,
 
 2731                                    enum ha_rkey_function find_flag)
 
 2734   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2735               m_lock_type != F_UNLCK);
 
 2736   DBUG_ASSERT(end_range == NULL);
 
 2758   DBUG_ENTER(
"handler::ha_index_next");
 
 2759   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2760               m_lock_type != F_UNLCK);
 
 2761   DBUG_ASSERT(inited == INDEX);
 
 2765   DBUG_RETURN(result);
 
 2783   DBUG_ENTER(
"handler::ha_index_prev");
 
 2784   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2785               m_lock_type != F_UNLCK);
 
 2786   DBUG_ASSERT(inited == INDEX);
 
 2790   DBUG_RETURN(result);
 
 2808   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2809               m_lock_type != F_UNLCK);
 
 2810   DBUG_ASSERT(inited == INDEX);
 
 2832   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2833               m_lock_type != F_UNLCK);
 
 2834   DBUG_ASSERT(inited == INDEX);
 
 2858   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2859               m_lock_type != F_UNLCK);
 
 2860   DBUG_ASSERT(inited == INDEX);
 
 2883                            enum ha_rkey_function find_flag)
 
 2886   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2887               m_lock_type != F_UNLCK);
 
 2888   DBUG_ASSERT(inited == INDEX);
 
 2891     { result= index_read(buf, key, key_len, find_flag); })
 
 2912   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 2913               m_lock_type != F_UNLCK);
 
 2914   DBUG_ASSERT(inited == INDEX);
 
 2917     { result= index_read_last(buf, key, key_len); })
 
 2931   DBUG_ENTER(
"handler::read_first_row");
 
 2933   ha_statistic_increment(&SSV::ha_read_first_count);
 
 2940   if (
stats.deleted < 10 || primary_key >= MAX_KEY ||
 
 2941       !(index_flags(primary_key, 0, 0) & HA_READ_ORDER))
 
 2945       while ((error= 
rnd_next(buf)) == HA_ERR_RECORD_DELETED)
 
 2981   const ulonglong save_nr= nr;
 
 2983   if (variables->auto_increment_increment == 1)
 
 2987     nr= (((nr+ variables->auto_increment_increment -
 
 2988            variables->auto_increment_offset)) /
 
 2989          (ulonglong) variables->auto_increment_increment);
 
 2990     nr= (nr* (ulonglong) variables->auto_increment_increment +
 
 2991          variables->auto_increment_offset);
 
 2994   if (unlikely(nr <= save_nr))
 
 2995     return ULONGLONG_MAX;
 
 3001 void handler::adjust_next_insert_id_after_explicit_value(ulonglong nr)
 
 3031   if (unlikely(nr < variables->auto_increment_offset))
 
 3038     DBUG_PRINT(
"info",(
"auto_increment: nr: %lu cannot honour " 
 3039                        "auto_increment_offset: %lu",
 
 3040                        (ulong) nr, variables->auto_increment_offset));
 
 3043   if (variables->auto_increment_increment == 1)
 
 3045   nr= (((nr - variables->auto_increment_offset)) /
 
 3046        (ulonglong) variables->auto_increment_increment);
 
 3047   return (nr * (ulonglong) variables->auto_increment_increment +
 
 3048           variables->auto_increment_offset);
 
 3127 #define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here 
 3128 #define AUTO_INC_DEFAULT_NB_MAX_BITS 16 
 3129 #define AUTO_INC_DEFAULT_NB_MAX ((1 << AUTO_INC_DEFAULT_NB_MAX_BITS) - 1) 
 3131 int handler::update_auto_increment()
 
 3133   ulonglong nr, nb_reserved_values;
 
 3135   THD *thd= table->in_use;
 
 3137   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 3138               m_lock_type != F_UNLCK);
 
 3139   DBUG_ENTER(
"handler::update_auto_increment");
 
 3147   if ((nr= 
table->next_number_field->val_int()) != 0 ||
 
 3148       (
table->auto_increment_field_not_null &&
 
 3149       thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO))
 
 3157     adjust_next_insert_id_after_explicit_value(nr);
 
 3166       thd->auto_inc_intervals_forced.get_next();
 
 3169       nr= forced->minimum();
 
 3170       nb_reserved_values= forced->values();
 
 3178       ulonglong nb_desired_values;
 
 3193         nb_desired_values= estimation_rows_to_insert;
 
 3195                (thd->lex->many_values.elements > 0))
 
 3202         nb_desired_values= thd->lex->many_values.elements;
 
 3211           set_if_smaller(nb_desired_values, AUTO_INC_DEFAULT_NB_MAX);
 
 3214           nb_desired_values= AUTO_INC_DEFAULT_NB_MAX;
 
 3218                          variables->auto_increment_increment,
 
 3219                          nb_desired_values, &nr,
 
 3220                          &nb_reserved_values);
 
 3221       if (nr == ULONGLONG_MAX)
 
 3222         DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED);  
 
 3235     if (
table->s->next_number_keypart == 0)
 
 3248       DBUG_PRINT(
"info",(
"auto_increment: special not-first-in-index"));
 
 3252   if (unlikely(nr == ULONGLONG_MAX))
 
 3253       DBUG_RETURN(HA_ERR_AUTOINC_ERANGE); 
 
 3255   DBUG_PRINT(
"info",(
"auto_increment: %lu", (ulong) nr));
 
 3257   if (unlikely(
table->next_number_field->store((longlong) nr, TRUE)))
 
 3262     if (thd->killed == THD::KILL_BAD_DATA)
 
 3263       DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
 
 3274     if (unlikely(
table->next_number_field->store((longlong) nr, TRUE)))
 
 3275       nr= 
table->next_number_field->val_int();
 
 3280                                           variables->auto_increment_increment);
 
 3283     if (mysql_bin_log.is_open() && !thd->is_current_stmt_binlog_format_row())
 
 3286                                                               variables->auto_increment_increment);
 
 3322   DBUG_ENTER(
"column_bitmaps_signal");
 
 3323   DBUG_PRINT(
"info", (
"read_set: 0x%lx  write_set: 0x%lx", (
long) 
table->read_set,
 
 3324                       (
long)
table->write_set));
 
 3346                                  ulonglong nb_desired_values,
 
 3347                                  ulonglong *first_value,
 
 3348                                  ulonglong *nb_reserved_values)
 
 3352   DBUG_ENTER(
"handler::get_auto_increment");
 
 3354   (void) 
extra(HA_EXTRA_KEYREAD);
 
 3355   table->mark_columns_used_by_index_no_reset(
table->s->next_number_index,
 
 3363     *first_value= ULONGLONG_MAX;
 
 3367   if (
table->s->next_number_keypart == 0)
 
 3375     *nb_reserved_values= ULONGLONG_MAX;
 
 3379     uchar key[MAX_KEY_LENGTH];
 
 3380     key_copy(key, 
table->record[0],
 
 3381              table->key_info + 
table->s->next_number_index,
 
 3382              table->s->next_number_key_offset);
 
 3384                              make_prev_keypart_map(
table->s->next_number_keypart),
 
 3385                              HA_READ_PREFIX_LAST);
 
 3392     *nb_reserved_values= 1;
 
 3397     if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
 
 3409     nr= ((ulonglong) 
table->next_number_field->
 
 3410          val_int_offset(
table->s->rec_buff_length)+1);
 
 3412   (void) 
extra(HA_EXTRA_NO_KEYREAD);
 
 3418 void handler::ha_release_auto_increment()
 
 3420   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 3421               m_lock_type != F_UNLCK ||
 
 3423   release_auto_increment();
 
 3434     table->in_use->auto_inc_intervals_forced.empty();
 
 3454   char key_buff[MAX_KEY_LENGTH];
 
 3455   String str(key_buff,
sizeof(key_buff),system_charset_info);
 
 3460     str.copy(
"", 0, system_charset_info);
 
 3461     my_printf_error(ER_DUP_ENTRY, msg, errflag, str.c_ptr(), 
"*UNKNOWN*");
 
 3466     key_unpack(&str,table, key);
 
 3467     uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(msg);
 
 3468     if (str.length() >= max_length)
 
 3470       str.length(max_length-4);
 
 3471       str.append(STRING_WITH_LEN(
"..."));
 
 3473     my_printf_error(ER_DUP_ENTRY, msg, errflag, str.c_ptr_safe(), key->
name);
 
 3502   DBUG_ENTER(
"handler::print_error");
 
 3503   DBUG_PRINT(
"enter",(
"error: %d",error));
 
 3505   int textno=ER_GET_ERRNO;
 
 3508     textno=ER_OPEN_AS_READONLY;
 
 3511     textno=ER_FILE_USED;
 
 3515       char errbuf[MYSYS_STRERROR_SIZE];
 
 3516       textno=ER_FILE_NOT_FOUND;
 
 3517       my_error(textno, errflag, table_share->table_name.str,
 
 3518                error, my_strerror(errbuf, 
sizeof(errbuf), error));
 
 3521   case HA_ERR_KEY_NOT_FOUND:
 
 3522   case HA_ERR_NO_ACTIVE_RECORD:
 
 3523   case HA_ERR_RECORD_DELETED:
 
 3524   case HA_ERR_END_OF_FILE:
 
 3525     textno=ER_KEY_NOT_FOUND;
 
 3527   case HA_ERR_WRONG_MRG_TABLE_DEF:
 
 3528     textno=ER_WRONG_MRG_TABLE;
 
 3530   case HA_ERR_FOUND_DUPP_KEY:
 
 3533     if ((
int) key_nr >= 0)
 
 3536                          key_nr == MAX_KEY ? NULL : &
table->key_info[key_nr],
 
 3543   case HA_ERR_FOREIGN_DUPLICATE_KEY:
 
 3545     DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 3546                 m_lock_type != F_UNLCK);
 
 3548     char rec_buf[MAX_KEY_LENGTH];
 
 3549     String rec(rec_buf, 
sizeof(rec_buf), system_charset_info);
 
 3556     key_unpack(&rec, 
table, &
table->key_info[0]);
 
 3558     char child_table_name[NAME_LEN + 1];
 
 3559     char child_key_name[NAME_LEN + 1];
 
 3561                             child_key_name, 
sizeof(child_key_name)))
 
 3563       my_error(ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO, errflag,
 
 3564                table_share->table_name.str, rec.c_ptr_safe(),
 
 3565                child_table_name, child_key_name);
 
 3569       my_error(ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO, errflag,
 
 3570                table_share->table_name.str, rec.c_ptr_safe());
 
 3574   case HA_ERR_NULL_IN_SPATIAL:
 
 3575     my_error(ER_CANT_CREATE_GEOMETRY_OBJECT, errflag);
 
 3577   case HA_ERR_FOUND_DUPP_UNIQUE:
 
 3578     textno=ER_DUP_UNIQUE;
 
 3580   case HA_ERR_RECORD_CHANGED:
 
 3581     textno=ER_CHECKREAD;
 
 3583   case HA_ERR_CRASHED:
 
 3584     textno=ER_NOT_KEYFILE;
 
 3586   case HA_ERR_WRONG_IN_RECORD:
 
 3587     textno= ER_CRASHED_ON_USAGE;
 
 3589   case HA_ERR_CRASHED_ON_USAGE:
 
 3590     textno=ER_CRASHED_ON_USAGE;
 
 3592   case HA_ERR_NOT_A_TABLE:
 
 3595   case HA_ERR_CRASHED_ON_REPAIR:
 
 3596     textno=ER_CRASHED_ON_REPAIR;
 
 3598   case HA_ERR_OUT_OF_MEM:
 
 3599     textno=ER_OUT_OF_RESOURCES;
 
 3601   case HA_ERR_WRONG_COMMAND:
 
 3602     textno=ER_ILLEGAL_HA;
 
 3604   case HA_ERR_OLD_FILE:
 
 3605     textno=ER_OLD_KEYFILE;
 
 3607   case HA_ERR_UNSUPPORTED:
 
 3608     textno=ER_UNSUPPORTED_EXTENSION;
 
 3610   case HA_ERR_RECORD_FILE_FULL:
 
 3611   case HA_ERR_INDEX_FILE_FULL:
 
 3613     textno=ER_RECORD_FILE_FULL;
 
 3615     errflag|= ME_NOREFRESH;
 
 3618   case HA_ERR_LOCK_WAIT_TIMEOUT:
 
 3619     textno=ER_LOCK_WAIT_TIMEOUT;
 
 3621   case HA_ERR_LOCK_TABLE_FULL:
 
 3622     textno=ER_LOCK_TABLE_FULL;
 
 3624   case HA_ERR_LOCK_DEADLOCK:
 
 3625     textno=ER_LOCK_DEADLOCK;
 
 3627   case HA_ERR_READ_ONLY_TRANSACTION:
 
 3628     textno=ER_READ_ONLY_TRANSACTION;
 
 3630   case HA_ERR_CANNOT_ADD_FOREIGN:
 
 3631     textno=ER_CANNOT_ADD_FOREIGN;
 
 3633   case HA_ERR_ROW_IS_REFERENCED:
 
 3637     my_error(ER_ROW_IS_REFERENCED_2, errflag, str.c_ptr_safe());
 
 3640   case HA_ERR_NO_REFERENCED_ROW:
 
 3644     my_error(ER_NO_REFERENCED_ROW_2, errflag, str.c_ptr_safe());
 
 3647   case HA_ERR_TABLE_DEF_CHANGED:
 
 3648     textno=ER_TABLE_DEF_CHANGED;
 
 3650   case HA_ERR_NO_SUCH_TABLE:
 
 3651     my_error(ER_NO_SUCH_TABLE, errflag, table_share->db.str,
 
 3652              table_share->table_name.str);
 
 3654   case HA_ERR_RBR_LOGGING_FAILED:
 
 3655     textno= ER_BINLOG_ROW_LOGGING_FAILED;
 
 3657   case HA_ERR_DROP_INDEX_FK:
 
 3659     const char *ptr= 
"???";
 
 3661     if ((
int) key_nr >= 0)
 
 3662       ptr= 
table->key_info[key_nr].name;
 
 3663     my_error(ER_DROP_INDEX_FK, errflag, ptr);
 
 3666   case HA_ERR_TABLE_NEEDS_UPGRADE:
 
 3667     textno=ER_TABLE_NEEDS_UPGRADE;
 
 3669   case HA_ERR_NO_PARTITION_FOUND:
 
 3670     textno=ER_WRONG_PARTITION_NAME;
 
 3672   case HA_ERR_TABLE_READONLY:
 
 3673     textno= ER_OPEN_AS_READONLY;
 
 3675   case HA_ERR_AUTOINC_READ_FAILED:
 
 3676     textno= ER_AUTOINC_READ_FAILED;
 
 3678   case HA_ERR_AUTOINC_ERANGE:
 
 3679     textno= ER_WARN_DATA_OUT_OF_RANGE;
 
 3681   case HA_ERR_TOO_MANY_CONCURRENT_TRXS:
 
 3682     textno= ER_TOO_MANY_CONCURRENT_TRXS;
 
 3684   case HA_ERR_INDEX_COL_TOO_LONG:
 
 3685     textno= ER_INDEX_COLUMN_TOO_LONG;
 
 3687   case HA_ERR_NOT_IN_LOCK_PARTITIONS:
 
 3688     textno=ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET;
 
 3690   case HA_ERR_INDEX_CORRUPT:
 
 3691     textno= ER_INDEX_CORRUPT;
 
 3693   case HA_ERR_UNDO_REC_TOO_BIG:
 
 3694     textno= ER_UNDO_RECORD_TOO_BIG;
 
 3696   case HA_ERR_TABLE_IN_FK_CHECK:
 
 3697     textno= ER_TABLE_IN_FK_CHECK;
 
 3699   case HA_WRONG_CREATE_OPTION:
 
 3700     textno= ER_ILLEGAL_HA;
 
 3702   case HA_ERR_TOO_MANY_FIELDS:
 
 3703     textno= ER_TOO_MANY_FIELDS;
 
 3705   case HA_ERR_INNODB_READ_ONLY:
 
 3706     textno= ER_INNODB_READ_ONLY;
 
 3712       bool temporary= FALSE;
 
 3715       if (!str.is_empty())
 
 3719           my_error(ER_GET_TEMPORARY_ERRMSG, errflag, error, str.ptr(), engine);
 
 3721           my_error(ER_GET_ERRMSG, errflag, error, str.ptr(), engine);
 
 3724         my_error(ER_GET_ERRNO,errflag,error);
 
 3728   if (textno != ER_FILE_NOT_FOUND)
 
 3729     my_error(textno, errflag, table_share->table_name.str, error);
 
 3760   ulong mysql_version= 
table->s->mysql_version;
 
 3762   if (mysql_version < 50124)
 
 3765     KEY *key_end= key + 
table->s->keys;
 
 3766     for (; key < key_end; key++)
 
 3770       for (; key_part < key_part_end; key_part++)
 
 3772         if (!key_part->fieldnr)
 
 3774         Field *field= 
table->field[key_part->fieldnr - 1];
 
 3775         uint cs_number= field->charset()->number;
 
 3776         if ((mysql_version < 50048 &&
 
 3784               cs_number == 26)) || 
 
 3785              (mysql_version < 50124 &&
 
 3788           return HA_ADMIN_NEEDS_UPGRADE;
 
 3796 int handler::ha_check_for_upgrade(
HA_CHECK_OPT *check_opt)
 
 3799   KEY *keyinfo, *keyend;
 
 3802   if (!
table->s->mysql_version)
 
 3805     keyinfo= 
table->key_info;
 
 3807     for (; keyinfo < keyend; keyinfo++)
 
 3809       keypart= keyinfo->key_part;
 
 3811       for (; keypart < keypartend; keypart++)
 
 3813         if (!keypart->fieldnr)
 
 3815         Field *field= 
table->field[keypart->fieldnr-1];
 
 3816         if (field->type() == MYSQL_TYPE_BLOB)
 
 3818           if (check_opt->sql_flags & TT_FOR_UPGRADE)
 
 3819             check_opt->flags= T_MEDIUM;
 
 3820           return HA_ADMIN_NEEDS_CHECK;
 
 3825   if (
table->s->frm_version != FRM_VER_TRUE_VARCHAR)
 
 3826     return HA_ADMIN_NEEDS_ALTER;
 
 3831   return check_for_upgrade(check_opt);
 
 3835 int handler::check_old_types()
 
 3839   for (field= 
table->field; (*field); field++)
 
 3841     if (
table->s->mysql_version == 0) 
 
 3844       if ((*field)->type() == MYSQL_TYPE_NEWDECIMAL) 
 
 3846         return HA_ADMIN_NEEDS_ALTER;
 
 3848       if ((*field)->type() == MYSQL_TYPE_VAR_STRING)
 
 3850         return HA_ADMIN_NEEDS_ALTER;
 
 3853     if ((*field)->type() == MYSQL_TYPE_YEAR && (*field)->field_length == 2)
 
 3854       return HA_ADMIN_NEEDS_ALTER; 
 
 3862   char path[FN_REFLEN];
 
 3865   DBUG_ENTER(
"update_frm_version");
 
 3873   if (table->s->mysql_version == MYSQL_VERSION_ID)
 
 3876   strxmov(path, table->s->normalized_path.str, reg_ext, NullS);
 
 3879                              path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
 
 3883     int4store(version, MYSQL_VERSION_ID);
 
 3888     table->s->mysql_version= MYSQL_VERSION_ID;
 
 3893   DBUG_RETURN(result);
 
 3904   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 3905               m_lock_type != F_UNLCK);
 
 3906   DBUG_ENTER(
"handler::get_dup_key");
 
 3907   table->file->errkey  = (uint) -1;
 
 3908   if (error == HA_ERR_FOUND_DUPP_KEY ||
 
 3909       error == HA_ERR_FOUND_DUPP_UNIQUE || error == HA_ERR_NULL_IN_SPATIAL ||
 
 3910       error == HA_ERR_DROP_INDEX_FK)
 
 3911     table->file->info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
 
 3912   DBUG_RETURN(table->file->errkey);
 
 3935   int enoent_or_zero= ENOENT;                   
 
 3936   char buff[FN_REFLEN];
 
 3937   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 3939   for (
const char **ext=
bas_ext(); *ext ; ext++)
 
 3941     fn_format(buff, name, 
"", *ext, MY_UNPACK_FILENAME|MY_APPEND_EXT);
 
 3944       if (my_errno != ENOENT)
 
 3952         saved_error= my_errno;
 
 3957     error= enoent_or_zero;
 
 3959   return saved_error ? saved_error : error;
 
 3966   const char **ext, **start_ext;
 
 3968   for (ext= start_ext; *ext ; ext++)
 
 3970     if (rename_file_ext(from, to, *ext))
 
 3972       if ((error=my_errno) != ENOENT)
 
 3980     for (; ext >= start_ext; ext--)
 
 3981       rename_file_ext(to, from, *ext);
 
 3987 void handler::drop_table(
const char *name)
 
 4012   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4013               m_lock_type != F_UNLCK);
 
 4015   if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
 
 4016       (check_opt->sql_flags & TT_FOR_UPGRADE))
 
 4019   if (table->s->mysql_version < MYSQL_VERSION_ID)
 
 4021     if ((error= check_old_types()))
 
 4023     error= ha_check_for_upgrade(check_opt);
 
 4024     if (error && (error != HA_ADMIN_NEEDS_CHECK))
 
 4026     if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
 
 4029   if ((error= check(thd, check_opt)))
 
 4032   if (table->file != 
this)
 
 4034   return update_frm_version(table);
 
 4044 handler::mark_trx_read_write()
 
 4046   Ha_trx_info *ha_info= &ha_thd()->ha_data[ht->slot].ha_info[0];
 
 4055   if (ha_info->is_started())
 
 4057     DBUG_ASSERT(has_transactions());
 
 4062     if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE)
 
 4063       ha_info->set_trx_read_write();
 
 4077   mark_trx_read_write();
 
 4079   result= repair(thd, check_opt);
 
 4080   DBUG_ASSERT(result == HA_ADMIN_NOT_IMPLEMENTED ||
 
 4083   if (result == HA_ADMIN_OK)
 
 4084     result= update_frm_version(table);
 
 4099   DBUG_ENTER(
"handler::ha_start_bulk_insert");
 
 4100   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4101               m_lock_type == F_WRLCK);
 
 4102   estimation_rows_to_insert= rows;
 
 4103   start_bulk_insert(rows);
 
 4118   DBUG_ENTER(
"handler::ha_end_bulk_insert");
 
 4119   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4120               m_lock_type == F_WRLCK);
 
 4121   estimation_rows_to_insert= 0;
 
 4122   DBUG_RETURN(end_bulk_insert());
 
 4134                             uint *dup_key_found)
 
 4136   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4137               m_lock_type == F_WRLCK);
 
 4138   mark_trx_read_write();
 
 4153   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4154               m_lock_type == F_WRLCK);
 
 4155   mark_trx_read_write();
 
 4170   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4171               m_lock_type == F_WRLCK);
 
 4172   mark_trx_read_write();
 
 4187   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4188               m_lock_type == F_WRLCK);
 
 4189   mark_trx_read_write();
 
 4204   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4205               m_lock_type == F_WRLCK);
 
 4206   mark_trx_read_write();
 
 4208   return optimize(thd, check_opt);
 
 4221   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4222               m_lock_type != F_UNLCK);
 
 4223   mark_trx_read_write();
 
 4225   return analyze(thd, check_opt);
 
 4238   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4239               m_lock_type == F_UNLCK);
 
 4240   mark_trx_read_write();
 
 4242   return check_and_repair(thd);
 
 4255   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4256               m_lock_type != F_UNLCK);
 
 4257   mark_trx_read_write();
 
 4259   return disable_indexes(mode);
 
 4272   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4273               m_lock_type != F_UNLCK);
 
 4274   mark_trx_read_write();
 
 4276   return enable_indexes(mode);
 
 4289   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4290               m_lock_type == F_WRLCK);
 
 4291   mark_trx_read_write();
 
 4293   return discard_or_import_tablespace(discard);
 
 4300   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4301               m_lock_type != F_UNLCK);
 
 4302   mark_trx_read_write();
 
 4318    DBUG_ASSERT(ha_thd()->mdl_context.is_lock_owner(MDL_key::TABLE,
 
 4320                                                    table->s->table_name.str,
 
 4333 enum_alter_inplace_result
 
 4337   DBUG_ENTER(
"check_if_supported_alter");
 
 4343     Alter_inplace_info::ALTER_COLUMN_NAME |
 
 4344     Alter_inplace_info::ALTER_COLUMN_DEFAULT |
 
 4345     Alter_inplace_info::CHANGE_CREATE_OPTION |
 
 4346     Alter_inplace_info::ALTER_RENAME;
 
 4349   if (ha_alter_info->
handler_flags & ~inplace_offline_operations)
 
 4350     DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 
 4361   if (create_info->used_fields & (HA_CREATE_USED_CHARSET |
 
 4362                                   HA_CREATE_USED_DEFAULT_CHARSET |
 
 4363                                   HA_CREATE_USED_PACK_KEYS |
 
 4364                                   HA_CREATE_USED_MAX_ROWS) ||
 
 4365       (table->s->row_type != create_info->
row_type))
 
 4366     DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 
 4370     IS_EQUAL_PACK_LENGTH : IS_EQUAL_YES;
 
 4372       == COMPATIBLE_DATA_YES)
 
 4373     DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
 
 4375   DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
 
 4391                                                   const char *try_instead)
 
 4394     my_error(ER_ALTER_OPERATION_NOT_SUPPORTED, MYF(0),
 
 4395              not_supported, try_instead);
 
 4397     my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
 
 4411   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 4412   mark_trx_read_write();
 
 4427   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 4428   mark_trx_read_write();
 
 4443   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 4444   mark_trx_read_write();
 
 4446   return drop_table(name);
 
 4459   DBUG_ASSERT(m_lock_type == F_UNLCK);
 
 4460   mark_trx_read_write();
 
 4462   return create(name, form, info);
 
 4481   DBUG_ASSERT(m_lock_type == F_UNLCK ||
 
 4482               (!old_name && strcmp(name, table_share->path.str)));
 
 4483   mark_trx_read_write();
 
 4485   return create_handler_files(name, old_name, action_flag, info);
 
 4498                      ulonglong * 
const copied,
 
 4499                      ulonglong * 
const deleted,
 
 4500                      const uchar *pack_frm_data,
 
 4501                      size_t pack_frm_len)
 
 4507   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 4508               m_lock_type != F_UNLCK);
 
 4509   mark_trx_read_write();
 
 4511   return change_partitions(create_info, path, copied, deleted,
 
 4512                            pack_frm_data, pack_frm_len);
 
 4525   DBUG_ASSERT(!table->db_stat);
 
 4527   mark_trx_read_write();
 
 4529   return drop_partitions(path);
 
 4542   DBUG_ASSERT(!table->db_stat);
 
 4543   mark_trx_read_write();
 
 4545   return rename_partitions(path);
 
 4560   DBUG_ENTER(
"ha_enable_transaction");
 
 4561   DBUG_PRINT(
"enter", (
"on: %d", (
int) on));
 
 4563   if ((thd->transaction.flags.enabled= on))
 
 4572       error= trans_commit_implicit(thd);
 
 4580   DBUG_ENTER(
"index_next_same");
 
 4583     my_ptrdiff_t ptrdiff= buf - table->record[0];
 
 4584     uchar *UNINIT_VAR(save_record_0);
 
 4585     KEY *UNINIT_VAR(key_info);
 
 4599       save_record_0= table->record[0];
 
 4600       table->record[0]= 
buf;
 
 4601       key_info= table->key_info + active_index;
 
 4602       key_part= key_info->key_part;
 
 4603       key_part_end= key_part + key_info->user_defined_key_parts;
 
 4604       for (; key_part < key_part_end; key_part++)
 
 4606         DBUG_ASSERT(key_part->field);
 
 4607         key_part->field->move_field_offset(ptrdiff);
 
 4611     if (key_cmp_if_same(table, key, active_index, keylen))
 
 4613       table->status=STATUS_NOT_FOUND;
 
 4614       error=HA_ERR_END_OF_FILE;
 
 4620       table->record[0]= save_record_0;
 
 4621       for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
 
 4622         key_part->field->move_field_offset(-ptrdiff);
 
 4632   info(HA_STATUS_CONST | HA_STATUS_TIME | HA_STATUS_VARIABLE |
 
 4634   stat_info->records=              
stats.records;
 
 4635   stat_info->mean_rec_length=      
stats.mean_rec_length;
 
 4636   stat_info->data_file_length=     
stats.data_file_length;
 
 4637   stat_info->max_data_file_length= 
stats.max_data_file_length;
 
 4638   stat_info->index_file_length=    
stats.index_file_length;
 
 4639   stat_info->delete_length=        
stats.delete_length;
 
 4640   stat_info->create_time=          
stats.create_time;
 
 4641   stat_info->update_time=          
stats.update_time;
 
 4642   stat_info->check_time=           
stats.check_time;
 
 4643   stat_info->check_sum=            0;
 
 4644   if (table_flags() & (ulong) HA_HAS_CHECKSUM)
 
 4645     stat_info->check_sum= checksum();
 
 4665                     bool update_create_info,
 
 4670   char name_buff[FN_REFLEN];
 
 4673   bool saved_abort_on_warning;
 
 4674   DBUG_ENTER(
"ha_create_table");
 
 4675 #ifdef HAVE_PSI_TABLE_INTERFACE 
 4676   my_bool temp_table= (my_bool)is_temp_table ||
 
 4678                (create_info->options & HA_LEX_CREATE_TMP_TABLE ? TRUE : FALSE);
 
 4681   init_tmp_table_share(thd, &share, db, 0, table_name, path);
 
 4682   if (open_table_def(thd, &share, 0))
 
 4685 #ifdef HAVE_PSI_TABLE_INTERFACE 
 4686   share.
m_psi= PSI_TABLE_CALL(get_table_share)(temp_table, &share);
 
 4689   if (open_table_from_share(thd, &share, 
"", 0, (uint) READ_ALL, 0, &table,
 
 4693   if (update_create_info)
 
 4694     update_create_info_from_table(create_info, &table);
 
 4698   saved_abort_on_warning = thd->abort_on_warning; 
 
 4699   thd->abort_on_warning = 
false;
 
 4700   error= table.file->
ha_create(name, &table, create_info);
 
 4701   thd->abort_on_warning = saved_abort_on_warning;
 
 4705 #ifdef HAVE_PSI_TABLE_INTERFACE 
 4707       (temp_table, db, strlen(db), 
table_name, strlen(table_name));
 
 4710   (void) closefrm(&table, 0);
 
 4712   free_table_share(&share);
 
 4713   DBUG_RETURN(error != 0);
 
 4734   char path[FN_REFLEN + 1];
 
 4738   DBUG_ENTER(
"ha_create_table_from_engine");
 
 4739   DBUG_PRINT(
"enter", (
"name '%s'.'%s'", db, name));
 
 4741   memset(&create_info, 0, 
sizeof(create_info));
 
 4742   if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
 
 4753   build_table_filename(path, 
sizeof(path) - 1, db, name, 
"", 0);
 
 4755   error= writefrm(path, frmblob, frmlen);
 
 4760   init_tmp_table_share(thd, &share, db, 0, name, path);
 
 4761   if (open_table_def(thd, &share, 0))
 
 4766 #ifdef HAVE_PSI_TABLE_INTERFACE 
 4774   if (open_table_from_share(thd, &share, 
"" ,0, 0, 0, &table, FALSE))
 
 4776     free_table_share(&share);
 
 4780   update_create_info_from_table(&create_info, &table);
 
 4781   create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
 
 4784   error=table.file->
ha_create(path, &table, &create_info);
 
 4785   (void) closefrm(&table, 1);
 
 4787   DBUG_RETURN(error != 0);
 
 4806   uchar *frmblob= NULL;
 
 4808   DBUG_ENTER(
"ha_check_if_table_exists");
 
 4810   *exists= ! ha_discover(thd, db, name, &frmblob, &frmlen);
 
 4845   DBUG_ENTER(
"ha_check_if_supported_system_table");
 
 4847   bool is_system_database= 
false;
 
 4852   DBUG_ASSERT(known_system_databases != NULL);
 
 4853   names= known_system_databases;
 
 4854   while (names && *names)
 
 4856     if (strcmp(*names, db) == 0)
 
 4859       check_params.db= *names;
 
 4860       is_system_database= 
true;
 
 4865   if (!is_system_database)
 
 4869   systab= mysqld_system_tables;
 
 4870   check_params.is_sql_layer_system_table= 
false;
 
 4871   while (systab && systab->db)
 
 4873     if (systab->db == check_params.db &&
 
 4874         strcmp(systab->tablename, table_name) == 0)
 
 4876       check_params.is_sql_layer_system_table= 
true;
 
 4883   check_params.status= check_params.is_sql_layer_system_table ?
 
 4884     st_sys_tbl_chk_params::KNOWN_SYSTEM_TABLE :
 
 4885     st_sys_tbl_chk_params::NOT_KNOWN_SYSTEM_TABLE;
 
 4886   check_params.db_type= hton->db_type;
 
 4888   plugin_foreach(NULL, check_engine_system_table_handlerton,
 
 4889                  MYSQL_STORAGE_ENGINE_PLUGIN, &check_params);
 
 4892   if (check_params.status == st_sys_tbl_chk_params::KNOWN_SYSTEM_TABLE)
 
 4920 static my_bool check_engine_system_table_handlerton(THD *unused,
 
 4928   if (check_params->status == st_sys_tbl_chk_params::KNOWN_SYSTEM_TABLE)
 
 4934     if (hton->db_type == check_params->db_type)
 
 4938                                        check_params->table_name,
 
 4939                                        check_params->is_sql_layer_system_table))
 
 4940         check_params->status= st_sys_tbl_chk_params::SUPPORTED_SYSTEM_TABLE;
 
 4957                                       check_params->table_name,
 
 4958                                       check_params->is_sql_layer_system_table))
 
 4964     if (hton->db_type == check_params->db_type)
 
 4966       check_params->status= st_sys_tbl_chk_params::SUPPORTED_SYSTEM_TABLE;
 
 4970       check_params->status= st_sys_tbl_chk_params::KNOWN_SYSTEM_TABLE;
 
 4983 const char** ha_known_system_databases(
void)
 
 4985   list<const char*> found_databases;
 
 4986   const char **databases, **database;
 
 4989   found_databases.push_back((
char*) mysqld_system_database);
 
 4992   plugin_foreach(NULL, system_databases_handlerton,
 
 4993                  MYSQL_STORAGE_ENGINE_PLUGIN, &found_databases);
 
 4995   databases= (
const char **) my_once_alloc(
sizeof(
char *)*
 
 4996                                      (found_databases.size()+1),
 
 4997                                      MYF(MY_WME | MY_FAE));
 
 4998   DBUG_ASSERT(databases != NULL);
 
 5000   list<const char*>::iterator it;
 
 5001   database= databases;
 
 5002   for (it= found_databases.begin(); it != found_databases.end(); it++)
 
 5015 static my_bool system_databases_handlerton(THD *unused, 
plugin_ref plugin,
 
 5018   list<const char*> *found_databases= (list<const char*> *) arg;
 
 5026       found_databases->push_back(db);
 
 5032 void st_ha_check_opt::init()
 
 5034   flags= sql_flags= 0;
 
 5053   DBUG_ENTER(
"ha_init_key_cache");
 
 5055   if (!key_cache->key_cache_inited)
 
 5058     size_t tmp_buff_size= (size_t) key_cache->param_buff_size;
 
 5059     uint tmp_block_size= (uint) key_cache->param_block_size;
 
 5060     uint division_limit= key_cache->param_division_limit;
 
 5061     uint age_threshold=  key_cache->param_age_threshold;
 
 5063     DBUG_RETURN(!init_key_cache(key_cache,
 
 5066                                 division_limit, age_threshold));
 
 5077   DBUG_ENTER(
"ha_resize_key_cache");
 
 5079   if (key_cache->key_cache_inited)
 
 5082     size_t tmp_buff_size= (size_t) key_cache->param_buff_size;
 
 5083     long tmp_block_size= (
long) key_cache->param_block_size;
 
 5084     uint division_limit= key_cache->param_division_limit;
 
 5085     uint age_threshold=  key_cache->param_age_threshold;
 
 5087     DBUG_RETURN(!resize_key_cache(key_cache, tmp_block_size,
 
 5089                                   division_limit, age_threshold));
 
 5100   if (key_cache->key_cache_inited)
 
 5103     uint division_limit= key_cache->param_division_limit;
 
 5104     uint age_threshold=  key_cache->param_age_threshold;
 
 5106     change_key_cache_param(key_cache, division_limit, age_threshold);
 
 5117   mi_change_key_cache(old_key_cache, new_key_cache);
 
 5140 static my_bool discover_handlerton(THD *thd, 
plugin_ref plugin,
 
 5145   if (hton->state == SHOW_OPTION_YES && hton->discover &&
 
 5146       (!(hton->discover(hton, thd, vargs->db, vargs->name, 
 
 5154 int ha_discover(THD *thd, 
const char *db, 
const char *name,
 
 5155                 uchar **frmblob, 
size_t *frmlen)
 
 5158   DBUG_ENTER(
"ha_discover");
 
 5159   DBUG_PRINT(
"enter", (
"db: %s, name: %s", db, name));
 
 5165   if (plugin_foreach(thd, discover_handlerton,
 
 5166                  MYSQL_STORAGE_ENGINE_PLUGIN, &args))
 
 5170     status_var_increment(thd->status_var.ha_discover_count);
 
 5189 static my_bool find_files_handlerton(THD *thd, 
plugin_ref plugin,
 
 5196   if (hton->state == SHOW_OPTION_YES && hton->find_files)
 
 5197       if (hton->find_files(hton, thd, vargs->db, vargs->path, vargs->wild, 
 
 5198                           vargs->dir, vargs->files))
 
 5205 ha_find_files(THD *thd,
const char *db,
const char *path,
 
 5209   DBUG_ENTER(
"ha_find_files");
 
 5210   DBUG_PRINT(
"enter", (
"db: '%s'  path: '%s'  wild: '%s'  dir: %d", 
 
 5211                        db, path, wild ? wild : 
"NULL", dir));
 
 5214   plugin_foreach(thd, find_files_handlerton,
 
 5215                  MYSQL_STORAGE_ENGINE_PLUGIN, &args);
 
 5236 static my_bool table_exists_in_engine_handlerton(THD *thd, 
plugin_ref plugin,
 
 5242   int err= HA_ERR_NO_SUCH_TABLE;
 
 5244   if (hton->state == SHOW_OPTION_YES && hton->table_exists_in_engine)
 
 5245     err = hton->table_exists_in_engine(hton, thd, vargs->db, vargs->name);
 
 5248   if (vargs->err == HA_ERR_TABLE_EXIST)
 
 5254 int ha_table_exists_in_engine(THD* thd, 
const char* db, 
const char* name)
 
 5256   DBUG_ENTER(
"ha_table_exists_in_engine");
 
 5257   DBUG_PRINT(
"enter", (
"db: %s, name: %s", db, name));
 
 5259   plugin_foreach(thd, table_exists_in_engine_handlerton,
 
 5260                  MYSQL_STORAGE_ENGINE_PLUGIN, &args);
 
 5261   DBUG_PRINT(
"exit", (
"error: %d", args.err));
 
 5262   DBUG_RETURN(args.err);
 
 5275 static my_bool make_pushed_join_handlerton(THD *thd, 
plugin_ref plugin,
 
 5281   if (hton && hton->make_pushed_join)
 
 5283     const int error= hton->make_pushed_join(hton, thd, vargs->plan);
 
 5284     if (unlikely(error))
 
 5295   DBUG_ENTER(
"ha_make_pushed_joins");
 
 5297   plugin_foreach(thd, make_pushed_join_handlerton,
 
 5298                  MYSQL_STORAGE_ENGINE_PLUGIN, &args);
 
 5299   DBUG_PRINT(
"exit", (
"error: %d", args.err));
 
 5300   DBUG_RETURN(args.err);
 
 5309 #define MAX_HTON_LIST_ST 63 
 5318   enum_binlog_func fn;
 
 5325 static my_bool binlog_func_list(THD *thd, 
plugin_ref plugin, 
void *arg)
 
 5329   if (hton->state == SHOW_OPTION_YES && hton->binlog_func)
 
 5331     uint sz= hton_list->sz;
 
 5332     if (sz == MAX_HTON_LIST_ST-1)
 
 5337     hton_list->hton[sz]= hton;
 
 5338     hton_list->sz= sz+1;
 
 5343 static my_bool binlog_func_foreach(THD *thd, 
binlog_func_st *bfn)
 
 5349   plugin_foreach(thd, binlog_func_list,
 
 5350                  MYSQL_STORAGE_ENGINE_PLUGIN, &hton_list);
 
 5352   for (i= 0, sz= hton_list.sz; i < sz ; i++)
 
 5353     hton_list.hton[
i]->binlog_func(hton_list.hton[i], thd, bfn->fn, bfn->arg);
 
 5357 #ifdef HAVE_NDB_BINLOG 
 5359 int ha_reset_logs(THD *thd)
 
 5362   binlog_func_foreach(thd, &bfn);
 
 5366 void ha_reset_slave(THD* thd)
 
 5369   binlog_func_foreach(thd, &bfn);
 
 5372 void ha_binlog_wait(THD* thd)
 
 5375   binlog_func_foreach(thd, &bfn);
 
 5378 int ha_binlog_index_purge_file(THD *thd, 
const char *file)
 
 5381   binlog_func_foreach(thd, &bfn);
 
 5385 struct binlog_log_query_st
 
 5387   enum_binlog_command binlog_command;
 
 5394 static my_bool binlog_log_query_handlerton2(THD *thd,
 
 5398   struct binlog_log_query_st *b= (
struct binlog_log_query_st*)args;
 
 5399   if (hton->state == SHOW_OPTION_YES && hton->binlog_log_query)
 
 5400     hton->binlog_log_query(hton, thd,
 
 5409 static my_bool binlog_log_query_handlerton(THD *thd,
 
 5413   return binlog_log_query_handlerton2(thd, plugin_data(plugin, 
handlerton *), args);
 
 5416 void ha_binlog_log_query(THD *thd, 
handlerton *hton,
 
 5417                          enum_binlog_command binlog_command,
 
 5418                          const char *
query, uint query_length,
 
 5421   struct binlog_log_query_st b;
 
 5422   b.binlog_command= binlog_command;
 
 5424   b.query_length= query_length;
 
 5428     plugin_foreach(thd, binlog_log_query_handlerton,
 
 5429                    MYSQL_STORAGE_ENGINE_PLUGIN, &b);
 
 5431     binlog_log_query_handlerton2(thd, hton, &b);
 
 5435 int ha_binlog_end(THD* thd)
 
 5438   binlog_func_foreach(thd, &bfn);
 
 5466   uint keys_per_block= (
stats.block_size/2/
 
 5469   read_time=((double) (records + keys_per_block-1) /
 
 5470              (double) keys_per_block);
 
 5497   for (; kp != kp_end; kp++)
 
 5499     if (!kp->field->part_of_key.is_set(keyno))
 
 5542                                      void *seq_init_param, uint n_ranges_arg,
 
 5543                                      uint *bufsz, uint *
flags, 
 
 5548   ha_rows rows, total_rows= 0;
 
 5550   THD *thd= current_thd;
 
 5555   DBUG_EXECUTE_IF(
"bug13822652_2", thd->killed= THD::KILL_QUERY;);
 
 5557   seq_it= seq->init(seq_init_param, n_ranges, *flags);
 
 5558   while (!seq->next(seq_it, &range))
 
 5560     if (unlikely(thd->killed != 0))
 
 5561       return HA_POS_ERROR;
 
 5565     if (range.range_flag & GEOM_FLAG)
 
 5568       range.start_key.flag= (ha_rkey_function) (range.range_flag ^ GEOM_FLAG);
 
 5569       min_endp= &range.start_key;
 
 5574       min_endp= range.start_key.length? &range.start_key : NULL;
 
 5575       max_endp= range.end_key.length? &range.end_key : NULL;
 
 5597     int keyparts_used= 0;
 
 5598     if ((range.range_flag & UNIQUE_RANGE) &&                        
 
 5599         !(range.range_flag & NULL_RANGE))
 
 5601     else if ((range.range_flag & EQ_RANGE) &&                       
 
 5602              (range.range_flag & USE_INDEX_STATISTICS) &&           
 
 5603              (keyparts_used= my_count_bits(range.start_key.keypart_map)) &&
 
 5604              table->key_info[keyno].
rec_per_key[keyparts_used-1] && 
 
 5605              !(range.range_flag & NULL_RANGE))
 
 5606       rows= table->key_info[keyno].
rec_per_key[keyparts_used-1];
 
 5609       DBUG_EXECUTE_IF(
"crash_records_in_range", DBUG_SUICIDE(););
 
 5610       DBUG_ASSERT(min_endp || max_endp);
 
 5611       if (HA_POS_ERROR == (rows= this->records_in_range(keyno, min_endp, 
 
 5615         total_rows= HA_POS_ERROR;
 
 5622   if (total_rows != HA_POS_ERROR)
 
 5625     *
flags|= HA_MRR_USE_DEFAULT_IMPL;
 
 5626     *
flags|= HA_MRR_SUPPORT_SORTED;
 
 5628     DBUG_ASSERT(cost->is_zero());
 
 5629     if ((*
flags & HA_MRR_INDEX_ONLY) && total_rows > 2)
 
 5630       cost->add_io(index_only_read_time(keyno, total_rows) *
 
 5633       cost->add_io(read_time(keyno, n_ranges, total_rows) *
 
 5676                                        uint *bufsz, uint *
flags, 
 
 5681   *flags|= HA_MRR_USE_DEFAULT_IMPL;
 
 5682   *flags|= HA_MRR_SUPPORT_SORTED;
 
 5687   if (*flags & HA_MRR_INDEX_ONLY)
 
 5742   DBUG_ENTER(
"handler::multi_range_read_init");
 
 5743   mrr_iter= seq_funcs->init(seq_init_param, n_ranges, mode);
 
 5744   mrr_funcs= *seq_funcs;
 
 5745   mrr_is_output_sorted= 
test(mode & HA_MRR_SORTED);
 
 5746   mrr_have_range= FALSE;
 
 5766   int result= HA_ERR_END_OF_FILE;
 
 5768   DBUG_ENTER(
"handler::multi_range_read_next");
 
 5770   if (!mrr_have_range)
 
 5772     mrr_have_range= TRUE;
 
 5779     if (mrr_cur_range.range_flag != (UNIQUE_RANGE | EQ_RANGE))
 
 5783       if (result != HA_ERR_END_OF_FILE)
 
 5794     while (!(range_res= mrr_funcs.next(mrr_iter, &mrr_cur_range)))
 
 5798                                  &mrr_cur_range.start_key : 0,
 
 5799                                mrr_cur_range.end_key.keypart_map ?
 
 5800                                  &mrr_cur_range.end_key : 0,
 
 5801                                test(mrr_cur_range.range_flag & EQ_RANGE),
 
 5802                                mrr_is_output_sorted);
 
 5803       if (result != HA_ERR_END_OF_FILE)
 
 5807   while ((result == HA_ERR_END_OF_FILE) && !range_res);
 
 5809   *range_info= mrr_cur_range.ptr;
 
 5810   DBUG_PRINT(
"exit",(
"handler::multi_range_read_next result %d", result));
 
 5811   DBUG_RETURN(result);
 
 5857                            void *seq_init_param, uint n_ranges, uint 
mode,
 
 5862   DBUG_ENTER(
"DsMrr_impl::dsmrr_init");
 
 5863   THD *thd= h_arg->table->in_use;     
 
 5871       mode & (HA_MRR_USE_DEFAULT_IMPL | HA_MRR_SORTED)) 
 
 5873     use_default_impl= TRUE;
 
 5874     retval= h->handler::multi_range_read_init(seq_funcs, seq_init_param,
 
 5875                                               n_ranges, mode, buf);
 
 5876     DBUG_RETURN(retval);
 
 5891   DBUG_ASSERT(!h->pushed_idx_cond ||
 
 5892               h->pushed_idx_cond_keyno == h->active_index ||
 
 5893               h->pushed_idx_cond_keyno != table->s->primary_key ||
 
 5894               (h2 && h->pushed_idx_cond_keyno == h2->active_index));
 
 5896   rowids_buf= buf->buffer;
 
 5898   is_mrr_assoc= !
test(mode & HA_MRR_NO_ASSOCIATION);
 
 5901     status_var_increment(table->in_use->status_var.ha_multi_range_read_init_count);
 
 5903   rowids_buf_end= buf->buffer_end;
 
 5904   elem_size= h->
ref_length + (int)is_mrr_assoc * 
sizeof(
void*);
 
 5905   rowids_buf_last= rowids_buf + 
 
 5906                       ((rowids_buf_end - rowids_buf)/ elem_size)*
 
 5908   rowids_buf_end= rowids_buf_last;
 
 5928     if (!(new_h2= h->clone(h->table->s->normalized_path.str, thd->mem_root)))
 
 5937   if (h2->active_index == MAX_KEY)
 
 5939     DBUG_ASSERT(h->active_index != MAX_KEY);
 
 5940     const uint mrr_keyno= h->active_index;
 
 5945     if ((retval= h2->extra(HA_EXTRA_KEYREAD)))
 
 5952     if (mrr_keyno == h->pushed_idx_cond_keyno)
 
 5975     DBUG_ASSERT(h->inited == handler::RND);
 
 5976     DBUG_ASSERT(h->active_index == MAX_KEY || 
 
 5977                 h->active_index == table->s->primary_key);
 
 5984   if (h->inited == handler::INDEX)
 
 6002   DBUG_ASSERT(h->inited != handler::INDEX);
 
 6003   DBUG_ASSERT(h->active_index == MAX_KEY || 
 
 6004               h->active_index == table->s->primary_key);
 
 6005   DBUG_ASSERT(h2->inited == handler::INDEX);
 
 6006   DBUG_ASSERT(h2->active_index != MAX_KEY);
 
 6007   DBUG_ASSERT(h->m_lock_type == h2->m_lock_type);
 
 6009   if ((retval= h2->handler::multi_range_read_init(seq_funcs, seq_init_param, 
 
 6010                                                   n_ranges, mode, buf)))
 
 6021     buf->end_of_used_area= rowids_buf_last;
 
 6027   if ((h->inited != handler::RND) && 
 
 6028       ((h->inited==handler::INDEX? h->
ha_index_end(): FALSE) || 
 
 6035   use_default_impl= FALSE;
 
 6036   h->mrr_funcs= *seq_funcs;
 
 6040   h2->ha_index_or_rnd_end();
 
 6045   DBUG_ASSERT(retval != 0);
 
 6046   DBUG_RETURN(retval);
 
 6050 void DsMrr_impl::dsmrr_close()
 
 6052   DBUG_ENTER(
"DsMrr_impl::dsmrr_close");
 
 6055   if (h2 && h2->active_index != MAX_KEY)
 
 6057     h2->ha_index_or_rnd_end();
 
 6060   use_default_impl= 
true;
 
 6067   DBUG_ENTER(
"DsMrr_impl::reset");
 
 6083 static int rowid_cmp(
void *h, uchar *a, uchar *b)
 
 6085   return ((
handler*)h)->cmp_ref(a, b);
 
 6110   DBUG_ENTER(
"DsMrr_impl::dsmrr_fill_buffer");
 
 6111   DBUG_ASSERT(rowids_buf < rowids_buf_end);
 
 6113   rowids_buf_cur= rowids_buf;
 
 6114   while ((rowids_buf_cur < rowids_buf_end) && 
 
 6115          !(res= h2->handler::multi_range_read_next(&range_info)))
 
 6118     if (h2->mrr_funcs.skip_index_tuple &&
 
 6119         h2->mrr_funcs.skip_index_tuple(h2->mrr_iter, curr_range->ptr))
 
 6123     h2->position(table->record[0]);
 
 6124     memcpy(rowids_buf_cur, h2->ref, h2->
ref_length);
 
 6129       memcpy(rowids_buf_cur, &range_info, 
sizeof(
void*));
 
 6130       rowids_buf_cur += 
sizeof(
void*);
 
 6134   if (res && res != HA_ERR_END_OF_FILE)
 
 6136   dsmrr_eof= 
test(res == HA_ERR_END_OF_FILE);
 
 6139   uint elem_size= h->ref_length + (int)is_mrr_assoc * 
sizeof(
void*);
 
 6140   uint n_rowids= (rowids_buf_cur - rowids_buf) / elem_size;
 
 6142   my_qsort2(rowids_buf, n_rowids, elem_size, (qsort2_cmp)rowid_cmp,
 
 6144   rowids_buf_last= rowids_buf_cur;
 
 6145   rowids_buf_cur=  rowids_buf;
 
 6154 int DsMrr_impl::dsmrr_next(
char **range_info)
 
 6157   uchar *cur_range_info= 0;
 
 6160   if (use_default_impl)
 
 6161     return h->handler::multi_range_read_next(range_info);
 
 6165     if (rowids_buf_cur == rowids_buf_last)
 
 6169         res= HA_ERR_END_OF_FILE;
 
 6179     if (rowids_buf_cur == rowids_buf_last)
 
 6181       res= HA_ERR_END_OF_FILE;
 
 6184     rowid= rowids_buf_cur;
 
 6187       memcpy(&cur_range_info, rowids_buf_cur + h->ref_length, 
sizeof(uchar*));
 
 6189     rowids_buf_cur += h->ref_length + 
sizeof(
void*) * 
test(is_mrr_assoc);
 
 6190     if (h2->mrr_funcs.skip_record &&
 
 6191         h2->mrr_funcs.skip_record(h2->mrr_iter, (
char *) cur_range_info, rowid))
 
 6193     res= h->rnd_pos(table->record[0], rowid);
 
 6199     memcpy(range_info, rowid + h->ref_length, 
sizeof(
void*));
 
 6209 ha_rows DsMrr_impl::dsmrr_info(uint keyno, uint n_ranges, uint rows,
 
 6213   uint def_flags= *
flags;
 
 6214   uint def_bufsz= *bufsz;
 
 6217   res= h->handler::multi_range_read_info(keyno, n_ranges, rows, &def_bufsz,
 
 6221   if ((*flags & HA_MRR_USE_DEFAULT_IMPL) || 
 
 6222       choose_mrr_impl(keyno, rows, flags, bufsz, cost))
 
 6225     DBUG_PRINT(
"info", (
"Default MRR implementation choosen"));
 
 6228     DBUG_ASSERT(*flags & HA_MRR_USE_DEFAULT_IMPL);
 
 6233     DBUG_PRINT(
"info", (
"DS-MRR implementation choosen"));
 
 6243 ha_rows DsMrr_impl::dsmrr_info_const(uint keyno, 
RANGE_SEQ_IF *seq,
 
 6244                                  void *seq_init_param, uint n_ranges, 
 
 6248   uint def_flags= *
flags;
 
 6249   uint def_bufsz= *bufsz;
 
 6251   rows= h->handler::multi_range_read_info_const(keyno, seq, seq_init_param,
 
 6252                                                 n_ranges, &def_bufsz, 
 
 6254   if (rows == HA_POS_ERROR)
 
 6266   if ((*flags & HA_MRR_USE_DEFAULT_IMPL) ||
 
 6267       choose_mrr_impl(keyno, rows, flags, bufsz, cost))
 
 6269     DBUG_PRINT(
"info", (
"Default MRR implementation choosen"));
 
 6272     DBUG_ASSERT(*flags & HA_MRR_USE_DEFAULT_IMPL);
 
 6277     DBUG_PRINT(
"info", (
"DS-MRR implementation choosen"));
 
 6306 bool DsMrr_impl::choose_mrr_impl(uint keyno, ha_rows rows, uint *flags,
 
 6310   THD *thd= current_thd;
 
 6312       *flags & (HA_MRR_INDEX_ONLY | HA_MRR_SORTED) || 
 
 6313       (keyno == table->s->primary_key && h->primary_key_is_clustered()) ||
 
 6339     if (min_file_size == -1)
 
 6342       min_file_size= 100 * 1024 * 1024;    
 
 6345     if (table->file->stats.data_file_length < 
 
 6346         static_cast<ulonglong>(min_file_size) ||
 
 6352   if (get_disk_sweep_mrr_cost(keyno, rows, *flags, bufsz, &dsmrr_cost))
 
 6370     *flags &= ~HA_MRR_USE_DEFAULT_IMPL;  
 
 6371     *flags &= ~HA_MRR_SUPPORT_SORTED;    
 
 6384 static void get_sort_and_sweep_cost(
TABLE *table, ha_rows nrows, 
 
 6402 bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
 
 6406   ha_rows rows_in_last_step;
 
 6408   double index_read_cost;
 
 6410   const uint elem_size= h->ref_length + 
 
 6411                         sizeof(
void*) * (!
test(flags & HA_MRR_NO_ASSOCIATION));
 
 6412   const ha_rows max_buff_entries= *buffer_size / elem_size;
 
 6414   if (!max_buff_entries)
 
 6418   n_full_steps= (uint)floor(rows2double(rows) / max_buff_entries);
 
 6424   rows_in_last_step= rows % max_buff_entries;
 
 6430     get_sort_and_sweep_cost(table, max_buff_entries, cost);
 
 6443     const ha_rows keys_in_buffer=
 
 6444       max<ha_rows>(
static_cast<ha_rows
>(1.2 * rows_in_last_step), 100);
 
 6445     *buffer_size= min<ulong>(*buffer_size,
 
 6446                              static_cast<ulong
>(keys_in_buffer) * elem_size);
 
 6450   get_sort_and_sweep_cost(table, rows_in_last_step, &last_step_cost);
 
 6451   (*cost)+= last_step_cost;
 
 6461   index_read_cost= h->index_only_read_time(keynr, rows);
 
 6505     const double ROWID_COMPARE_SORT_COST = 0.01;
 
 6508     const double cpu_sort= nrows * log2(nrows) * ROWID_COMPARE_SORT_COST;
 
 6560   DBUG_ENTER(
"get_sweep_read_cost");
 
 6566       ceil(ulonglong2double(table->file->stats.data_file_length) / IO_SIZE);
 
 6570       n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
 
 6571     if (busy_blocks < 1.0)
 
 6574     DBUG_PRINT(
"info",(
"sweep: nblocks=%g, busy_blocks=%g", n_blocks,
 
 6580       cost->
add_io(busy_blocks * 
 
 6581                    (DISK_SEEK_BASE_COST +
 
 6582                     DISK_SEEK_PROP_COST * n_blocks / busy_blocks));
 
 6584   DBUG_PRINT(
"info",(
"returning cost=%g", cost->
total_cost()));
 
 6618   DBUG_ENTER(
"handler::read_range_first");
 
 6620   eq_range= eq_range_arg;
 
 6623   range_key_part= table->key_info[active_index].key_part;
 
 6630                               start_key->keypart_map,
 
 6633     DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND) 
 
 6634                 ? HA_ERR_END_OF_FILE
 
 6648     DBUG_RETURN(HA_ERR_END_OF_FILE);
 
 6669   DBUG_ENTER(
"handler::read_range_next");
 
 6676                                    end_range->length));
 
 6680     DBUG_RETURN(result);
 
 6693     DBUG_RETURN(HA_ERR_END_OF_FILE);
 
 6699                             enum_range_scan_direction direction)
 
 6703     save_end_range= *range;
 
 6704     end_range= &save_end_range;
 
 6705     range_key_part= table->key_info[active_index].key_part;
 
 6706     key_compare_result_on_equal= ((range->flag == HA_READ_BEFORE_KEY) ? 1 :
 
 6707                                   (range->flag == HA_READ_AFTER_KEY) ? -1 : 0);
 
 6712   range_scan_direction= direction;
 
 6734   if (!range || in_range_check_pushed_down)
 
 6736   cmp= key_cmp(range_key_part, range->key, range->length);
 
 6738     cmp= key_compare_result_on_equal;
 
 6763 int handler::compare_key_icp(
const key_range *range)
 const 
 6768   cmp= key_cmp(range_key_part, range->key, range->length);
 
 6770     cmp= key_compare_result_on_equal;
 
 6771   if (range_scan_direction == RANGE_SCAN_DESC)
 
 6777                                 key_part_map keypart_map,
 
 6778                                 enum ha_rkey_function find_flag)
 
 6781   error= index_init(index, 0);
 
 6785     error1= index_end();
 
 6787   return error ?  error : error1;
 
 6801 static my_bool exts_handlerton(THD *unused, 
plugin_ref plugin,
 
 6807   if (hton->state == SHOW_OPTION_YES && hton->create &&
 
 6808       (file= hton->create(hton, (
TABLE_SHARE*) 0, current_thd->mem_root)))
 
 6811     const char **ext, *old_ext;
 
 6813     for (ext= file->
bas_ext(); *ext; ext++)
 
 6815       while ((old_ext= it++))
 
 6817         if (!strcmp(old_ext, *ext))
 
 6821         found_exts->push_back((
char *) *ext);
 
 6833   known_extensions->name= 
"known_exts";
 
 6834   known_extensions->type_lengths= NULL;
 
 6837   const char **ext, *old_ext;
 
 6839   found_exts.push_back((
char*) TRG_EXT);
 
 6840   found_exts.push_back((
char*) TRN_EXT);
 
 6842   plugin_foreach(NULL, exts_handlerton,
 
 6843                  MYSQL_STORAGE_ENGINE_PLUGIN, &found_exts);
 
 6845   size_t arr_length= 
sizeof(
char *)* (found_exts.elements+1);
 
 6846   ext= (
const char **) sql_alloc(arr_length);
 
 6848   DBUG_ASSERT(NULL != ext);
 
 6849   known_extensions->count= found_exts.elements;
 
 6850   known_extensions->type_names= ext;
 
 6853   while ((old_ext= it++))
 
 6856   return known_extensions;
 
 6860 static bool stat_print(THD *thd, 
const char *
type, uint type_len,
 
 6861                        const char *file, uint file_len,
 
 6862                        const char *status, uint status_len)
 
 6865   protocol->prepare_for_resend();
 
 6866   protocol->
store(type, type_len, system_charset_info);
 
 6867   protocol->
store(file, file_len, system_charset_info);
 
 6868   protocol->
store(status, status_len, system_charset_info);
 
 6869   if (protocol->write())
 
 6875 static my_bool showstat_handlerton(THD *thd, 
plugin_ref plugin,
 
 6878   enum ha_stat_type stat= *(
enum ha_stat_type *) arg;
 
 6880   if (hton->state == SHOW_OPTION_YES && hton->show_status &&
 
 6881       hton->show_status(hton, thd, stat_print, stat))
 
 6886 bool ha_show_status(THD *thd, 
handlerton *db_type, 
enum ha_stat_type stat)
 
 6897                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
 6900   if (db_type == NULL)
 
 6902     result= plugin_foreach(thd, showstat_handlerton,
 
 6903                            MYSQL_STORAGE_ENGINE_PLUGIN, &stat);
 
 6907     if (db_type->state != SHOW_OPTION_YES)
 
 6909       const LEX_STRING *name=&hton2plugin[db_type->slot]->name;
 
 6910       result= stat_print(thd, name->str, name->length,
 
 6911                          "", 0, 
"DISABLED", 8) ? 1 : 0;
 
 6914       result= db_type->show_status &&
 
 6915               db_type->show_status(db_type, thd, stat_print, stat) ? 1 : 0;
 
 6936 static bool check_table_binlog_row_based(THD *thd, 
TABLE *table)
 
 6938   if (table->s->cached_row_logging_check == -1)
 
 6940     int const check(table->s->tmp_table == NO_TMP_TABLE &&
 
 6942                     binlog_filter->db_ok(table->s->db.str));
 
 6943     table->s->cached_row_logging_check= check;
 
 6946   DBUG_ASSERT(table->s->cached_row_logging_check == 0 ||
 
 6947               table->s->cached_row_logging_check == 1);
 
 6949   return (thd->is_current_stmt_binlog_format_row() &&
 
 6950           table->s->cached_row_logging_check &&
 
 6951           (thd->variables.option_bits & OPTION_BIN_LOG) &&
 
 6952           mysql_bin_log.is_open());
 
 6976 static int write_locked_table_maps(THD *thd)
 
 6978   DBUG_ENTER(
"write_locked_table_maps");
 
 6979   DBUG_PRINT(
"enter", (
"thd: 0x%lx  thd->lock: 0x%lx " 
 6980                        "thd->extra_lock: 0x%lx",
 
 6981                        (
long) thd, (
long) thd->lock, (
long) thd->extra_lock));
 
 6983   DBUG_PRINT(
"debug", (
"get_binlog_table_maps(): %d", thd->get_binlog_table_maps()));
 
 6985   if (thd->get_binlog_table_maps() == 0)
 
 6988     locks[0]= thd->extra_lock;
 
 6989     locks[1]= thd->lock;
 
 6990     for (uint i= 0 ; i < 
sizeof(locks)/
sizeof(*locks) ; ++
i )
 
 6996       bool need_binlog_rows_query= thd->variables.binlog_rows_query_log_events;
 
 6997       TABLE **
const end_ptr= lock->table + lock->table_count;
 
 6998       for (
TABLE **table_ptr= lock->table ; 
 
 6999            table_ptr != end_ptr ;
 
 7002         TABLE *
const table= *table_ptr;
 
 7003         DBUG_PRINT(
"info", (
"Checking table %s", table->s->table_name.str));
 
 7004         if (table->current_lock == F_WRLCK &&
 
 7005             check_table_binlog_row_based(thd, table))
 
 7020           bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
 
 7021                                 table->file->has_transactions();
 
 7022           int const error= thd->binlog_write_table_map(table, has_trans,
 
 7023                                                        need_binlog_rows_query);
 
 7026           if (need_binlog_rows_query)
 
 7027             need_binlog_rows_query= FALSE;
 
 7032           if (unlikely(error))
 
 7042 typedef bool Log_func(THD*, 
TABLE*, 
bool,
 
 7043                       const uchar*, 
const uchar*);
 
 7046                           const uchar *before_record,
 
 7047                           const uchar *after_record,
 
 7051   THD *
const thd= table->in_use;
 
 7053   if (check_table_binlog_row_based(thd, table))
 
 7055     DBUG_DUMP(
"read_set 10", (uchar*) table->read_set->bitmap,
 
 7056               (table->s->fields + 7) / 8);
 
 7063     if (likely(!(error= write_locked_table_maps(thd))))
 
 7073       bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
 
 7074                            table->file->has_transactions();
 
 7076         (*log_func)(thd, 
table, has_trans, before_record, after_record);
 
 7079   return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
 
 7085   DBUG_ENTER(
"handler::ha_external_lock");
 
 7093   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 7094               ((lock_type != F_UNLCK && m_lock_type == F_UNLCK) ||
 
 7095                lock_type == F_UNLCK));
 
 7097   DBUG_ASSERT(inited == NONE || table->open_by_handler);
 
 7099   if (MYSQL_HANDLER_RDLOCK_START_ENABLED() ||
 
 7100       MYSQL_HANDLER_WRLOCK_START_ENABLED() ||
 
 7101       MYSQL_HANDLER_UNLOCK_START_ENABLED())
 
 7103     if (lock_type == F_RDLCK)
 
 7105       MYSQL_HANDLER_RDLOCK_START(table_share->db.str,
 
 7106                                  table_share->table_name.str);
 
 7108     else if (lock_type == F_WRLCK)
 
 7110       MYSQL_HANDLER_WRLOCK_START(table_share->db.str,
 
 7111                                  table_share->table_name.str);
 
 7113     else if (lock_type == F_UNLCK)
 
 7115       MYSQL_HANDLER_UNLOCK_START(table_share->db.str,
 
 7116                                  table_share->table_name.str);
 
 7120   ha_statistic_increment(&SSV::ha_external_lock_count);
 
 7123     { error= external_lock(thd, lock_type); })
 
 7136     m_lock_type= lock_type;
 
 7137     cached_table_flags= table_flags();
 
 7140   if (MYSQL_HANDLER_RDLOCK_DONE_ENABLED() ||
 
 7141       MYSQL_HANDLER_WRLOCK_DONE_ENABLED() ||
 
 7142       MYSQL_HANDLER_UNLOCK_DONE_ENABLED())
 
 7144     if (lock_type == F_RDLCK)
 
 7146       MYSQL_HANDLER_RDLOCK_DONE(error);
 
 7148     else if (lock_type == F_WRLCK)
 
 7150       MYSQL_HANDLER_WRLOCK_DONE(error);
 
 7152     else if (lock_type == F_UNLCK)
 
 7154       MYSQL_HANDLER_UNLOCK_DONE(error);
 
 7168   DBUG_ENTER(
"handler::ha_reset");
 
 7170   DBUG_ASSERT((uchar*) table->def_read_set.bitmap +
 
 7171               table->s->column_bitmap_size ==
 
 7172               (uchar*) table->def_write_set.bitmap);
 
 7173   DBUG_ASSERT(bitmap_is_set_all(&table->s->all_set));
 
 7176   DBUG_ASSERT(inited == NONE);
 
 7178   free_io_cache(table);
 
 7180   table->default_column_bitmaps();
 
 7186   const int retval= reset();
 
 7187   DBUG_RETURN(retval);
 
 7191 int handler::ha_write_row(uchar *buf)
 
 7194   Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
 
 7195   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 7196               m_lock_type == F_WRLCK);
 
 7198   DBUG_ENTER(
"handler::ha_write_row");
 
 7199   DBUG_EXECUTE_IF(
"inject_error_ha_write_row",
 
 7200                   DBUG_RETURN(HA_ERR_INTERNAL_ERROR); );
 
 7202   MYSQL_INSERT_ROW_START(table_share->db.str, table_share->table_name.str);
 
 7203   mark_trx_read_write();
 
 7206     { error= write_row(buf); })
 
 7208   MYSQL_INSERT_ROW_DONE(error);
 
 7209   if (unlikely(error))
 
 7215   DEBUG_SYNC_C(
"ha_write_row_end");
 
 7220 int handler::ha_update_row(
const uchar *old_data, uchar *new_data)
 
 7223   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 7224               m_lock_type == F_WRLCK);
 
 7225   Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
 
 7231   DBUG_ASSERT(new_data == table->record[0]);
 
 7232   DBUG_ASSERT(old_data == table->record[1]);
 
 7234   MYSQL_UPDATE_ROW_START(table_share->db.str, table_share->table_name.str);
 
 7235   mark_trx_read_write();
 
 7238     { error= update_row(old_data, new_data);})
 
 7240   MYSQL_UPDATE_ROW_DONE(error);
 
 7241   if (unlikely(error))
 
 7243   if (unlikely(error= 
binlog_log_row(table, old_data, new_data, log_func)))
 
 7248 int handler::ha_delete_row(
const uchar *buf)
 
 7251   DBUG_ASSERT(table_share->tmp_table != NO_TMP_TABLE ||
 
 7252               m_lock_type == F_WRLCK);
 
 7253   Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
 
 7257   DBUG_ASSERT(buf == table->record[0] ||
 
 7258               buf == table->record[1]);
 
 7259   DBUG_EXECUTE_IF(
"inject_error_ha_delete_row",
 
 7260                   return HA_ERR_INTERNAL_ERROR; );
 
 7262   MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
 
 7263   mark_trx_read_write();
 
 7266     { error= delete_row(buf);})
 
 7268   MYSQL_DELETE_ROW_DONE(error);
 
 7269   if (unlikely(error))
 
 7286   table->use_all_columns();
 
 7303   DBUG_ENTER(
"handler::get_ha_share_ptr");
 
 7304   DBUG_ASSERT(ha_share && table_share);
 
 7307   if (table_share->tmp_table == NO_TMP_TABLE)
 
 7311   DBUG_RETURN(*ha_share);
 
 7326   DBUG_ENTER(
"handler::set_ha_share_ptr");
 
 7327   DBUG_ASSERT(ha_share);
 
 7329   if (table_share->tmp_table == NO_TMP_TABLE)
 
 7333   *ha_share= arg_ha_share;
 
 7344   DBUG_ASSERT(table_share);
 
 7345   if (table_share->tmp_table == NO_TMP_TABLE)
 
 7356   DBUG_ASSERT(table_share);
 
 7357   if (table_share->tmp_table == NO_TMP_TABLE)
 
 7368   DBUG_ENTER(
"signal_log_not_needed");
 
 7369   DBUG_PRINT(
"enter", (
"logfile '%s'", log_file));
 
 7373 #ifdef TRANS_LOG_MGM_EXAMPLE_CODE 
 7380 int example_of_iterator_using_for_logs_cleanup(
handlerton *hton)
 
 7387   if (!hton->create_iterator)
 
 7390   if ((*hton->create_iterator)(hton, HA_TRANSACTLOG_ITERATOR, &iterator) !=
 
 7396   while((*iterator.next)(&iterator, (
void*)&data) == 0)
 
 7398     printf(
"%s\n", data.filename.str);
 
 7399     if (data.status == HA_LOG_STATUS_FREE &&
 
 7401                           data.filename.str, MYF(MY_WME)))
 
 7406   (*iterator.destroy)(&iterator);
 
 7418 #define fl_dir FN_ROOTDIR 
 7426 enum log_status fl_get_log_status(
char *log)
 
 7430     return HA_LOG_STATUS_INUSE;
 
 7431   return HA_LOG_STATUS_NOSUCHLOG;
 
 7438   enum log_status *statuses;
 
 7445                           void *iterator_object)
 
 7447   struct fl_buff *buff= (
struct fl_buff *)iterator->buffer;
 
 7450   if (buff->current >= buff->entries)
 
 7452   data->filename= buff->names[buff->current];
 
 7453   data->status= buff->statuses[buff->current];
 
 7461   my_free(iterator->buffer);
 
 7468 enum handler_create_iterator_result
 
 7472   struct fl_buff *buff;
 
 7479   iterator->buffer= 0;
 
 7481   if (!(dirp = my_dir(fl_dir, MYF(0))))
 
 7483     return HA_ITERATOR_ERROR;
 
 7485   if ((ptr= (uchar*)my_malloc(ALIGN_SIZE(
sizeof(fl_buff)) +
 
 7487                                sizeof(
enum log_status) +
 
 7489                               (uint) dirp->number_off_files),
 
 7492     return HA_ITERATOR_ERROR;
 
 7494   buff= (
struct fl_buff *)ptr;
 
 7495   buff->entries= buff->current= 0;
 
 7496   ptr= ptr + (ALIGN_SIZE(
sizeof(fl_buff)));
 
 7498   ptr= ptr + ((ALIGN_SIZE(
sizeof(
LEX_STRING)) *
 
 7499                (uint) dirp->number_off_files));
 
 7500   buff->statuses= (
enum log_status *)(ptr);
 
 7501   name_ptr= (
char *)(ptr + (
sizeof(
enum log_status) *
 
 7502                             (uint) dirp->number_off_files));
 
 7503   for (i=0 ; i < (uint) dirp->number_off_files  ; i++)
 
 7506     file= dirp->dir_entry + 
i;
 
 7507     if ((file->name[0] == 
'.' &&
 
 7508          ((file->name[1] == 
'.' && file->name[2] == 
'\0') ||
 
 7509             file->name[1] == 
'\0')))
 
 7511     if ((st= fl_get_log_status(file->name)) == HA_LOG_STATUS_NOSUCHLOG)
 
 7513     name_ptr= strxnmov(buff->names[buff->entries].str= name_ptr,
 
 7514                        FN_REFLEN, fl_dir, file->name, NullS);
 
 7515     buff->names[buff->entries].length= (name_ptr -
 
 7516                                         buff->names[buff->entries].str);
 
 7517     buff->statuses[buff->entries]= st;
 
 7521   iterator->buffer= buff;
 
 7522   iterator->next= &fl_log_iterator_next;
 
 7523   iterator->destroy= &fl_log_iterator_destroy;
 
 7524   return HA_ITERATOR_OK;
 
 7529 enum handler_create_iterator_result
 
 7530 fl_create_iterator(
enum handler_iterator_type type,
 
 7534   case HA_TRANSACTLOG_ITERATOR:
 
 7535     return fl_log_iterator_buffer_init(iterator);
 
 7537     return HA_ITERATOR_UNSUPPORTED;