Skip to content

Commit 710b344

Browse files
committed
Fix Bug#14705287 ASSERTION FAILURE IN THREAD 140369867454208 IN FILE
DATA0TYPE.IC LINE 602 Deny the ALTER TABLE command if we are going to end up with too many columns in the table. Also lift the limit from the artificial 1000 (and remove the hard coded magic number 1000), to the actual limit of REC_MAX_N_FIELDS - DATA_N_SYS_COLS (1020) columns, add a new macro REC_MAX_N_USER_FIELDS for that. Approved by: Marko, Joh (rb:1393)
1 parent fef98b3 commit 710b344

File tree

6 files changed

+24
-8
lines changed

6 files changed

+24
-8
lines changed

include/my_base.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,8 @@ is the global server default. */
477477
#define HA_FTS_INVALID_DOCID 182 /* Invalid InnoDB Doc ID */
478478
#define HA_ERR_TABLE_IN_FK_CHECK 183 /* Table being used in foreign key check */
479479
#define HA_ERR_TABLESPACE_EXISTS 184 /* The tablespace existed in storage engine */
480-
#define HA_ERR_LAST 184 /* Copy of last error nr */
480+
#define HA_ERR_TOO_MANY_FIELDS 185 /* Table has too many columns */
481+
#define HA_ERR_LAST 185 /* Copy of last error nr */
481482

482483
/* Number of different errors */
483484
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)

mysys/my_handler_errors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ static const char *handler_error_messages[]=
8787
"Undo record too big",
8888
"Invalid InnoDB FTS Doc ID",
8989
"Table is being used in foreign key check",
90-
"Tablespace already exists"
90+
"Tablespace already exists",
91+
"Too many columns"
9192
};
9293

9394
extern void my_handler_error_register(void);

sql/handler.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3650,6 +3650,9 @@ void handler::print_error(int error, myf errflag)
36503650
case HA_WRONG_CREATE_OPTION:
36513651
textno= ER_ILLEGAL_HA;
36523652
break;
3653+
case HA_ERR_TOO_MANY_FIELDS:
3654+
textno= ER_TOO_MANY_FIELDS;
3655+
break;
36533656
default:
36543657
{
36553658
/* The error was "unknown" to this function.

storage/innobase/handler/ha_innodb.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
5959

6060
#include "trx0sys.h"
6161
#include "mtr0mtr.h"
62+
#include "rem0types.h"
6263
#include "row0ins.h"
6364
#include "row0mysql.h"
6465
#include "row0sel.h"
@@ -9369,11 +9370,8 @@ ha_innobase::create(
93699370
DBUG_ASSERT(thd != NULL);
93709371
DBUG_ASSERT(create_info != NULL);
93719372

9372-
if (form->s->fields > 1000) {
9373-
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
9374-
but we play safe here */
9375-
9376-
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
9373+
if (form->s->fields > REC_MAX_N_USER_FIELDS) {
9374+
DBUG_RETURN(HA_ERR_TOO_MANY_FIELDS);
93779375
} else if (srv_read_only_mode) {
93789376
DBUG_RETURN(HA_ERR_TABLE_READONLY);
93799377
}

storage/innobase/handler/handler0alter.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Smart ALTER TABLE
3434
#include "dict0stats.h"
3535
#include "dict0stats_bg.h"
3636
#include "log0log.h"
37+
#include "rem0types.h"
3738
#include "row0log.h"
3839
#include "row0merge.h"
3940
#include "srv0srv.h"
@@ -268,6 +269,14 @@ ha_innobase::check_if_supported_inplace_alter(
268269
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
269270
}
270271

272+
if (altered_table->s->fields > REC_MAX_N_USER_FIELDS) {
273+
/* Deny the inplace ALTER TABLE. MySQL will try to
274+
re-create the table and ha_innobase::create() will
275+
return an error too. This is how we effectively
276+
deny adding too many columns to a table. */
277+
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
278+
}
279+
271280
update_thd();
272281
trx_search_latch_release_if_reserved(prebuilt->trx);
273282

storage/innobase/include/rem0types.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1994, 2009, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License as published by the Free Software
@@ -34,6 +34,10 @@ typedef byte rec_t;
3434
#define REC_MAX_HEAP_NO (2 * 8192 - 1)
3535
#define REC_MAX_N_OWNED (16 - 1)
3636

37+
/* Maximum number of user defined fields/columns. The reserved columns
38+
are the ones InnoDB adds internally: DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR */
39+
#define REC_MAX_N_USER_FIELDS (REC_MAX_N_FIELDS - DATA_N_SYS_COLS)
40+
3741
/* REC_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and is the maximum
3842
indexed field length (or indexed prefix length) for indexes on tables of
3943
ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT format.

0 commit comments

Comments
 (0)