251
251
/**************************************************************//**
252
Pad a column with spaces. */
257
ulint mbminlen, /*!< in: minimum size of a character,
259
byte* pad, /*!< out: padded buffer */
260
ulint len) /*!< in: number of bytes to pad */
264
switch (UNIV_EXPECT(mbminlen, 1)) {
269
memset(pad, 0x20, len);
278
} while (pad < pad_end);
281
/* space=0x00000020 */
289
} while (pad < pad_end);
294
/**************************************************************//**
295
252
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
296
253
The counterpart of this function is row_sel_field_store_in_mysql_format() in
383
340
/* Remove trailing spaces from old style VARCHAR
386
/* Handle Unicode strings differently. */
343
/* Handle UCS2 strings differently. */
387
344
ulint mbminlen = dtype_get_mbminlen(dtype);
389
346
ptr = mysql_data;
395
/* space=0x00000020 */
396
/* Trim "half-chars", just in case. */
400
&& ptr[col_len - 4] == 0x00
401
&& ptr[col_len - 3] == 0x00
402
&& ptr[col_len - 2] == 0x00
403
&& ptr[col_len - 1] == 0x20) {
408
349
/* space=0x0020 */
409
350
/* Trim "half-chars", just in case. */
618
559
"InnoDB: " REFMAN "forcing-recovery.html"
619
560
" for help.\n", stderr);
621
case DB_FOREIGN_EXCEED_MAX_CASCADE:
622
fprintf(stderr, "InnoDB: Cannot delete/update rows with"
623
" cascading foreign key constraints that exceed max"
625
"Please drop excessive foreign constraints"
626
" and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD);
629
563
fprintf(stderr, "InnoDB: unknown error code %lu\n",
675
609
prebuilt->select_lock_type = LOCK_NONE;
676
610
prebuilt->stored_select_lock_type = 99999999;
677
UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type,
678
sizeof prebuilt->stored_select_lock_type);
680
612
prebuilt->search_tuple = dtuple_create(
681
613
heap, 2 * dict_table_get_n_cols(table));
843
dtuple_t* row_get_prebuilt_insert_row(row_prebuilt_t* prebuilt);
845
775
/*********************************************************************//**
846
776
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
847
777
has not yet been built in the prebuilt struct, then this function first
849
779
@return prebuilt dtuple; the column type information is also set in it */
851
782
row_get_prebuilt_insert_row(
852
783
/*========================*/
1432
1363
thr->run_node = node;
1433
1364
thr->prev_node = node;
1434
thr->fk_cascade_depth = 0;
1436
1366
row_upd_step(thr);
1438
/* The recursive call for cascading update/delete happens
1439
in above row_upd_step(), reset the counter once we come
1440
out of the recursive call, so it does not accumulate for
1441
different row deletes */
1442
thr->fk_cascade_depth = 0;
1444
1368
err = trx->error_state;
1446
/* Reset fk_cascade_depth back to 0 */
1447
thr->fk_cascade_depth = 0;
1449
1370
if (err != DB_SUCCESS) {
1450
1371
que_thr_stop_for_mysql(thr);
1482
1403
srv_n_rows_updated++;
1485
/* We update table statistics only if it is a DELETE or UPDATE
1486
that changes indexed columns, UPDATEs that change only non-indexed
1487
columns would not affect statistics. */
1488
if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
1489
row_update_statistics_if_needed(prebuilt->table);
1406
row_update_statistics_if_needed(prebuilt->table);
1492
1408
trx->op_info = "";
1497
1413
/*********************************************************************//**
1498
This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
1499
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
1500
Before calling this function row_search_for_mysql() must have
1501
initialized prebuilt->new_rec_locks to store the information which new
1502
record locks really were set. This function removes a newly set
1503
clustered index record lock under prebuilt->pcur or
1504
prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
1505
releases the latest clustered index record lock we set.
1506
@return error code or DB_SUCCESS */
1414
This can only be used when srv_locks_unsafe_for_binlog is TRUE or
1415
this session is using a READ COMMITTED isolation level. Before
1416
calling this function we must use trx_reset_new_rec_lock_info() and
1417
trx_register_new_rec_lock() to store the information which new record locks
1418
really were set. This function removes a newly set lock under prebuilt->pcur,
1419
and also under prebuilt->clust_pcur. Currently, this is only used and tested
1420
in the case of an UPDATE or a DELETE statement, where the row lock is of the
1422
Thus, this implements a 'mini-rollback' that releases the latest record
1424
@return error code or DB_SUCCESS */
1509
1427
row_unlock_for_mysql(
1510
1428
/*=================*/
1511
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL
1429
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
1513
ibool has_latches_on_recs)/*!< in: TRUE if called so
1514
that we have the latches on
1515
the records under pcur and
1516
clust_pcur, and we do not need
1517
to reposition the cursors. */
1431
ibool has_latches_on_recs)/*!< TRUE if called so that we have
1432
the latches on the records under pcur
1433
and clust_pcur, and we do not need to
1434
reposition the cursors. */
1519
1436
btr_pcur_t* pcur = prebuilt->pcur;
1520
1437
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
1600
if (rec_trx_id != trx->id) {
1517
if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) {
1601
1518
/* We did not update the record: unlock it */
1603
1520
rec = btr_pcur_get_rec(pcur);
1643
1560
trx = thr_get_trx(thr);
1645
/* Increment fk_cascade_depth to record the recursive call depth on
1646
a single update/delete that affects multiple tables chained
1647
together with foreign key relations. */
1648
thr->fk_cascade_depth++;
1650
if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
1651
return (DB_FOREIGN_EXCEED_MAX_CASCADE);
1654
1562
thr->run_node = node;
1655
1563
thr->prev_node = node;
1657
1565
row_upd_step(thr);
1659
/* The recursive call for cascading update/delete happens
1660
in above row_upd_step(), reset the counter once we come
1661
out of the recursive call, so it does not accumulate for
1662
different row deletes */
1663
thr->fk_cascade_depth = 0;
1665
1567
err = trx->error_state;
1667
1569
/* Note that the cascade node is a subnode of another InnoDB
2124
2026
name, reject_fks);
2125
2027
if (err == DB_SUCCESS) {
2126
2028
/* Check that also referencing constraints are ok */
2127
err = dict_load_foreigns(name, FALSE, TRUE);
2029
err = dict_load_foreigns(name, TRUE);
2130
2032
if (err != DB_SUCCESS) {
2473
2375
info = pars_info_create();
2475
2377
pars_info_add_str_literal(info, "table_name", name);
2476
pars_info_add_ull_literal(info, "new_id", new_id);
2378
pars_info_add_dulint_literal(info, "new_id", new_id);
2478
2380
err = que_eval_sql(info,
2479
2381
"PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
2818
2720
trx->table_id = table->id;
2820
/* Lock all index trees for this table, as we will
2821
truncate the table/index and possibly change their metadata.
2822
All DML/DDL are blocked by table level lock, with
2823
a few exceptions such as queries into information schema
2824
about the table, MySQL could try to access index stats
2825
for this kind of query, we need to use index locks to
2827
dict_table_x_lock_indexes(table);
2829
2722
if (table->space && !table->dir_path_of_temp_table) {
2830
2723
/* Discard and create the single-table tablespace. */
2831
2724
ulint space = table->space;
2842
2735
|| fil_create_new_single_table_tablespace(
2843
2736
space, table->name, FALSE, flags,
2844
2737
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2845
dict_table_x_unlock_indexes(table);
2846
2738
ut_print_timestamp(stderr);
2847
2739
fprintf(stderr,
2848
2740
" InnoDB: TRUNCATE TABLE %s failed to"
2947
2839
mem_heap_free(heap);
2949
/* Done with index truncation, release index tree locks,
2950
subsequent work relates to table level metadata change */
2951
dict_table_x_unlock_indexes(table);
2953
2841
dict_hdr_get_new_id(&new_id, NULL, NULL);
2955
2843
info = pars_info_create();
2957
2845
pars_info_add_int4_literal(info, "space", (lint) table->space);
2958
pars_info_add_ull_literal(info, "old_id", table->id);
2959
pars_info_add_ull_literal(info, "new_id", new_id);
2846
pars_info_add_dulint_literal(info, "old_id", table->id);
2847
pars_info_add_dulint_literal(info, "new_id", new_id);
2961
2849
err = que_eval_sql(info,
2962
2850
"PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n"
3344
3232
dict_table_remove_from_cache(table);
3346
if (dict_load_table(name, TRUE) != NULL) {
3234
if (dict_load_table(name) != NULL) {
3347
3235
ut_print_timestamp(stderr);
3348
3236
fputs(" InnoDB: Error: not able to remove table ",
3489
3377
btr_pcur_store_position(&pcur, &mtr);
3490
3378
btr_pcur_commit_specify_mtr(&pcur, &mtr);
3492
table = dict_load_table(table_name, TRUE);
3380
table = dict_load_table(table_name);
3495
3383
row_drop_table_for_mysql(table_name, trx, FALSE);
4001
3889
an ALTER, not in a RENAME. */
4003
3891
err = dict_load_foreigns(
4004
new_name, FALSE, !old_is_tmp || trx->check_foreigns);
3892
new_name, !old_is_tmp || trx->check_foreigns);
4006
3894
if (err != DB_SUCCESS) {
4007
3895
ut_print_timestamp(stderr);