| 183 | */ |
| 184 | |
| 185 | enum Sql_cmd_truncate_table::truncate_result |
| 186 | Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref, |
| 187 | bool is_tmp_table) |
| 188 | { |
| 189 | int error= 0; |
| 190 | uint flags= 0; |
| 191 | TABLE *table; |
| 192 | DBUG_ENTER("Sql_cmd_truncate_table::handler_truncate"); |
| 193 | |
| 194 | /* |
| 195 | Can't recreate, the engine must mechanically delete all rows |
| 196 | in the table. Use open_and_lock_tables() to open a write cursor. |
| 197 | */ |
| 198 | |
| 199 | /* If it is a temporary table, no need to take locks. */ |
| 200 | if (!is_tmp_table) |
| 201 | { |
| 202 | /* We don't need to load triggers. */ |
| 203 | DBUG_ASSERT(table_ref->trg_event_map == 0); |
| 204 | /* |
| 205 | Our metadata lock guarantees that no transaction is reading |
| 206 | or writing into the table. Yet, to open a write cursor we need |
| 207 | a thr_lock lock. Allow to open base tables only. |
| 208 | */ |
| 209 | table_ref->required_type= TABLE_TYPE_NORMAL; |
| 210 | /* |
| 211 | Ignore pending FLUSH TABLES since we don't want to release |
| 212 | the MDL lock taken above and otherwise there is no way to |
| 213 | wait for FLUSH TABLES in deadlock-free fashion. |
| 214 | */ |
| 215 | flags= MYSQL_OPEN_IGNORE_FLUSH; |
| 216 | /* |
| 217 | Even though we have an MDL lock on the table here, we don't |
| 218 | pass MYSQL_OPEN_HAS_MDL_LOCK to open_and_lock_tables |
| 219 | since to truncate a MERGE table, we must open and lock |
| 220 | merge children, and on those we don't have an MDL lock. |
| 221 | Thus clear the ticket to satisfy MDL asserts. |
| 222 | */ |
| 223 | table_ref->mdl_request.ticket= NULL; |
| 224 | } |
| 225 | |
| 226 | /* Open the table as it will handle some required preparations. */ |
| 227 | if (open_and_lock_tables(thd, table_ref, FALSE, flags)) |
| 228 | DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG); |
| 229 | |
| 230 | /* Whether to truncate regardless of foreign keys. */ |
| 231 | if (! (thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)) |
| 232 | if (fk_truncate_illegal_if_parent(thd, table_ref->table)) |
| 233 | DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG); |
| 234 | |
| 235 | table= table_ref->table; |
| 236 | |
| 237 | if ((table->file->ht->flags & HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE) && |
| 238 | !is_tmp_table) |
| 239 | { |
| 240 | if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) |
| 241 | DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG); |
| 242 | /* |
nothing calls this directly
no test coverage detected