MWL#43 CREATE TABLE options (by Sanja)

Docs/sp-imp-spec.txt:
  New sql_mode added.
include/my_base.h:
  Flag in frm of create options.
libmysqld/CMakeLists.txt:
  New files added.
libmysqld/Makefile.am:
  New files added.
mysql-test/r/events_bugs.result:
  New sql_mode added.
mysql-test/r/information_schema.result:
  New sql_mode added.
mysql-test/r/sp.result:
  New sql_mode added.
mysql-test/r/system_mysql_db.result:
  New sql_mode added.
mysql-test/suite/funcs_1/r/is_columns_mysql.result:
  New sql_mode added.
mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result:
  New sql_mode added.
mysql-test/t/events_bugs.test:
  New sql_mode added.
mysql-test/t/sp.test:
  New sql_mode added.
scripts/mysql_system_tables.sql:
  New sql_mode added.
scripts/mysql_system_tables_fix.sql:
  New sql_mode added.
sql/CMakeLists.txt:
  New files added.
sql/Makefile.am:
  New files added.
sql/event_db_repository.cc:
  New sql_mode added.
sql/field.cc:
  Create options support added.
sql/field.h:
  Create options support added.
sql/ha_partition.cc:
  Create options support added.
sql/handler.cc:
  Create options support added.
sql/handler.h:
  Create options support added.
sql/log_event.h:
  New sql_mode added.
sql/mysql_priv.h:
  New sql_mode added.
sql/mysqld.cc:
  New sql_mode added.
sql/share/errmsg.txt:
  New error messages added.
sql/sp.cc:
  New sql_mode added.
sql/sp_head.cc:
  Create options support added.
sql/sql_class.cc:
  Create options support added.
  Debug added.
sql/sql_class.h:
  Create options support added.
sql/sql_insert.cc:
  my_safe_a* moved to mysqld_priv.h
sql/sql_lex.h:
  Create options support added.
sql/sql_parse.cc:
  Create options support added.
sql/sql_show.cc:
  Create options support added.
sql/sql_table.cc:
  Create options support added.
sql/sql_view.cc:
  New sql_mode added.
sql/sql_yacc.yy:
  Create options support added.
sql/structs.h:
  Create options support added.
sql/table.cc:
  Create options support added.
sql/table.h:
  Create options support added.
sql/unireg.cc:
  Create options support added.
storage/example/ha_example.cc:
  Create options example.
storage/example/ha_example.h:
  Create options example.
storage/pbxt/src/discover_xt.cc:
  Create options support added.
This commit is contained in:
Sergei Golubchik 2010-04-08 14:10:05 +02:00
parent 8e122db92d
commit e24e1668bc
52 changed files with 1701 additions and 168 deletions

View file

@ -1934,3 +1934,4 @@ client/sql_list.h
libmysqld/client_plugin.c
sql/client_plugin.c
*.dgcov
libmysqld/create_options.cc

View file

@ -1075,7 +1075,7 @@
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
'NOT_USED',
'IGNORE_BAD_TABLE_OPTIONS',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@ -1097,4 +1097,4 @@
) comment='Stored Procedures';
--

View file

@ -314,6 +314,8 @@ enum ha_base_keytype {
#define HA_OPTION_RELIES_ON_SQL_LAYER 512
#define HA_OPTION_NULL_FIELDS 1024
#define HA_OPTION_PAGE_CHECKSUM 2048
/* .frm has extra create options in linked-list format */
#define HA_OPTION_TEXT_CREATE_OPTIONS (1L << 14)
#define HA_OPTION_TEMP_COMPRESS_RECORD (1L << 15) /* set by isamchk */
#define HA_OPTION_READ_ONLY_DATA (1L << 16) /* Set by isamchk */
#define HA_OPTION_NO_CHECKSUM (1L << 17)

View file

@ -208,10 +208,14 @@ extern void my_large_free(uchar * ptr, myf my_flags);
#define alloca __builtin_alloca
#endif /* GNUC */
#define my_alloca(SZ) alloca((size_t) (SZ))
#define my_afree(PTR) {}
#define my_afree(PTR) ((void)0)
#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(MY_FAE)))
#define my_safe_afree(ptr, size, min_length) ((size <= min_length) ? (void)0 : my_free(ptr,MYF(MY_WME)))
#else
#define my_alloca(SZ) my_malloc(SZ,MYF(MY_FAE))
#define my_afree(PTR) my_free(PTR,MYF(MY_WME))
#define my_safe_alloca(size, min_length) my_alloca(size)
#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
#endif /* HAVE_ALLOCA */
#ifndef errno /* did we already get it? */

View file

@ -139,7 +139,8 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
../sql/scheduler.cc ../sql/event_parse_data.cc
../sql/scheduler.cc ../sql/event_parse_data.cc
../sql/create_options.cc
${GEN_SOURCES}
${LIB_SOURCES})

View file

@ -75,7 +75,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
debug_sync.cc \
sql_tablespace.cc \
sql_tablespace.cc create_options.cc \
rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc opt_table_elimination.cc

View file

@ -0,0 +1,182 @@
drop table if exists t1;
SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1';
Warnings:
Warning 1650 Unknown option 'fkey'
Warning 1650 Unknown option 'dff'
Warning 1650 Unknown option 'tkey1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey`=vvv,
KEY `akey` (`a`) `dff`=vvv
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`='1v1'
drop table t1;
#reassiginig options in the same line
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
Warnings:
Warning 1650 Unknown option 'fkey'
Warning 1650 Unknown option 'dff'
Warning 1650 Unknown option 'tkey1'
Warning 1650 Unknown option 'tkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey`=vvv,
KEY `akey` (`a`) `dff`=vvv
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=1v2 `tkey2`=2v1
#add option
alter table t1 tkey4=4v1;
Warnings:
Warning 1650 Unknown option 'tkey4'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey`=vvv,
KEY `akey` (`a`) `dff`=vvv
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=1v2 `tkey2`=2v1 `tkey4`=4v1
#remove options
alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
Warnings:
Warning 1650 Unknown option 'tkey3'
Warning 1650 Unknown option 'tkey4'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey`=vvv,
KEY `akey` (`a`) `dff`=vvv
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=1v2 `tkey2`=2v1
drop table t1;
create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
Warnings:
Warning 1650 Unknown option 'fkey1'
Warning 1650 Unknown option 'kkey1'
Warning 1650 Unknown option 'TKEY1'
Warning 1650 Unknown option 'tkey2'
Warning 1650 Unknown option 'tkey3'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v1,
KEY `akey` (`a`) `kkey1`=v1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#change field with option with the same value
alter table t1 change a a int `FKEY1`='v1';
Warnings:
Warning 1650 Unknown option 'FKEY1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `FKEY1`='v1',
KEY `akey` (`a`) `kkey1`=v1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#change field with option with a different value
alter table t1 change a a int fkey1=v2;
Warnings:
Warning 1650 Unknown option 'fkey1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
KEY `akey` (`a`) `kkey1`=v1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#new column no options
alter table t1 add column b int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`b` int(11) DEFAULT NULL,
KEY `akey` (`a`) `kkey1`=v1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#new key with options
alter table t1 add key bkey (b) kkey2=v1;
Warnings:
Warning 1650 Unknown option 'kkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`b` int(11) DEFAULT NULL,
KEY `akey` (`a`) `kkey1`=v1,
KEY `bkey` (`b`) `kkey2`=v1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#new column with options
alter table t1 add column c int fkey1=v1 fkey2=v2;
Warnings:
Warning 1650 Unknown option 'fkey1'
Warning 1650 Unknown option 'fkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2,
KEY `akey` (`a`) `kkey1`=v1,
KEY `bkey` (`b`) `kkey2`=v1
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#new key no options
alter table t1 add key ckey (c);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2,
KEY `akey` (`a`) `kkey1`=v1,
KEY `bkey` (`b`) `kkey2`=v1,
KEY `ckey` (`c`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#drop column
alter table t1 drop b;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2,
KEY `akey` (`a`) `kkey1`=v1,
KEY `ckey` (`c`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#add column with options after delete
alter table t1 add column b int fkey2=v1;
Warnings:
Warning 1650 Unknown option 'fkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2,
`b` int(11) DEFAULT NULL `fkey2`=v1,
KEY `akey` (`a`) `kkey1`=v1,
KEY `ckey` (`c`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
#add key
alter table t1 add key bkey (b) kkey2=v2;
Warnings:
Warning 1650 Unknown option 'kkey2'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `fkey1`=v2,
`c` int(11) DEFAULT NULL `fkey1`=v1 `fkey2`=v2,
`b` int(11) DEFAULT NULL `fkey2`=v1,
KEY `akey` (`a`) `kkey1`=v1,
KEY `ckey` (`c`),
KEY `bkey` (`b`) `kkey2`=v2
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey2`=2v1 `tkey3`=3v1
drop table t1;
create table t1 (a int) tkey1=100;
Warnings:
Warning 1650 Unknown option 'tkey1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 `tkey1`=100
drop table t1;
#error on unknown option
SET SQL_MODE='';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
ERROR HY000: Unknown option 'fkey'
SET @@SQL_MODE=@OLD_SQL_MODE;

View file

@ -729,9 +729,8 @@ set @@sql_mode= pow(2,32)-1;
create event e1 on schedule every 1 day do select 1;
select @@sql_mode;
@@sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
name

View file

@ -616,7 +616,7 @@ proc body longblob
proc definer char(77)
proc created timestamp
proc modified timestamp
proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
proc sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
proc comment char(64)
proc character_set_client char(32)
proc collation_connection char(32)

View file

@ -62,4 +62,44 @@ select @@global.example_ulong_var;
set session sql_mode=@old_sql_mode;
set session old=bla;
ERROR HY000: Variable 'old' is a read only variable
#legal values
CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `complex`='c,f,f,f'
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0
drop table t1;
SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
#illegal value fixed
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
Warnings:
Warning 1651 Incorrect value '10000000000000000000' for option 'ULL'
Warning 1651 Incorrect value 'ttt' for option 'one_or_two'
Warning 1651 Incorrect value 'SSS' for option 'YESNO'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS
#alter table
alter table t1 ULL=10000000;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000
alter table t1 change a a int complex='c,c,c';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `complex`='c,c,c'
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000
drop table t1;
#illegal value error
SET SQL_MODE='';
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
ERROR HY000: Incorrect value '10000000000000000000' for option 'ULL'
SET @@SQL_MODE=@OLD_SQL_MODE;
UNINSTALL PLUGIN example;

View file

@ -6940,9 +6940,8 @@ create procedure p() begin end;
call p();
select @@sql_mode;
@@sql_mode
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,?,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,IGNORE_BAD_TABLE_OPTIONS,ONLY_FULL_GROUP_BY,NO_UNSIGNED_SUBTRACTION,NO_DIR_IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,HIGH_NOT_PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
set @@sql_mode= @old_mode;
select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
name

View file

@ -202,7 +202,7 @@ proc CREATE TABLE `proc` (
`definer` char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
@ -227,7 +227,7 @@ event CREATE TABLE `event` (
`ends` datetime DEFAULT NULL,
`status` enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL DEFAULT 'ENABLED',
`on_completion` enum('DROP','PRESERVE') NOT NULL DEFAULT 'DROP',
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
`comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
`originator` int(10) unsigned NOT NULL,
`time_zone` char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM',

View file

@ -49,7 +49,7 @@ NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE') select,insert,update,references
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned select,insert,update,references
NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql event sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select,insert,update,references
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED') select,insert,update,references
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
@ -124,7 +124,7 @@ NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER') select,insert,update,references
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') select,insert,update,references
NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql proc sql_mode 15 NO set 488 1464 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') select,insert,update,references
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI select,insert,update,references
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL select,insert,update,references
@ -330,7 +330,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@ -405,7 +405,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc sql_mode set 488 1464 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)

View file

@ -49,7 +49,7 @@ NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL
NULL mysql event name 2 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64) PRI
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL latin1 latin1_swedish_ci char(64)
@ -124,7 +124,7 @@ NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL utf8 utf8_bin char(77) MUL
@ -327,7 +327,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@ -402,7 +402,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)

View file

@ -0,0 +1,68 @@
--disable_warnings
drop table if exists t1;
--enable_warnings
SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1='1v1';
show create table t1;
drop table t1;
--echo #reassiginig options in the same line
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1 TKEY1=DEFAULT tkey1=1v2 tkey2=2v1;
show create table t1;
-- echo #add option
alter table t1 tkey4=4v1;
show create table t1;
--echo #remove options
alter table t1 tkey3=DEFAULT tkey4=DEFAULT;
show create table t1;
drop table t1;
create table t1 (a int fkey1=v1, key akey (a) kkey1=v1) tkey1=1v1 tkey1=1v2 TKEY1=DEFAULT tkey2=2v1 tkey3=3v1;
show create table t1;
--echo #change field with option with the same value
alter table t1 change a a int `FKEY1`='v1';
show create table t1;
--echo #change field with option with a different value
alter table t1 change a a int fkey1=v2;
show create table t1;
--echo #new column no options
alter table t1 add column b int;
show create table t1;
--echo #new key with options
alter table t1 add key bkey (b) kkey2=v1;
show create table t1;
--echo #new column with options
alter table t1 add column c int fkey1=v1 fkey2=v2;
show create table t1;
--echo #new key no options
alter table t1 add key ckey (c);
show create table t1;
--echo #drop column
alter table t1 drop b;
show create table t1;
--echo #add column with options after delete
alter table t1 add column b int fkey2=v1;
show create table t1;
--echo #add key
alter table t1 add key bkey (b) kkey2=v2;
show create table t1;
drop table t1;
#numeric (unquoted) value
create table t1 (a int) tkey1=100;
show create table t1;
drop table t1;
--echo #error on unknown option
SET SQL_MODE='';
--error ER_UNKNOWN_OPTION
create table t1 (a int fkey=vvv, key akey (a) dff=vvv) tkey1=1v1;
SET @@SQL_MODE=@OLD_SQL_MODE;

View file

@ -1204,7 +1204,6 @@ create event e1 on schedule every 1 day do select 1;
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.event where name = 'p' and sql_mode = @full_mode;
drop event e1;

View file

@ -84,4 +84,35 @@ set session sql_mode=@old_sql_mode;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
set session old=bla;
###############################################################
# engine-specific clauses in the CREATE TABLE:
--echo #legal values
CREATE TABLE t1 ( a int complex='c,f,f,f' ) ENGINE=example ULL=10000 STR='dskj' one_or_two='one' YESNO=0;
show create table t1;
drop table t1;
SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
--echo #illegal value fixed
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
show create table t1;
--echo #alter table
alter table t1 ULL=10000000;
show create table t1;
alter table t1 change a a int complex='c,c,c';
show create table t1;
drop table t1;
--echo #illegal value error
SET SQL_MODE='';
--error ER_BAD_OPTION_VALUE
CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS;
SET @@SQL_MODE=@OLD_SQL_MODE;
UNINSTALL PLUGIN example;

View file

@ -8210,7 +8210,6 @@ call p();
select @@sql_mode;
set @@sql_mode= @old_mode;
# Rename SQL modes that differ in name between the server and the table definition.
select replace(@full_mode, '?', 'NOT_USED') into @full_mode;
select replace(@full_mode, 'ALLOW_INVALID_DATES', 'INVALID_DATES') into @full_mode;
select name from mysql.proc where name = 'p' and sql_mode = @full_mode;
drop procedure p;

View file

@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_transition_type ( Time_zone_id int unsign
CREATE TABLE IF NOT EXISTS time_zone_leap_second ( Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8 comment='Leap seconds information for time zones';
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'IGNORE_BAD_TABLE_OPTIONS', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) COLLATE utf8_general_ci DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp(14), PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Procedure privileges';
@ -80,7 +80,7 @@ PREPARE stmt FROM @str;
EXECUTE stmt;
DROP PREPARE stmt;
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) CHARACTER SET utf8 NOT NULL default '', body longblob NOT NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', execute_at DATETIME default NULL, interval_value int(11) default NULL, interval_field ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, last_executed DATETIME default NULL, starts DATETIME default NULL, ends DATETIME default NULL, status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') NOT NULL default 'DROP', sql_mode set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '', originator INTEGER UNSIGNED NOT NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL DEFAULT 'SYSTEM', character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;

View file

@ -368,7 +368,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
'NOT_USED',
'IGNORE_BAD_TABLE_OPTIONS',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
@ -482,14 +482,14 @@ ALTER TABLE db MODIFY Event_priv enum('N','Y') character set utf8 DEFAULT 'N' NO
ALTER TABLE event DROP PRIMARY KEY;
ALTER TABLE event ADD PRIMARY KEY(db, name);
# Add sql_mode column just in case.
ALTER TABLE event ADD sql_mode set ('NOT_USED') AFTER on_completion;
ALTER TABLE event ADD sql_mode set ('IGNORE_BAD_TABLE_OPTIONS') AFTER on_completion;
# Update list of sql_mode values.
ALTER TABLE event MODIFY sql_mode
set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
'NOT_USED',
'IGNORE_BAD_TABLE_OPTIONS',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',

View file

@ -77,6 +77,7 @@ SET (SQL_SOURCE
rpl_rli.cc rpl_mi.cc sql_servers.cc
sql_connect.cc scheduler.cc
sql_profile.cc event_parse_data.cc opt_table_elimination.cc
create_options.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h

View file

@ -78,7 +78,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_plugin.h authors.h event_parse_data.h \
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
contributors.h sql_servers.h
contributors.h sql_servers.h \
create_options.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \
@ -124,7 +125,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc event_parse_data.cc \
opt_table_elimination.cc
opt_table_elimination.cc create_options.cc
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c client_plugin.c

612
sql/create_options.cc Normal file
View file

@ -0,0 +1,612 @@
/* Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/**
@file
Engine defined options of tables/fields/keys in CREATE/ALTER TABLE.
*/
#include "mysql_priv.h"
#include "create_options.h"
#include <my_getopt.h>
#define FRM_QUOTED_VALUE 0x8000
/**
Links this item to the given list end
@param start The list beginning or NULL
@param end The list last element or does not matter
*/
void engine_option_value::link(engine_option_value **start,
engine_option_value **end)
{
DBUG_ENTER("engine_option_value::link");
DBUG_PRINT("enter", ("name: '%s' (%u) value: '%s' (%u)",
name.str, (uint) name.length,
value.str, (uint) value.length));
engine_option_value *opt;
/* check duplicates to avoid writing them to frm*/
for(opt= *start;
opt && ((opt->parsed && !opt->value.str) ||
my_strnncoll(system_charset_info,
(uchar *)name.str, name.length,
(uchar*)opt->name.str, opt->name.length));
opt= opt->next) /* no-op */;
if (opt)
{
opt->value.str= NULL; /* remove previous value */
opt->parsed= TRUE; /* and don't issue warnings for it anymore */
}
/*
Add this option to the end of the list
@note: We add even if it is opt->value.str == NULL because it can be
ALTER TABLE to remove the option.
*/
if (*start)
{
(*end)->next= this;
*end= this;
}
else
{
/*
note that is *start == 0, the value of *end does not matter,
it can be uninitialized.
*/
*start= *end= this;
}
DBUG_VOID_RETURN;
}
static bool report_wrong_value(THD *thd, const char *name, const char *val,
my_bool suppress_warning)
{
if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS))
{
my_error(ER_BAD_OPTION_VALUE, MYF(0), val, name);
return 1;
}
/*
We may need to suppress warnings to avoid duplicate messages
about the same option (option list is parsed more than once during
CREATE/ALTER table).
Errors are not suppressed, as they abort the execution on the first parsing.
*/
if (!suppress_warning)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BAD_OPTION_VALUE,
ER(ER_BAD_OPTION_VALUE), val, name);
return 0;
}
static bool report_unknown_option(THD *thd, engine_option_value *val,
my_bool suppress_warning)
{
DBUG_ENTER("report_unknown_option");
if (val->parsed)
{
DBUG_PRINT("info", ("parsed => exiting"));
DBUG_RETURN(FALSE);
}
if (!(thd->variables.sql_mode & MODE_IGNORE_BAD_TABLE_OPTIONS))
{
my_error(ER_UNKNOWN_OPTION, MYF(0), val->name.str);
DBUG_RETURN(TRUE);
}
if (!suppress_warning)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_UNKNOWN_OPTION,
ER(ER_UNKNOWN_OPTION),
val->name.str);
DBUG_RETURN(FALSE);
}
static bool set_one_value(ha_create_table_option *opt,
THD *thd, LEX_STRING *value, void *base,
my_bool suppress_warning,
MEM_ROOT *root)
{
DBUG_ENTER("set_one_value");
DBUG_PRINT("enter", ("opt: 0x%lx type: %u name '%s' value: '%s'",
(ulong) opt,
opt->type, opt->name,
(value->str ? value->str : "<DEFAULT>")));
switch (opt->type)
{
case HA_OPTION_TYPE_ULL:
{
ulonglong *val= (ulonglong*)((char*)base + opt->offset);
if (!value->str)
{
*val= opt->def_value;
DBUG_RETURN(0);
}
my_option optp= { opt->name, 1, 0, (uchar **)val, 0, 0, GET_ULL,
REQUIRED_ARG, opt->def_value, opt->min_value, opt->max_value,
0, opt->block_size, 0};
ulonglong orig_val= strtoull(value->str, NULL, 10);
my_bool unused;
*val= orig_val;
*val= getopt_ull_limit_value(*val, &optp, &unused);
if (*val == orig_val)
DBUG_RETURN(0);
DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
suppress_warning));
}
case HA_OPTION_TYPE_STRING:
{
char **val= (char **)((char *)base + opt->offset);
if (!value->str)
{
*val= 0;
DBUG_RETURN(0);
}
if (!(*val= strmake_root(root, value->str, value->length)))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
case HA_OPTION_TYPE_ENUM:
{
uint *val= (uint *)((char *)base + opt->offset), num;
*val= opt->def_value;
if (!value->str)
DBUG_RETURN(0);
const char *start= opt->values, *end;
num= 0;
while (*start)
{
for (end=start;
*end && *end != ',';
end+= my_mbcharlen(system_charset_info, *end)) /* no-op */;
if (!my_strnncoll(system_charset_info,
(uchar*)start, end-start,
(uchar*)value->str, value->length))
{
*val= num;
DBUG_RETURN(0);
}
if (*end) *end++;
start= end;
num++;
}
DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
suppress_warning));
}
case HA_OPTION_TYPE_BOOL:
{
bool *val= (bool *)((char *)base + opt->offset);
*val= opt->def_value;
if (!value->str)
DBUG_RETURN(0);
if (!my_strnncoll(system_charset_info,
(const uchar*)"NO", 2,
(uchar *)value->str, value->length) ||
!my_strnncoll(system_charset_info,
(const uchar*)"OFF", 3,
(uchar *)value->str, value->length) ||
!my_strnncoll(system_charset_info,
(const uchar*)"0", 1,
(uchar *)value->str, value->length))
{
*val= FALSE;
DBUG_RETURN(FALSE);
}
if (!my_strnncoll(system_charset_info,
(const uchar*)"YES", 3,
(uchar *)value->str, value->length) ||
!my_strnncoll(system_charset_info,
(const uchar*)"ON", 2,
(uchar *)value->str, value->length) ||
!my_strnncoll(system_charset_info,
(const uchar*)"1", 1,
(uchar *)value->str, value->length))
{
*val= TRUE;
DBUG_RETURN(FALSE);
}
DBUG_RETURN(report_wrong_value(thd, opt->name, value->str,
suppress_warning));
}
}
DBUG_ASSERT(0);
my_error(ER_UNKNOWN_ERROR, MYF(0));
DBUG_RETURN(1);
}
static const size_t ha_option_type_sizeof[]=
{ sizeof(ulonglong), sizeof(char *), sizeof(uint), sizeof(bool)};
/**
Creates option structure and parses list of options in it
@param thd thread handler
@param option_struct where to store pointer on the option struct
@param option_list list of options given by user
@param rules list of option description by engine
@param suppress_warning second parse so we do not need warnings
@param root MEM_ROOT where allocate memory
@retval TRUE Error
@retval FALSE OK
*/
my_bool parse_option_list(THD* thd, void **option_struct,
engine_option_value *option_list,
ha_create_table_option *rules,
my_bool suppress_warning,
MEM_ROOT *root)
{
ha_create_table_option *opt;
size_t option_struct_size= 0;
engine_option_value *val= option_list;
DBUG_ENTER("parse_option_list");
DBUG_PRINT("enter",
("struct: 0x%lx list: 0x%lx rules: 0x%lx suppres %u root 0x%lx",
(ulong) *option_struct, (ulong)option_list, (ulong)rules,
(uint) suppress_warning, (ulong) root));
if (rules)
{
LEX_STRING default_val= {NULL, 0};
for (opt= rules; opt->name; opt++)
set_if_bigger(option_struct_size, opt->offset +
ha_option_type_sizeof[opt->type]);
*option_struct= alloc_root(root, option_struct_size);
/* set all values to default */
for (opt= rules; opt->name; opt++)
set_one_value(opt, thd, &default_val, *option_struct,
suppress_warning, root);
}
for (; val; val= val->next)
{
for (opt= rules; opt && opt->name; opt++)
{
if (my_strnncoll(system_charset_info,
(uchar*)opt->name, opt->name_length,
(uchar*)val->name.str, val->name.length))
continue;
if (set_one_value(opt, thd, &val->value,
*option_struct, suppress_warning || val->parsed, root))
DBUG_RETURN(TRUE);
val->parsed= true;
break;
}
if (report_unknown_option(thd, val, suppress_warning))
DBUG_RETURN(TRUE);
val->parsed= true;
}
DBUG_RETURN(FALSE);
}
/**
Parses all table/fields/keys options
@param thd thread handler
@param file handler of the table
@parem share descriptor of the table
@retval TRUE Error
@retval FALSE OK
*/
my_bool parse_engine_table_options(THD *thd, handlerton *ht,
TABLE_SHARE *share)
{
MEM_ROOT *root= &share->mem_root;
DBUG_ENTER("parse_engine_table_options");
if (parse_option_list(thd, &share->option_struct, share->option_list,
ht->table_options, TRUE, root))
DBUG_RETURN(TRUE);
for (Field **field= share->field; *field; field++)
{
if (parse_option_list(thd, &(*field)->option_struct, (*field)->option_list,
ht->field_options, TRUE, root))
DBUG_RETURN(TRUE);
}
for (uint index= 0; index < share->keys; index ++)
{
if (parse_option_list(thd, &share->key_info[index].option_struct,
share->key_info[index].option_list,
ht->index_options, TRUE, root))
DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
}
/**
Returns representation length of key and value in the frm file
*/
uint engine_option_value::frm_length()
{
/*
1 byte - name length
2 bytes - value length
if value.str is NULL, this option is not written to frm (=DEFAULT)
*/
return value.str ? 1 + name.length + 2 + value.length : 0;
}
/**
Returns length of representation of option list in the frm file
*/
static uint option_list_frm_length(engine_option_value *opt)
{
uint res= 0;
for (; opt; opt= opt->next)
res+= opt->frm_length();
return res;
}
/**
Calculates length of options image in the .frm
@param table_option_list list of table options
@param create_fields field descriptors list
@param keys number of keys
@param key_info array of key descriptors
@returns length of image in frm
*/
uint engine_table_options_frm_length(engine_option_value *table_option_list,
List<Create_field> &create_fields,
uint keys, KEY *key_info)
{
List_iterator<Create_field> it(create_fields);
Create_field *field;
uint res, index;
DBUG_ENTER("engine_table_options_frm_length");
res= option_list_frm_length(table_option_list);
while ((field= it++))
res+= option_list_frm_length(field->option_list);
for (index= 0; index < keys; index++, key_info++)
res+= option_list_frm_length(key_info->option_list);
/*
if there's at least one option somewhere (res > 0)
we write option lists for all fields and keys, zero-terminated.
If there're no options we write nothing at all (backward compatibility)
*/
DBUG_RETURN(res ? res + 1 + create_fields.elements + keys : 0);
}
/**
Writes image of the key and value to the frm image buffer
@param buff pointer to the buffer free space beginning
@returns pointer to byte after last recorded in the buffer
*/
uchar *engine_option_value::frm_image(uchar *buff)
{
if (value.str)
{
*buff++= name.length;
memcpy(buff, name.str, name.length);
buff+= name.length;
int2store(buff, value.length | (quoted_value ? FRM_QUOTED_VALUE : 0));
buff+= 2;
memcpy(buff, (const uchar *) value.str, value.length);
buff+= value.length;
}
return buff;
}
/**
Writes image of the key and value to the frm image buffer
@param buff pointer to the buffer to store the options in
@param opt list of options;
@returns pointer to the end of the stored data in the buffer
*/
static uchar *option_list_frm_image(uchar *buff, engine_option_value *opt)
{
for (; opt; opt= opt->next)
buff= opt->frm_image(buff);
*buff++= 0;
return buff;
}
/**
Writes options image in the .frm buffer
@param buff pointer to the buffer
@param table_option_list list of table options
@param create_fields field descriptors list
@param keys number of keys
@param key_info array of key descriptors
@returns pointer to byte after last recorded in the buffer
*/
uchar *engine_table_options_frm_image(uchar *buff,
engine_option_value *table_option_list,
List<Create_field> &create_fields,
uint keys, KEY *key_info)
{
List_iterator<Create_field> it(create_fields);
Create_field *field;
KEY *key_info_end= key_info + keys;
DBUG_ENTER("engine_table_options_frm_image");
buff= option_list_frm_image(buff, table_option_list);
while ((field= it++))
buff= option_list_frm_image(buff, field->option_list);
while (key_info < key_info_end)
buff= option_list_frm_image(buff, (key_info++)->option_list);
DBUG_RETURN(buff);
}
/**
Reads name and value from buffer, then link it in the list
@param buff the buffer to read from
@param start The list beginning or NULL
@param end The list last element or does not matter
@param root MEM_ROOT for allocating
@returns pointer to byte after last recorded in the buffer
*/
uchar *engine_option_value::frm_read(const uchar *buff, engine_option_value **start,
engine_option_value **end, MEM_ROOT *root)
{
LEX_STRING name, value;
uint len;
name.length= buff[0];
buff++;
if (!(name.str= strmake_root(root, (const char*)buff, name.length)))
return NULL;
buff+= name.length;
len= uint2korr(buff);
value.length= len & ~FRM_QUOTED_VALUE;
buff+= 2;
if (!(value.str= strmake_root(root, (const char*)buff, value.length)))
return NULL;
buff+= value.length;
engine_option_value *ptr=new (root)
engine_option_value(name, value, len & FRM_QUOTED_VALUE, start, end);
if (!ptr)
return NULL;
return (uchar *)buff;
}
/**
Reads options from this buffer
@param buff the buffer to read from
@param length buffer length
@param share table descriptor
@param root MEM_ROOT for allocating
@retval TRUE Error
@retval FALSE OK
*/
my_bool engine_table_options_frm_read(const uchar *buff, uint length,
TABLE_SHARE *share)
{
const uchar *buff_end= buff + length;
engine_option_value *end;
MEM_ROOT *root= &share->mem_root;
uint count;
DBUG_ENTER("engine_table_options_frm_read");
while (buff < buff_end && *buff)
{
if (!(buff= engine_option_value::frm_read(buff, &share->option_list, &end,
root)))
DBUG_RETURN(TRUE);
}
buff++;
for (count=0; count < share->fields; count++)
{
while (buff < buff_end && *buff)
{
if (!(buff= engine_option_value::frm_read(buff,
&share->field[count]->option_list,
&end, root)))
DBUG_RETURN(TRUE);
}
buff++;
}
for (count=0; count < share->keys; count++)
{
while (buff < buff_end && *buff)
{
if (!(buff= engine_option_value::frm_read(buff,
&share->key_info[count].option_list,
&end, root)))
DBUG_RETURN(TRUE);
}
buff++;
}
DBUG_RETURN(buff != buff_end);
}
/**
Merges two lists of engine_option_value's with duplicate removal.
*/
engine_option_value *merge_engine_table_options(engine_option_value *first,
engine_option_value *second,
MEM_ROOT *root)
{
engine_option_value *end, *opt;
DBUG_ENTER("merge_engine_table_options");
/* find last element */
if (first && second)
for (end= first; end->next; end= end->next) /* no-op */;
for (opt= second; opt; opt= opt->next)
new (root) engine_option_value(opt->name, opt->value, opt->quoted_value,
&first, &end);
DBUG_RETURN(first);
}

92
sql/create_options.h Normal file
View file

@ -0,0 +1,92 @@
/* Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/**
@file
Engine defined options of tables/fields/keys in CREATE/ALTER TABLE.
*/
#ifndef SQL_CREATE_OPTIONS_INCLUDED
#define SQL_CREATE_OPTIONS_INCLUDED
#include "handler.h"
class engine_option_value: public Sql_alloc
{
public:
LEX_STRING name;
LEX_STRING value;
engine_option_value *next; ///< parser puts them in a FIFO linked list
bool parsed; ///< to detect unrecognized options
bool quoted_value; ///< option=VAL vs. option='VAL'
engine_option_value(LEX_STRING &name_arg, LEX_STRING &value_arg, bool quoted,
engine_option_value **start, engine_option_value **end) :
name(name_arg), value(value_arg),
next(NULL), parsed(false), quoted_value(quoted)
{
link(start, end);
}
engine_option_value(LEX_STRING &name_arg,
engine_option_value **start, engine_option_value **end) :
name(name_arg), value(null_lex_str),
next(NULL), parsed(false), quoted_value(false)
{
link(start, end);
}
engine_option_value(LEX_STRING &name_arg, ulonglong value_arg,
engine_option_value **start, engine_option_value **end,
MEM_ROOT *root) :
name(name_arg), next(NULL), parsed(false), quoted_value(false)
{
if ((value.str= (char *)alloc_root(root, 22)))
{
value.length= longlong10_to_str(value_arg, value.str, 10) - value.str;
link(start, end);
}
}
static uchar *frm_read(const uchar *buff, engine_option_value **start,
engine_option_value **end, MEM_ROOT *root);
void link(engine_option_value **start, engine_option_value **end);
uint frm_length();
uchar *frm_image(uchar *buff);
};
typedef struct st_key KEY;
class Create_field;
my_bool parse_engine_table_options(THD *thd, handlerton *ht,
TABLE_SHARE *share);
my_bool parse_option_list(THD* thd, void **option_struct,
engine_option_value *option_list,
ha_create_table_option *rules,
my_bool suppress_warning,
MEM_ROOT *root);
my_bool engine_table_options_frm_read(const uchar *buff,
uint length,
TABLE_SHARE *share);
engine_option_value *merge_engine_table_options(engine_option_value *source,
engine_option_value *changes,
MEM_ROOT *root);
uint engine_table_options_frm_length(engine_option_value *table_option_list,
List<Create_field> &create_fields,
uint keys, KEY *key_info);
uchar *engine_table_options_frm_image(uchar *buff,
engine_option_value *table_option_list,
List<Create_field> &create_fields,
uint keys, KEY *key_info);
#endif

View file

@ -105,7 +105,8 @@ const TABLE_FIELD_TYPE event_table_fields[ET_FIELD_COUNT] =
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
"'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
"'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY',"
"'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"

View file

@ -1306,14 +1306,13 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg)
:ptr(ptr_arg), null_ptr(null_ptr_arg),
table(0), orig_table(0), table_name(0),
field_name(field_name_arg),
key_start(0), part_of_key(0), part_of_key_not_clustered(0),
part_of_sortkey(0), unireg_check(unireg_check_arg),
field_length(length_arg), null_bit(null_bit_arg),
is_created_from_null_item(FALSE),
vcol_info(0), stored_in_db(TRUE)
:ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
table_name(0), field_name(field_name_arg), option_list(0),
option_struct(0), key_start(0), part_of_key(0),
part_of_key_not_clustered(0), part_of_sortkey(0),
unireg_check(unireg_check_arg), field_length(length_arg),
null_bit(null_bit_arg), is_created_from_null_item(FALSE), vcol_info(0),
stored_in_db(TRUE)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
comment.str= (char*) "";
@ -9567,7 +9566,8 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
Item *fld_on_update_value, LEX_STRING *fld_comment,
char *fld_change, List<String> *fld_interval_list,
CHARSET_INFO *fld_charset, uint fld_geom_type,
Virtual_column_info *fld_vcol_info)
Virtual_column_info *fld_vcol_info,
engine_option_value *create_opt)
{
uint sign_len, allowed_type_modifier= 0;
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
@ -9578,6 +9578,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
field_name= fld_name;
def= fld_default_value;
flags= fld_type_modifier;
option_list= create_opt;
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
Field::NEXT_NUMBER : Field::NONE);
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
@ -10217,6 +10218,8 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
decimals= old_field->decimals();
vcol_info= old_field->vcol_info;
stored_in_db= old_field->stored_in_db;
option_list= old_field->option_list;
option_struct= old_field->option_struct;
/* Fix if the original table had 4 byte pointer blobs */
if (flags & BLOB_FLAG)
@ -10290,6 +10293,19 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
}
/**
Makes a clone of this object for ALTER/CREATE TABLE
@param mem_root MEM_ROOT where to clone the field
*/
Create_field *Create_field::clone(MEM_ROOT *mem_root) const
{
Create_field *res= new (mem_root) Create_field(*this);
return res;
}
/**
maximum possible display length for blob.

View file

@ -137,6 +137,9 @@ public:
struct st_table *table; // Pointer for table
struct st_table *orig_table; // Pointer to original table
const char **table_name, *field_name;
/** reference to the list of options or NULL */
engine_option_value *option_list;
void *option_struct; /* structure with parsed options */
LEX_STRING comment;
/* Field is part of the following keys */
key_map key_start, part_of_key, part_of_key_not_clustered;
@ -2145,6 +2148,9 @@ public:
CHARSET_INFO *charset;
Field::geometry_type geom_type;
Field *field; // For alter table
engine_option_value *option_list;
/** structure with parsed options (for comparing fields in ALTER TABLE) */
void *option_struct;
uint8 row,col,sc_length,interval_id; // For rea_create_table
uint offset,pack_flag;
@ -2162,11 +2168,11 @@ public:
*/
bool stored_in_db;
Create_field() :after(0) {}
Create_field() :after(0), option_list(NULL), option_struct(NULL)
{}
Create_field(Field *field, Field *orig_field);
/* Used to make a clone of this object for ALTER/CREATE TABLE */
Create_field *clone(MEM_ROOT *mem_root) const
{ return new (mem_root) Create_field(*this); }
Create_field *clone(MEM_ROOT *mem_root) const;
void create_length_to_internal_length(void);
/* Init for a tmp table field. To be extended if need be. */
@ -2178,8 +2184,8 @@ public:
char *decimals, uint type_modifier, Item *default_value,
Item *on_update_value, LEX_STRING *comment, char *change,
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type,
Virtual_column_info *vcol_info);
uint uint_geom_type, Virtual_column_info *vcol_info,
engine_option_value *option_list);
bool field_flags_are_binary()
{

View file

@ -52,6 +52,7 @@
#endif
#include "mysql_priv.h"
#include "create_options.h"
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
@ -1218,7 +1219,9 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
DBUG_ENTER("prepare_new_partition");
if ((error= set_up_table_before_create(tbl, part_name, create_info,
0, p_elem)))
0, p_elem)) ||
parse_engine_table_options(ha_thd(), file->ht,
file->table_share))
goto error_create;
if ((error= file->ha_create(part_name, tbl, create_info)))
{
@ -1869,6 +1872,8 @@ uint ha_partition::del_ren_cre_table(const char *from,
{
if ((error= set_up_table_before_create(table_arg, from_buff,
create_info, i, NULL)) ||
parse_engine_table_options(ha_thd(), (*file)->ht,
(*file)->table_share) ||
((error= (*file)->ha_create(from_buff, table_arg, create_info))))
goto create_error;
}

View file

@ -24,6 +24,7 @@
#endif
#include "mysql_priv.h"
#include "create_options.h"
#include "rpl_filter.h"
#include <myisampack.h>
#include "myisam.h"
@ -3719,7 +3720,11 @@ int ha_create_table(THD *thd, const char *path,
name= get_canonical_filename(table.file, share.path.str, name_buff);
if (parse_engine_table_options(thd, table.file->ht, &share))
goto err;
error= table.file->ha_create(name, &table, create_info);
VOID(closefrm(&table, 0));
if (error)
{

View file

@ -16,6 +16,9 @@
/* Definitions for parameters to do with handler-routines */
#ifndef SQL_HANDLER_INCLUDED
#define SQL_HANDLER_INCLUDED
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
@ -549,6 +552,103 @@ struct handler_log_file_data {
enum log_status status;
};
/*
Definitions for engine-specific table/field/index options in the CREATE TABLE.
Options are declared with HA_*OPTION_* macros (HA_TOPTION_ULL, HA_FOPTION_ENUM,
HA_KOPTION_STRING, etc).
Every macros takes the option name, and the name of the underlying field of
the appropriate C structure. The "appropriate C structure" is
ha_table_option_struct for table level options,
ha_field_option_struct for field level options,
ha_key_option_struct for key level options. The engine either
defines a structure of this name, or uses #define's to map
these "appropriate" names to the actual structure type name.
ULL options use a ulonglong as the backing store.
HA_*OPTION_ULL() takes the option name, the structure field name,
the default value for the option, min, max, and blk_siz values.
STRING options use a char* as a backing store.
HA_*OPTION_STRING takes the option name and the structure field name.
The default value will be 0.
ENUM options use a uint as a backing store (not enum!!!).
HA_*OPTION_ENUM takes the option name, the structure field name,
the default value for the option as a number, and a string with the
permitted values for this enum - one string with comma separated values,
for example: "gzip,bzip2,lzma"
BOOL options use a bool as a backing store.
HA_*OPTION_BOOL takes the option name, the structure field name,
and the default value for the option.
From the SQL, BOOL options accept YES/NO, ON/OFF, and 1/0.
The name of the option is limited to 255 bytes,
the value (for string options) - to the 32767 bytes.
See ha_example.cc for an example.
*/
enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
HA_OPTION_TYPE_STRING, /* char * */
HA_OPTION_TYPE_ENUM, /* uint */
HA_OPTION_TYPE_BOOL}; /* bool */
#define HA_xOPTION_ULL(name, struc, field, def, min, max, blk_siz) \
{ HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \
offsetof(struc, field), def, min, max, blk_siz, 0 }
#define HA_xOPTION_STRING(name, struc, field) \
{ HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \
offsetof(struc, field), 0, 0, 0, 0, 0 }
#define HA_xOPTION_ENUM(name, struc, field, values, def) \
{ HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \
offsetof(struc, field), def, 0, \
sizeof(values)-1, 0, values }
#define HA_xOPTION_BOOL(name, struc, field, def) \
{ HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \
offsetof(struc, field), def, 0, 1, 0, 0 }
#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 }
#define HA_TOPTION_ULL(name, field, def, min, max, blk_siz) \
HA_xOPTION_ULL(name, ha_table_option_struct, field, def, min, max, blk_siz)
#define HA_TOPTION_STRING(name, field) \
HA_xOPTION_STRING(name, ha_table_option_struct, field)
#define HA_TOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
#define HA_TOPTION_BOOL(name, field, def) \
HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
#define HA_TOPTION_END HA_xOPTION_END
#define HA_FOPTION_ULL(name, field, def, min, max, blk_siz) \
HA_xOPTION_ULL(name, ha_field_option_struct, field, def, min, max, blk_siz)
#define HA_FOPTION_STRING(name, field) \
HA_xOPTION_STRING(name, ha_field_option_struct, field)
#define HA_FOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
#define HA_FOPTION_BOOL(name, field, def) \
HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
#define HA_FOPTION_END HA_xOPTION_END
#define HA_KOPTION_ULL(name, field, def, min, max, blk_siz) \
HA_xOPTION_ULL(name, ha_key_option_struct, field, def, min, max, blk_siz)
#define HA_KOPTION_STRING(name, field) \
HA_xOPTION_STRING(name, ha_key_option_struct, field)
#define HA_KOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_key_option_struct, field, values, def)
#define HA_KOPTION_BOOL(name, field, values, def) \
HA_xOPTION_BOOL(name, ha_key_option_struct, field, values, def)
#define HA_KOPTION_END HA_xOPTION_END
typedef struct st_ha_create_table_option {
enum ha_option_type type;
const char *name;
size_t name_length;
ptrdiff_t offset;
ulonglong def_value;
ulonglong min_value, max_value, block_size;
const char *values;
} ha_create_table_option;
enum handler_iterator_type
{
@ -721,7 +821,13 @@ struct handlerton
int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
const char *name);
uint32 license; /* Flag for Engine License */
void *data; /* Location for engines to keep personal structures */
/*
Optional clauses in the CREATE/ALTER TABLE
*/
ha_create_table_option *table_options; // table level options
ha_create_table_option *field_options; // these are specified per field
ha_create_table_option *index_options; // these are specified per index
};
@ -945,11 +1051,16 @@ typedef struct st_ha_create_information
uint extra_size; /* length of extra data segment */
/** Transactional or not. Unused; reserved for future versions. */
enum ha_choice transactional;
bool table_existed; /* 1 in create if table existed */
bool frm_only; /* 1 if no ha_create_table() */
bool varchar; /* 1 if table has a VARCHAR */
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
enum ha_choice page_checksum; /* If we have page_checksums */
bool table_existed; ///< 1 in create if table existed
bool frm_only; ///< 1 if no ha_create_table()
bool varchar; ///< 1 if table has a VARCHAR
enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY
enum ha_choice page_checksum; ///< If we have page_checksums
engine_option_value *option_list; ///< list of table create options
/* the following three are only for ALTER TABLE, check_if_incompatible_data() */
void *option_struct; ///< structure with parsed table options
void **fileds_option_struct; ///< array of field option structures
void **keys_option_struct; ///< array of key option structures
} HA_CREATE_INFO;
@ -2255,3 +2366,5 @@ int ha_binlog_end(THD *thd);
#define ha_binlog_wait(a) do {} while (0)
#define ha_binlog_end(a) do {} while (0)
#endif
#endif

View file

@ -1371,7 +1371,7 @@ protected:
MODE_PIPES_AS_CONCAT==0x2
MODE_ANSI_QUOTES==0x4
MODE_IGNORE_SPACE==0x8
MODE_NOT_USED==0x10
MODE_IGNORE_BAD_TABLE_OPTIONS==0x10
MODE_ONLY_FULL_GROUP_BY==0x20
MODE_NO_UNSIGNED_SUBTRACTION==0x40
MODE_NO_DIR_IN_CREATE==0x80

View file

@ -520,7 +520,7 @@ protected:
#define MODE_PIPES_AS_CONCAT 2
#define MODE_ANSI_QUOTES 4
#define MODE_IGNORE_SPACE 8
#define MODE_NOT_USED 16
#define MODE_IGNORE_BAD_TABLE_OPTIONS 16
#define MODE_ONLY_FULL_GROUP_BY 32
#define MODE_NO_UNSIGNED_SUBTRACTION 64
#define MODE_NO_DIR_IN_CREATE 128
@ -1508,7 +1508,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum enum_field_types t
char *change, List<String> *interval_list,
CHARSET_INFO *cs,
uint uint_geom_type,
Virtual_column_info *vcol_info);
Virtual_column_info *vcol_info,
engine_option_value *create_options);
Create_field * new_create_field(THD *thd, char *field_name, enum_field_types type,
char *length, char *decimals,
uint type_modifier,

View file

@ -244,7 +244,7 @@ const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
static const char *sql_mode_names[]=
{
"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
"?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
"IGNORE_BAD_TABLE_OPTIONS", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
"NO_DIR_IN_CREATE",
"POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
"NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
@ -264,7 +264,7 @@ static const unsigned int sql_mode_names_len[]=
/*PIPES_AS_CONCAT*/ 15,
/*ANSI_QUOTES*/ 11,
/*IGNORE_SPACE*/ 12,
/*?*/ 1,
/*IGNORE_BAD_TABLE_OPTIONS*/ 24,
/*ONLY_FULL_GROUP_BY*/ 18,
/*NO_UNSIGNED_SUBTRACTION*/ 23,
/*NO_DIR_IN_CREATE*/ 16,

View file

@ -6240,3 +6240,8 @@ ER_DEBUG_SYNC_TIMEOUT
ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
ER_UNKNOWN_OPTION
eng "Unknown option '%-.64s'"
ER_BAD_OPTION_VALUE
eng "Incorrect value '%-.64s' for option '%-.64s'"

View file

@ -147,7 +147,8 @@ TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
{
{ C_STRING_WITH_LEN("sql_mode") },
{ C_STRING_WITH_LEN("set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES',"
"'IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION',"
"'IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY',"
"'NO_UNSIGNED_SUBTRACTION',"
"'NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB',"
"'NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40',"
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"

View file

@ -2218,7 +2218,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
lex->charset ? lex->charset :
thd->variables.collation_database,
lex->uint_geom_type,
lex->vcol_info))
lex->vcol_info, NULL))
return TRUE;
if (field_def->interval_list.elements)

View file

@ -106,6 +106,7 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root)
key_create_info(rhs.key_create_info),
columns(rhs.columns, mem_root),
name(rhs.name),
option_list(rhs.option_list),
generated(rhs.generated)
{
list_copy_and_replace_each_value(columns, mem_root);
@ -775,6 +776,7 @@ THD::THD()
void THD::push_internal_handler(Internal_error_handler *handler)
{
DBUG_ENTER("THD::push_internal_handler");
if (m_internal_handler)
{
handler->m_prev_internal_handler= m_internal_handler;
@ -784,6 +786,7 @@ void THD::push_internal_handler(Internal_error_handler *handler)
{
m_internal_handler= handler;
}
DBUG_VOID_RETURN;
}
@ -803,8 +806,10 @@ bool THD::handle_error(uint sql_errno, const char *message,
void THD::pop_internal_handler()
{
DBUG_ENTER("THD::pop_internal_handler");
DBUG_ASSERT(m_internal_handler != NULL);
m_internal_handler= m_internal_handler->m_prev_internal_handler;
DBUG_VOID_RETURN;
}
extern "C"

View file

@ -205,13 +205,15 @@ public:
KEY_CREATE_INFO key_create_info;
List<Key_part_spec> columns;
const char *name;
engine_option_value *option_list;
bool generated;
Key(enum Keytype type_par, const char *name_arg,
KEY_CREATE_INFO *key_info_arg,
bool generated_arg, List<Key_part_spec> &cols)
bool generated_arg, List<Key_part_spec> &cols,
engine_option_value *create_opt)
:type(type_par), key_create_info(*key_info_arg), columns(cols),
name(name_arg), generated(generated_arg)
name(name_arg), option_list(create_opt), generated(generated_arg)
{}
Key(const Key &rhs, MEM_ROOT *mem_root);
virtual ~Key() {}
@ -240,7 +242,7 @@ public:
Foreign_key(const char *name_arg, List<Key_part_spec> &cols,
Table_ident *table, List<Key_part_spec> &ref_cols,
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols),
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
ref_table(table), ref_columns(ref_cols),
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
match_opt(match_opt_arg)

View file

@ -72,15 +72,6 @@ static void unlink_blobs(register TABLE *table);
#endif
static bool check_view_insertability(THD *thd, TABLE_LIST *view);
/* Define to force use of my_malloc() if the allocated memory block is big */
#ifndef HAVE_ALLOCA
#define my_safe_alloca(size, min_length) my_alloca(size)
#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
#else
#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
#endif
/*
Check that insert/update fields are from the same single table of a view.

View file

@ -1748,6 +1748,11 @@ typedef struct st_lex : public Query_tables_list
const char *stmt_definition_end;
/**
Collects create options for Field and KEY
*/
engine_option_value *option_list, *option_list_last;
/**
During name resolution search only in the table list given by
Name_resolution_context::first_name_resolution_table and

View file

@ -6086,7 +6086,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
char *change,
List<String> *interval_list, CHARSET_INFO *cs,
uint uint_geom_type,
Virtual_column_info *vcol_info)
Virtual_column_info *vcol_info,
engine_option_value *create_options)
{
register Create_field *new_field;
LEX *lex= thd->lex;
@ -6104,7 +6105,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::PRIMARY, NullS,
&default_key_create_info,
0, lex->col_list);
0, lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@ -6114,7 +6115,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
key= new Key(Key::UNIQUE, NullS,
&default_key_create_info, 0,
lex->col_list);
lex->col_list, NULL);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty();
}
@ -6172,7 +6173,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
if (!(new_field= new Create_field()) ||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
default_value, on_update_value, comment, change,
interval_list, cs, uint_geom_type, vcol_info))
interval_list, cs, uint_geom_type, vcol_info,
create_options))
DBUG_RETURN(1);
lex->alter_info.create_list.push_back(new_field);

View file

@ -18,6 +18,7 @@
#include "mysql_priv.h"
#include "sql_select.h" // For select_describe
#include "create_options.h"
#include "sql_show.h"
#include "repl_failsafe.h"
#include "sp.h"
@ -1043,7 +1044,7 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
/*
The identifier must be quoted as it includes a quote character or
it's a keyword
it's a keyword
*/
VOID(packet->reserve(length*2 + 2));
@ -1203,6 +1204,31 @@ static bool get_field_default_value(THD *thd, TABLE *table,
return has_default;
}
/**
Appends list of options to string
@param thd thread handler
@param packet string to append
@param opt list of options
*/
static void append_create_options(THD *thd, String *packet,
engine_option_value *opt)
{
for(; opt; opt= opt->next)
{
DBUG_ASSERT(opt->value.str);
packet->append(' ');
append_identifier(thd, packet, opt->name.str, opt->name.length);
packet->append('=');
if (opt->quoted_value)
append_unescaped(packet, opt->value.str, opt->value.length);
else
packet->append(opt->value.str, opt->value.length);
}
}
/*
Build a CREATE TABLE statement for a table.
@ -1385,6 +1411,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(packet, field->comment.str, field->comment.length);
}
append_create_options(thd, packet, field->option_list);
}
key_info= table->key_info;
@ -1456,6 +1483,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
append_identifier(thd, packet, parser_name->str, parser_name->length);
packet->append(STRING_WITH_LEN(" */ "));
}
append_create_options(thd, packet, key_info->option_list);
}
/*
@ -1615,6 +1643,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN(" CONNECTION="));
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
}
append_create_options(thd, packet, share->option_list);
append_directory(thd, packet, "DATA", create_info.data_file_name);
append_directory(thd, packet, "INDEX", create_info.index_file_name);
}

View file

@ -19,6 +19,7 @@
#include <hash.h>
#include <myisam.h>
#include <my_dir.h>
#include "create_options.h"
#include "sp_head.h"
#include "sql_trigger.h"
#include "sql_show.h"
@ -42,17 +43,10 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
static bool prepare_blob_field(THD *thd, Create_field *sql_field);
static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
static int
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
Alter_info *alter_info,
bool tmp_table,
uint *db_options,
handler *file, KEY **key_info_buffer,
uint *key_count, int select_field_count);
static bool
mysql_prepare_alter_table(THD *thd, TABLE *table,
HA_CREATE_INFO *create_info,
Alter_info *alter_info);
static int mysql_prepare_create_table(THD *, HA_CREATE_INFO *, Alter_info *,
bool, uint *, handler *, KEY **, uint *, int);
static bool mysql_prepare_alter_table(THD *, TABLE *, HA_CREATE_INFO *,
Alter_info *);
#ifndef DBUG_OFF
@ -2863,6 +2857,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->offset= record_offset;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
if (parse_option_list(thd, &sql_field->option_struct,
sql_field->option_list,
create_info->db_type->field_options, FALSE,
thd->mem_root))
DBUG_RETURN(TRUE);
/*
For now skip fields that are not physically stored in the database
(virtual fields) and update their offset later
@ -3061,6 +3060,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number;
key_info->algorithm= key->key_create_info.algorithm;
key_info->option_list= key->option_list;
if (parse_option_list(thd, &key_info->option_struct,
key_info->option_list,
create_info->db_type->index_options, FALSE,
thd->mem_root))
DBUG_RETURN(TRUE);
if (key->type == Key::FULLTEXT)
{
@ -3438,6 +3443,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
if (parse_option_list(thd, &create_info->option_struct,
create_info->option_list,
create_info->db_type->table_options, FALSE,
thd->mem_root))
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
@ -5679,6 +5690,7 @@ compare_tables(TABLE *table,
KEY_PART_INFO *key_part;
KEY_PART_INFO *end;
THD *thd= table->in_use;
uint i;
/*
Remember if the new definition has new VARCHAR column;
create_info->varchar will be reset in mysql_prepare_create_table.
@ -5769,6 +5781,12 @@ compare_tables(TABLE *table,
DBUG_RETURN(0);
}
if ((create_info->fileds_option_struct=
(void**)thd->calloc(sizeof(void*) * table->s->fields)) == NULL ||
(create_info->keys_option_struct=
(void**)thd->calloc(sizeof(void*) * table->s->keys)) == NULL)
DBUG_RETURN(1);
/*
Use transformed info to evaluate possibility of fast ALTER TABLE
but use the preserved field to persist modifications.
@ -5776,15 +5794,19 @@ compare_tables(TABLE *table,
new_field_it.init(alter_info->create_list);
tmp_new_field_it.init(tmp_alter_info.create_list);
/* Go through fields and check if the original ones are compatible
/*
Go through fields and check if the original ones are compatible
with new table.
*/
for (f_ptr= table->field, new_field= new_field_it++,
for (i= 0, f_ptr= table->field, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++;
(field= *f_ptr);
f_ptr++, new_field= new_field_it++,
i++, f_ptr++, new_field= new_field_it++,
tmp_new_field= tmp_new_field_it++)
{
DBUG_ASSERT(i < table->s->fields);
create_info->fileds_option_struct[i]= tmp_new_field->option_struct;
/* Make sure we have at least the default charset in use. */
if (!new_field->charset)
new_field->charset= create_info->default_table_charset;
@ -5938,7 +5960,9 @@ compare_tables(TABLE *table,
for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
{
/* Search an old key with the same name. */
for (table_key= table->key_info; table_key < table_key_end; table_key++)
for (i= 0, table_key= table->key_info;
table_key < table_key_end;
i++, table_key++)
{
if (! strcmp(table_key->name, new_key->name))
break;
@ -5957,6 +5981,11 @@ compare_tables(TABLE *table,
}
DBUG_PRINT("info", ("index added: '%s'", new_key->name));
}
else
{
DBUG_ASSERT(i < table->s->keys);
create_info->keys_option_struct[i]= new_key->option_struct;
}
}
/* Check if changes are compatible with current handler without a copy */
@ -6132,6 +6161,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
restore_record(table, s->default_values); // Empty record for DEFAULT
create_info->option_list= merge_engine_table_options(table->s->option_list,
create_info->option_list, thd->mem_root);
/*
First collect all fields from table which isn't in drop_list
*/
@ -6384,7 +6415,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
key= new Key(key_type, key_name,
&key_create_info,
test(key_info->flags & HA_GENERATED_KEY),
key_parts);
key_parts, key_info->option_list);
new_key_list.push_back(key);
}
}

View file

@ -1185,7 +1185,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
+ MODE_PIPES_AS_CONCAT affect expression parsing
+ MODE_ANSI_QUOTES affect expression parsing
+ MODE_IGNORE_SPACE affect expression parsing
- MODE_NOT_USED not used :)
- MODE_IGNORE_BAD_TABLE_OPTIONS affect only CREATE/ALTER TABLE parsing
* MODE_ONLY_FULL_GROUP_BY affect execution
* MODE_NO_UNSIGNED_SUBTRACTION affect execution
- MODE_NO_DIR_IN_CREATE affect table creation only

View file

@ -44,6 +44,7 @@
#include "sp_rcontext.h"
#include "sp.h"
#include "event_parse_data.h"
#include "create_options.h"
#include <myisam.h>
#include <myisammrg.h>
@ -608,6 +609,7 @@ static bool add_create_index_prepare (LEX *lex, Table_ident *table)
lex->alter_info.flags= ALTER_ADD_INDEX;
lex->col_list.empty();
lex->change= NullS;
lex->option_list= NULL;
return FALSE;
}
@ -617,7 +619,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type, const char *name,
{
Key *key;
key= new Key(type, name, info ? info : &lex->key_create_info, generated,
lex->col_list);
lex->col_list, lex->option_list);
if (key == NULL)
return TRUE;
@ -3898,7 +3900,11 @@ create2:
;
create2a:
field_list ')' opt_create_table_options
field_list ')'
{
Lex->create_info.option_list= NULL;
}
opt_create_table_options
opt_partitioning
create3 {}
| opt_partitioning
@ -4751,6 +4757,30 @@ create_table_option:
Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
Lex->create_info.transactional= $3;
}
| IDENT_sys equal TEXT_STRING_sys
{
new (YYTHD->mem_root)
engine_option_value($1, $3, true, &Lex->create_info.option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
new (YYTHD->mem_root)
engine_option_value($1, $3, false, &Lex->create_info.option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ulonglong_num
{
new (YYTHD->mem_root)
engine_option_value($1, $3, &Lex->create_info.option_list,
&Lex->option_list_last, YYTHD->mem_root);
}
| IDENT_sys equal DEFAULT
{
new (YYTHD->mem_root)
engine_option_value($1, &Lex->create_info.option_list,
&Lex->option_list_last);
}
;
default_charset:
@ -4872,25 +4902,33 @@ column_def:
;
key_def:
normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
normal_key_type opt_ident key_alg '(' key_list ')'
{ Lex->option_list= NULL; }
normal_key_options
{
if (add_create_index (Lex, $1, $2))
MYSQL_YYABORT;
}
| fulltext opt_key_or_index opt_ident init_key_options
'(' key_list ')' fulltext_key_options
'(' key_list ')'
{ Lex->option_list= NULL; }
fulltext_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| spatial opt_key_or_index opt_ident init_key_options
'(' key_list ')' spatial_key_options
'(' key_list ')'
{ Lex->option_list= NULL; }
spatial_key_options
{
if (add_create_index (Lex, $1, $3))
MYSQL_YYABORT;
}
| opt_constraint constraint_key_type opt_ident key_alg
'(' key_list ')' normal_key_options
'(' key_list ')'
{ Lex->option_list= NULL; }
normal_key_options
{
if (add_create_index (Lex, $2, $3 ? $3 : $1))
MYSQL_YYABORT;
@ -4953,6 +4991,7 @@ field_spec:
lex->comment=null_lex_str;
lex->charset=NULL;
lex->vcol_info= 0;
lex->option_list= NULL;
}
field_def
{
@ -4963,7 +5002,7 @@ field_spec:
&lex->comment,
lex->change,&lex->interval_list,lex->charset,
lex->uint_geom_type,
lex->vcol_info))
lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
;
@ -5383,6 +5422,29 @@ attribute:
Lex->charset=$2;
}
}
| IDENT_sys equal TEXT_STRING_sys
{
new (YYTHD->mem_root)
engine_option_value($1, $3, true, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
new (YYTHD->mem_root)
engine_option_value($1, $3, false, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ulonglong_num
{
new (YYTHD->mem_root)
engine_option_value($1, $3, &Lex->option_list,
&Lex->option_list_last, YYTHD->mem_root);
}
| IDENT_sys equal DEFAULT
{
new (YYTHD->mem_root)
engine_option_value($1, &Lex->option_list, &Lex->option_list_last);
}
;
now_or_signed_literal:
@ -5672,6 +5734,29 @@ key_using_alg:
all_key_opt:
KEY_BLOCK_SIZE opt_equal ulong_num
{ Lex->key_create_info.block_size= $3; }
| IDENT_sys equal TEXT_STRING_sys
{
new (YYTHD->mem_root)
engine_option_value($1, $3, true, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ident
{
new (YYTHD->mem_root)
engine_option_value($1, $3, false, &Lex->option_list,
&Lex->option_list_last);
}
| IDENT_sys equal ulonglong_num
{
new (YYTHD->mem_root)
engine_option_value($1, $3, &Lex->option_list,
&Lex->option_list_last, YYTHD->mem_root);
}
| IDENT_sys equal DEFAULT
{
new (YYTHD->mem_root)
engine_option_value($1, &Lex->option_list, &Lex->option_list_last);
}
;
normal_key_opt:
@ -6161,6 +6246,7 @@ alter_list_item:
LEX *lex=Lex;
lex->change= $3.str;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
lex->option_list= NULL;
}
field_spec opt_place
| MODIFY_SYM opt_column field_ident
@ -6172,6 +6258,7 @@ alter_list_item:
lex->charset= NULL;
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
lex->vcol_info= 0;
lex->option_list= NULL;
}
field_def
{
@ -6183,7 +6270,7 @@ alter_list_item:
&lex->comment,
$3.str, &lex->interval_list, lex->charset,
lex->uint_geom_type,
lex->vcol_info))
lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
}
opt_place
@ -6290,8 +6377,7 @@ alter_list_item:
}
| create_table_options_space_separated
{
LEX *lex=Lex;
lex->alter_info.flags|= ALTER_OPTIONS;
Lex->alter_info.flags|= ALTER_OPTIONS;
}
| FORCE_SYM
{

View file

@ -68,6 +68,7 @@ typedef struct st_key_part_info { /* Info about a key part */
uint8 null_bit; /* Position to null_bit */
} KEY_PART_INFO ;
class engine_option_value;
typedef struct st_key {
uint key_length; /* Tot length of key */
@ -101,6 +102,9 @@ typedef struct st_key {
int bdb_return_if_eq;
} handler;
struct st_table *table;
/** reference to the list of options or NULL */
engine_option_value *option_list;
void *option_struct; /* structure with parsed options */
} KEY;

View file

@ -18,6 +18,7 @@
#include "mysql_priv.h"
#include "sql_trigger.h"
#include "create_options.h"
#include <m_ctype.h>
#include "my_md5.h"
@ -667,12 +668,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
uint db_create_options, keys, key_parts, n_length;
uint key_info_length, com_length, null_bit_pos;
uint vcol_screen_length;
uint extra_rec_buf_length;
uint extra_rec_buf_length, options_len;
uint i,j;
bool use_hash;
char *keynames, *names, *comment_pos, *vcol_screen_pos;
uchar *record;
uchar *disk_buff, *strpos, *null_flags, *null_pos;
uchar *disk_buff, *strpos, *null_flags, *null_pos, *options;
uchar *buff= 0;
ulong pos, record_offset, *rec_per_key, rec_buff_length;
handler *handler_file= 0;
KEY *keyinfo;
@ -788,7 +790,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
for (i=0 ; i < keys ; i++, keyinfo++)
{
keyinfo->table= 0; // Updated in open_frm
if (new_frm_ver >= 3)
{
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
@ -858,15 +859,14 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if ((n_length= uint4korr(head+55)))
{
/* Read extra data segment */
uchar *buff, *next_chunk, *buff_end;
uchar *next_chunk, *buff_end;
DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
goto err;
if (my_pread(file, buff, n_length, record_offset + share->reclength,
MYF(MY_NABP)))
{
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
share->connect_string.length= uint2korr(buff);
if (!(share->connect_string.str= strmake_root(&share->mem_root,
@ -874,8 +874,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->connect_string.
length)))
{
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
next_chunk+= share->connect_string.length + 2;
buff_end= buff + n_length;
@ -895,8 +894,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
plugin_data(tmp_plugin, handlerton *)))
{
/* bad file, legacy_db_type did not match the name */
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
/*
tmp_plugin is locked with a local lock.
@ -925,8 +923,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
error= 8;
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
"--skip-partition");
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
plugin_unlock(NULL, share->db_plugin);
share->db_plugin= ha_lock_engine(NULL, partition_hton);
@ -940,8 +937,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* purecov: begin inspected */
error= 8;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
my_free(buff, MYF(0));
goto err;
goto free_and_err;
/* purecov: end */
}
next_chunk+= str_db_type_length + 2;
@ -957,16 +953,14 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
memdup_root(&share->mem_root, next_chunk + 4,
partition_info_len + 1)))
{
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
}
#else
if (partition_info_len)
{
DBUG_PRINT("info", ("WITH_PARTITION_STORAGE_ENGINE is not defined"));
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
#endif
next_chunk+= 5 + partition_info_len;
@ -1002,8 +996,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
DBUG_PRINT("error",
("fulltext key uses parser that is not defined in .frm"));
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
parser_name.str= (char*) next_chunk;
parser_name.length= strlen((char*) next_chunk);
@ -1013,12 +1006,20 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (! keyinfo->parser)
{
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), parser_name.str);
my_free(buff, MYF(0));
goto err;
goto free_and_err;
}
}
}
my_free(buff, MYF(0));
if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
{
/*
store options position, but skip till the time we will
know number of fields
*/
options_len= uint4korr(next_chunk);
options= next_chunk + 4;
next_chunk+= options_len + 4;
}
}
share->key_block_size= uint2korr(head+62);
@ -1028,21 +1029,21 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->rec_buff_length= rec_buff_length;
if (!(record= (uchar *) alloc_root(&share->mem_root,
rec_buff_length)))
goto err; /* purecov: inspected */
goto free_and_err; /* purecov: inspected */
share->default_values= record;
if (my_pread(file, record, (size_t) share->reclength,
record_offset, MYF(MY_NABP)))
goto err; /* purecov: inspected */
goto free_and_err; /* purecov: inspected */
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
if (my_read(file, head,288,MYF(MY_NABP)))
goto err;
goto free_and_err;
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
crypted->decode((char*) head+256,288-256);
if (sint2korr(head+284) != 0) // Should be 0
goto err; // Wrong password
goto free_and_err; // Wrong password
}
#endif
@ -1062,6 +1063,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
share->comment.length);
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, share->keys,n_length,int_length, com_length, vcol_screen_length));
if (!(field_ptr = (Field **)
alloc_root(&share->mem_root,
(uint) ((share->fields+1)*sizeof(Field*)+
@ -1070,14 +1073,14 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
keys+3)*sizeof(char *)+
(n_length+int_length+com_length+
vcol_screen_length)))))
goto err; /* purecov: inspected */
goto free_and_err; /* purecov: inspected */
share->field= field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length+
vcol_screen_length));
if (read_string(file,(uchar**) &disk_buff,read_length))
goto err; /* purecov: inspected */
goto free_and_err; /* purecov: inspected */
#ifdef HAVE_CRYPTED_FRM
if (crypted)
{
@ -1104,7 +1107,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
if (share->fieldnames.count != share->fields)
goto err;
goto free_and_err;
fix_type_pointers(&interval_array, share->intervals, interval_count,
&names);
@ -1118,7 +1121,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
uint count= (uint) (interval->count + 1) * sizeof(uint);
if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
count)))
goto err;
goto free_and_err;
for (count= 0; count < interval->count; count++)
{
char *val= (char*) interval->type_names[count];
@ -1134,7 +1137,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
share->db_type())))
goto err;
goto free_and_err;
record= share->default_values-1; /* Fieldstart = 1 */
if (share->null_field_first)
@ -1196,7 +1199,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
charset= &my_charset_bin;
#else
error= 4; // unsupported field type
goto err;
goto free_and_err;
#endif
}
else
@ -1207,7 +1210,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
error= 5; // Unknown or unavailable charset
errarg= (int) strpos[14];
goto err;
goto free_and_err;
}
}
@ -1247,7 +1250,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if ((uint)vcol_screen_pos[0] != 1)
{
error= 4;
goto err;
goto free_and_err;
}
field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
@ -1256,7 +1259,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
(char *)memdup_root(&share->mem_root,
vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE,
vcol_expr_length)))
goto err;
goto free_and_err;
vcol_info->expr_str.length= vcol_expr_length;
vcol_screen_pos+= vcol_info_length;
share->vfields++;
@ -1346,7 +1349,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (!reg_field) // Not supported field type
{
error= 4;
goto err; /* purecov: inspected */
goto free_and_err; /* purecov: inspected */
}
reg_field->field_index= i;
@ -1385,7 +1388,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
sent (OOM).
*/
error= 8;
goto err;
goto free_and_err;
}
}
if (!reg_field->stored_in_db)
@ -1462,7 +1465,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (!key_part->fieldnr)
{
error= 4; // Wrong file
goto err;
goto free_and_err;
}
field= key_part->field= share->field[key_part->fieldnr-1];
key_part->type= field->key_type();
@ -1627,6 +1630,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
null_length, 255);
}
if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS)
{
DBUG_ASSERT(options_len);
if (engine_table_options_frm_read(options, options_len, share) ||
parse_engine_table_options(thd, handler_file->ht, share))
goto free_and_err;
}
my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
if (share->found_next_number_field)
{
reg_field= *share->found_next_number_field;
@ -1685,6 +1697,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
#endif
DBUG_RETURN (0);
free_and_err:
my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
err:
share->error= error;
share->open_errno= my_errno;
@ -2883,6 +2897,7 @@ File create_frm(THD *thd, const char *name, const char *db,
ulong length;
uchar fill[IO_SIZE];
int create_flags= O_RDWR | O_TRUNC;
DBUG_ENTER("create_frm");
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
@ -2964,7 +2979,7 @@ File create_frm(THD *thd, const char *name, const char *db,
{
VOID(my_close(file,MYF(0)));
VOID(my_delete(name,MYF(0)));
return(-1);
DBUG_RETURN(-1);
}
}
}
@ -2975,7 +2990,7 @@ File create_frm(THD *thd, const char *name, const char *db,
else
my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
}
return (file);
DBUG_RETURN(file);
} /* create_frm */
@ -2994,6 +3009,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
create_info->comment= share->comment;
create_info->transactional= share->transactional;
create_info->page_checksum= share->page_checksum;
create_info->option_list= share->option_list;
DBUG_VOID_RETURN;
}

View file

@ -340,6 +340,8 @@ typedef struct st_table_share
#ifdef NOT_YET
struct st_table *open_tables; /* link to open tables */
#endif
engine_option_value *option_list; /* text options for table */
void *option_struct; /* structure with parsed options */
/* The following is copied to each TABLE on OPEN */
Field **field;

View file

@ -24,11 +24,15 @@
*/
#include "mysql_priv.h"
#include "create_options.h"
#include <m_ctype.h>
#include <assert.h>
#define FCOMP 17 /* Bytes for a packed field */
/* threshold for safe_alloca */
#define ALLOCA_THRESHOLD 2048
static uchar * pack_screens(List<Create_field> &create_fields,
uint *info_length, uint *screens, bool small_file);
static uint pack_keys(uchar *keybuff,uint key_count, KEY *key_info,
@ -107,6 +111,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
ulong key_buff_length;
File file;
ulong filepos, data_offset;
uint options_len;
uchar fileinfo[64],forminfo[288],*keybuff;
TYPELIB formnames;
uchar *screen_buff;
@ -183,6 +188,16 @@ bool mysql_create_frm(THD *thd, const char *file_name,
create_info->extra_size+= key_info[i].parser_name->length + 1;
}
options_len= engine_table_options_frm_length(create_info->option_list,
create_fields,
keys, key_info);
DBUG_PRINT("info", ("Options length: %u", options_len));
if (options_len)
{
create_info->table_options|= HA_OPTION_TEXT_CREATE_OPTIONS;
create_info->extra_size+= (options_len + 4);
}
if ((file=create_frm(thd, file_name, db, table, reclength, fileinfo,
create_info, keys)) < 0)
{
@ -294,6 +309,7 @@ bool mysql_create_frm(THD *thd, const char *file_name,
if (my_write(file, (uchar*) buff, 6, MYF_RW))
goto err;
}
for (i= 0; i < keys; i++)
{
if (key_info[i].parser_name)
@ -304,6 +320,24 @@ bool mysql_create_frm(THD *thd, const char *file_name,
}
}
if (options_len)
{
uchar *optbuff= (uchar *)my_safe_alloca(options_len + 4, ALLOCA_THRESHOLD);
my_bool error;
DBUG_PRINT("info", ("Create options length: %u", options_len));
if (!optbuff)
goto err;
int4store(optbuff, options_len);
engine_table_options_frm_image(optbuff + 4,
create_info->option_list,
create_fields,
keys, key_info);
error= my_write(file, optbuff, options_len + 4, MYF_RW);
my_safe_afree(optbuff, options_len + 4, ALLOCA_THRESHOLD);
if (error)
goto err;
}
VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0)));
if (my_write(file, forminfo, 288, MYF_RW) ||
my_write(file, screen_buff, info_length, MYF_RW) ||

View file

@ -113,6 +113,76 @@ static HASH example_open_tables;
/* The mutex used to init the hash; variable for example share methods */
pthread_mutex_t example_mutex;
/**
structure for CREATE TABLE options (table options)
These can be specified in the CREATE TABLE:
CREATE TABLE ( ... ) {...here...}
*/
struct example_table_options_struct
{
const char *strparam;
ulonglong ullparam;
uint enumparam;
bool boolparam;
};
/**
structure for CREATE TABLE options (field options)
These can be specified in the CREATE TABLE per field:
CREATE TABLE ( field ... {...here...}, ... )
*/
struct example_field_options_struct
{
const char *compex_param_to_parse_it_in_engine;
};
/* HA_TOPTION_* macros expect the structure called ha_table_option_struct */
#define ha_table_option_struct example_table_options_struct
ha_create_table_option example_table_option_list[]=
{
/*
one numeric option, with the default of UINT_MAX32, valid
range of values 0..UINT_MAX32, and a "block size" of 10
(any value must be divisible by 10).
*/
HA_TOPTION_ULL("ULL", ullparam, UINT_MAX32, 0, UINT_MAX32, 10),
/*
one option that takes an arbitrary string
*/
HA_TOPTION_STRING("STR", strparam),
/*
one enum option. a valid values are strings ONE and TWO.
A default value is 0, that is "one".
*/
HA_TOPTION_ENUM("one_or_two", enumparam, "one,two", 0),
/*
one boolean option, the valid values are YES/NO, ON/OFF, 1/0.
The default is 1, that is true, yes, on.
*/
HA_TOPTION_BOOL("YESNO", boolparam, 1),
HA_TOPTION_END
};
/* HA_FOPTION_* macros expect the structure called ha_field_option_struct */
#define ha_field_option_struct example_field_options_struct
ha_create_table_option example_field_option_list[]=
{
/*
If the engine wants something more complex than a string, number, enum,
or boolean - for example a list - it needs to specify the option
as a string and parse it internally.
*/
HA_FOPTION_STRING("COMPLEX", compex_param_to_parse_it_in_engine),
HA_FOPTION_END
};
/**
@brief
Function we use in the creation of our hash to get key.
@ -138,6 +208,8 @@ static int example_init_func(void *p)
example_hton->state= SHOW_OPTION_YES;
example_hton->create= example_create_handler;
example_hton->flags= HTON_CAN_RECREATE;
example_hton->table_options= example_table_option_list;
example_hton->field_options= example_field_option_list;
DBUG_RETURN(0);
}
@ -772,27 +844,6 @@ int ha_example::delete_table(const char *name)
}
/**
@brief
Renames a table from one name to another via an alter table call.
@details
If you do not implement this, the default rename_table() is called from
handler.cc and it will delete all files with the file extensions returned
by bas_ext().
Called from sql_table.cc by mysql_rename_table().
@see
mysql_rename_table() in sql_table.cc
*/
int ha_example::rename_table(const char * from, const char * to)
{
DBUG_ENTER("ha_example::rename_table ");
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
/**
@brief
Given a starting key and an ending key, estimate the number of rows that
@ -836,15 +887,105 @@ ha_rows ha_example::records_in_range(uint inx, key_range *min_key,
int ha_example::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
example_table_options_struct *options=
(example_table_options_struct *)table_arg->s->option_struct;
DBUG_ENTER("ha_example::create");
/*
This is not implemented but we want someone to be able to see that it
works.
This example shows how to support custom engine specific table and field
options.
*/
DBUG_ASSERT(options);
DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\
"boolparam: %u",
(options->strparam ? options->strparam : "<NULL>"),
options->ullparam, options->enumparam, options->boolparam));
for (Field **field= table_arg->s->field; *field; field++)
{
example_field_options_struct *field_options=
(example_field_options_struct *)(*field)->option_struct;
DBUG_ASSERT(field_options);
DBUG_PRINT("info", ("field: %s complex: '%-.64s'",
(*field)->field_name,
(field_options->compex_param_to_parse_it_in_engine ?
field_options->compex_param_to_parse_it_in_engine :
"<NULL>")));
}
DBUG_RETURN(0);
}
/**
check_if_incompatible_data() called if ALTER TABLE can't detect otherwise
if new and old definition are compatible
@details If there are no other explicit signs like changed number of
fields this function will be called by compare_tables()
(sql/sql_tables.cc) to decide should we rewrite whole table or only .frm
file.
*/
bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes)
{
example_table_options_struct *param_old, *param_new;
uint i;
DBUG_ENTER("ha_example::check_if_incompatible_data");
/*
This example shows how custom engine specific table and field
options can be accessed from this function to be compared.
*/
param_new= (example_table_options_struct *)info->option_struct;
DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u "
"boolparam: %u",
(param_new->strparam ? param_new->strparam : "<NULL>"),
param_new->ullparam, param_new->enumparam,
param_new->boolparam));
param_old= (example_table_options_struct *)table->s->option_struct;
DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u "
"boolparam: %u",
(param_old->strparam ? param_old->strparam : "<NULL>"),
param_old->ullparam, param_old->enumparam,
param_old->boolparam));
/*
check important parameters:
for this example engine, we'll assume that changing ullparam or
boolparam requires a table to be rebuilt, while changing strparam
or enumparam - does not.
*/
if (param_new->ullparam != param_old->ullparam ||
param_new->boolparam != param_old->boolparam)
DBUG_RETURN(COMPATIBLE_DATA_NO);
for (i= 0; i < table->s->fields; i++)
{
example_field_options_struct *f_old, *f_new;
f_old= (example_field_options_struct *)table->s->field[i]->option_struct;
DBUG_ASSERT(f_old);
DBUG_PRINT("info", ("old field: %u old complex: '%-.64s'", i,
(f_old->compex_param_to_parse_it_in_engine ?
f_old->compex_param_to_parse_it_in_engine :
"<NULL>")));
if (info->fileds_option_struct[i])
{
f_new= (example_field_options_struct *)info->fileds_option_struct[i];
DBUG_PRINT("info", ("old field: %u new complex: '%-.64s'", i,
(f_new->compex_param_to_parse_it_in_engine ?
f_new->compex_param_to_parse_it_in_engine :
"<NULL>")));
}
else
DBUG_PRINT("info", ("old field %i did not changed", i));
}
DBUG_RETURN(COMPATIBLE_DATA_YES);
}
struct st_mysql_storage_engine example_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };

View file

@ -243,9 +243,10 @@ public:
ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key);
int delete_table(const char *from);
int rename_table(const char * from, const char * to);
int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required
bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); ///< required

View file

@ -1623,7 +1623,7 @@ int xt_create_table_frm(handlerton *hton, THD* thd, const char *db, const char *
#endif
NULL /*default_value*/, NULL /*on_update_value*/, &comment, NULL /*change*/,
NULL /*interval_list*/, info->field_charset, 0 /*uint_geom_type*/,
NULL /*vcol_info*/))
NULL /*vcol_info*/, NULL /* create options */))
#endif
goto error;