diff options
-rw-r--r-- | mysql-test/r/sql_mode.result | 87 | ||||
-rw-r--r-- | mysql-test/t/sql_mode.test | 30 | ||||
-rw-r--r-- | sql/field.cc | 67 | ||||
-rw-r--r-- | sql/field.h | 3 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/mysqld.cc | 24 | ||||
-rw-r--r-- | sql/set_var.cc | 81 | ||||
-rw-r--r-- | sql/set_var.h | 19 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 168 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 6 |
16 files changed, 392 insertions, 119 deletions
diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result new file mode 100644 index 00000000000..eade1ca02ea --- /dev/null +++ b/mysql-test/r/sql_mode.result @@ -0,0 +1,87 @@ +drop table if exists t1; +CREATE TABLE `t1` ( +a int not null auto_increment, +`pseudo` varchar(35) character set latin2 NOT NULL default '', +`email` varchar(60) character set latin2 NOT NULL default '', +PRIMARY KEY (a), +UNIQUE KEY `email` USING BTREE (`email`) +) TYPE=HEAP CHARSET=latin1 ROW_FORMAT DYNAMIC; +set @@sql_mode=""; +show variables like 'sql_mode'; +Variable_name Value +sql_mode +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL auto_increment, + `pseudo` varchar(35) character set latin2 NOT NULL default '', + `email` varchar(60) character set latin2 NOT NULL default '', + PRIMARY KEY (`a`), + UNIQUE KEY `email` TYPE BTREE (`email`) +) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC +set @@sql_mode="ansi_quotes"; +show variables like 'sql_mode'; +Variable_name Value +sql_mode ANSI_QUOTES +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" int(11) NOT NULL auto_increment, + "pseudo" varchar(35) character set latin2 NOT NULL default '', + "email" varchar(60) character set latin2 NOT NULL default '', + PRIMARY KEY ("a"), + UNIQUE KEY "email" TYPE BTREE ("email") +) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC +set @@sql_mode="no_table_options"; +show variables like 'sql_mode'; +Variable_name Value +sql_mode NO_TABLE_OPTIONS +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL auto_increment, + `pseudo` varchar(35) character set latin2 NOT NULL default '', + `email` varchar(60) character set latin2 NOT NULL default '', + PRIMARY KEY (`a`), + UNIQUE KEY `email` TYPE BTREE (`email`) +) +set @@sql_mode="no_key_options"; +show variables like 'sql_mode'; +Variable_name Value +sql_mode NO_KEY_OPTIONS +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL auto_increment, + `pseudo` varchar(35) character set latin2 NOT NULL default '', + `email` varchar(60) character set latin2 NOT NULL default '', + PRIMARY KEY (`a`), + UNIQUE KEY `email` (`email`) +) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC +set @@sql_mode="no_field_options,mysql323,mysql40"; +show variables like 'sql_mode'; +Variable_name Value +sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL auto_increment, + `pseudo` varchar(35) NOT NULL default '', + `email` varchar(60) NOT NULL default '', + PRIMARY KEY (`a`), + UNIQUE KEY `email` (`email`) +) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC +set @@sql_mode="postgresql,oracle,mssql,db2,sapdb"; +show variables like 'sql_mode'; +Variable_name Value +sql_mode POSTGRESQL,ORACLE,MSSQL,DB2,SAPDB +show create table t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" int(11) NOT NULL, + "pseudo" varchar(35) NOT NULL default '', + "email" varchar(60) NOT NULL default '', + PRIMARY KEY ("a"), + UNIQUE KEY "email" ("email") +) +drop table t1; diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test new file mode 100644 index 00000000000..fd464f74de4 --- /dev/null +++ b/mysql-test/t/sql_mode.test @@ -0,0 +1,30 @@ +--disable_warnings +drop table if exists t1; +--enable_warnings + +CREATE TABLE `t1` ( + a int not null auto_increment, + `pseudo` varchar(35) character set latin2 NOT NULL default '', + `email` varchar(60) character set latin2 NOT NULL default '', + PRIMARY KEY (a), + UNIQUE KEY `email` USING BTREE (`email`) +) TYPE=HEAP CHARSET=latin1 ROW_FORMAT DYNAMIC; +set @@sql_mode=""; +show variables like 'sql_mode'; +show create table t1; +set @@sql_mode="ansi_quotes"; +show variables like 'sql_mode'; +show create table t1; +set @@sql_mode="no_table_options"; +show variables like 'sql_mode'; +show create table t1; +set @@sql_mode="no_key_options"; +show variables like 'sql_mode'; +show create table t1; +set @@sql_mode="no_field_options,mysql323,mysql40"; +show variables like 'sql_mode'; +show create table t1; +set @@sql_mode="postgresql,oracle,mssql,db2,sapdb"; +show variables like 'sql_mode'; +show create table t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index e789188e552..68717ee51a1 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -248,7 +248,15 @@ void Field_str::add_binary_or_charset(String &res) const { if (binary()) res.append(" binary"); - else if (field_charset != table->table_charset) + else if (field_charset != table->table_charset && + !(current_thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS) && + !(current_thd->variables.sql_mode & MODE_MYSQL323) && + !(current_thd->variables.sql_mode & MODE_MYSQL40) && + !(current_thd->variables.sql_mode & MODE_POSTGRESQL) && + !(current_thd->variables.sql_mode & MODE_ORACLE) && + !(current_thd->variables.sql_mode & MODE_MSSQL) && + !(current_thd->variables.sql_mode & MODE_DB2) && + !(current_thd->variables.sql_mode & MODE_SAPDB)) { res.append(" character set "); res.append(field_charset->csname); @@ -5037,38 +5045,52 @@ void Field_enum::sql_type(String &res) const } -/**************************************************************************** -** set type. -** This is a string which can have a collection of different values. -** Each string value is separated with a ','. -** For example "One,two,five" -** If one uses this string in a number context one gets the bits as a longlong -** number. -****************************************************************************/ +/* + set type. + This is a string which can have a collection of different values. + Each string value is separated with a ','. + For example "One,two,five" + If one uses this string in a number context one gets the bits as a longlong + number. + + If there was a value in string that wasn't in set, the 'err_pos' points to + the last invalid value found. 'err_len' will be set to length of the + error string. +*/ -ulonglong find_set(TYPELIB *lib,const char *x,uint length) +ulonglong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, + uint *err_len) { - const char *end=x+length; + const char *end= x + length; + *err_pos= 0; // No error yet while (end > x && my_isspace(system_charset_info, end[-1])) end--; - ulonglong found=0; + *err_len= 0; + ulonglong found= 0; if (x != end) { - const char *start=x; + const char *start= x; bool error= 0; for (;;) { - const char *pos=start; - for (; pos != end && *pos != field_separator ; pos++) ; - uint find=find_enum(lib,start,(uint) (pos-start)); + const char *pos= start; + uint var_len; + + for (; pos != end && *pos != field_separator; pos++) ; + var_len= (uint) (pos - start); + uint find= find_enum(lib, start, var_len); if (!find) - error=1; + { + *err_pos= (char*) start; + *err_len= var_len; + error= 1; + } else - found|= ((longlong) 1 << (find-1)); + found|= ((longlong) 1 << (find - 1)); if (pos == end) - break; - start=pos+1; + break; + start= pos + 1; } if (error) current_thd->cuted_fields++; @@ -5080,7 +5102,10 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length) int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) { int error= 0; - ulonglong tmp=find_set(typelib,from,length); + char *not_used; + uint not_used2; + + ulonglong tmp= find_set(typelib, from, length, ¬_used, ¬_used2); if (!tmp && length && length < 22) { /* This is for reading numbers with LOAD DATA INFILE */ diff --git a/sql/field.h b/sql/field.h index 06a9b534b16..af479c81b40 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1095,7 +1095,8 @@ uint32 calc_pack_length(enum_field_types type,uint32 length); bool set_field_to_null(Field *field); bool set_field_to_null_with_conversions(Field *field, bool no_conversions); uint find_enum(TYPELIB *typelib,const char *x, uint length); -ulonglong find_set(TYPELIB *typelib,const char *x, uint length); +ulonglong find_set(TYPELIB *typelib,const char *x, uint length, + char **err_pos, uint *err_len); bool test_if_int(const char *str, int length, const char *int_end, CHARSET_INFO *cs); diff --git a/sql/item_func.cc b/sql/item_func.cc index 62cf4c0d291..d489ff1055d 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -394,7 +394,7 @@ void Item_func_minus::fix_length_and_dec() { Item_num_op::fix_length_and_dec(); if (unsigned_flag && - (current_thd->sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) + (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) unsigned_flag=0; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index cdc668d9b28..fc34cce8882 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -209,6 +209,11 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define MODE_MSSQL 512 #define MODE_DB2 1024 #define MODE_SAPDB 2048 +#define MODE_NO_KEY_OPTIONS 4096 +#define MODE_NO_TABLE_OPTIONS 8192 +#define MODE_NO_FIELD_OPTIONS 16384 +#define MODE_MYSQL323 32768 +#define MODE_MYSQL40 65536 #define RAID_BLOCK_SIZE 1024 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 27c7fb369a1..18da509529b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -424,12 +424,12 @@ double log_10[32]; /* 10 potences */ I_List<THD> threads,thread_cache; time_t start_time; -ulong opt_sql_mode = 0L; const char *sql_mode_names[] = { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "SERIALIZE", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", - "POSTGRESQL", "ORACLE", "MSSQL", "SAPDB", + "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "SAPDB", "NO_KEY_OPTIONS", + "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", NullS }; TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"", @@ -4301,9 +4301,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_endinfo=1; /* unireg: memory allocation */ break; case 'a': - opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | - MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE | - MODE_ONLY_FULL_GROUP_BY); + global_system_variables.sql_mode= + (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | + MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE | + MODE_ONLY_FULL_GROUP_BY); global_system_variables.tx_isolation= ISO_SERIALIZABLE; break; case 'b': @@ -4730,16 +4731,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } case OPT_SQL_MODE: { - sql_mode_str = argument; - if ((opt_sql_mode = - find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0) + sql_mode_str= argument; + if ((global_system_variables.sql_mode= + find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0) { fprintf(stderr, "Unknown option to sql-mode: %s\n", argument); exit(1); } - global_system_variables.tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ? - ISO_SERIALIZABLE : - ISO_REPEATABLE_READ); + global_system_variables.tx_isolation= + ((global_system_variables.sql_mode & MODE_SERIALIZABLE) ? + ISO_SERIALIZABLE : + ISO_REPEATABLE_READ); break; } case OPT_MASTER_PASSWORD: diff --git a/sql/set_var.cc b/sql/set_var.cc index fc268d314ba..79e9f67e905 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -215,8 +215,10 @@ sys_var_long_ptr sys_slow_launch_time("slow_launch_time", &slow_launch_time); sys_var_thd_ulong sys_sort_buffer("sort_buffer_size", &SV::sortbuff_size); -sys_var_thd_enum sys_table_type("table_type", &SV::table_type, - &ha_table_typelib); +sys_var_thd_sql_mode sys_sql_mode("sql_mode", + &SV::sql_mode); +sys_var_thd_enum sys_table_type("table_type", &SV::table_type, + &ha_table_typelib); sys_var_long_ptr sys_table_cache_size("table_cache", &table_cache_size); sys_var_long_ptr sys_thread_cache_size("thread_cache_size", @@ -391,6 +393,7 @@ sys_var *sys_variables[]= &sys_sql_big_tables, &sys_sql_low_priority_updates, &sys_sql_max_join_size, + &sys_sql_mode, &sys_sql_warnings, &sys_table_cache_size, &sys_table_type, @@ -541,7 +544,7 @@ struct show_var_st init_vars[]= { {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR}, #endif {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS}, - {"sql_mode", (char*) &opt_sql_mode, SHOW_LONG}, + {sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS}, {"table_cache", (char*) &table_cache_size, SHOW_LONG}, {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS}, {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS}, @@ -923,6 +926,44 @@ err: return 1; } + + +bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) +{ + char buff[80], *value, *error= 0; + uint error_len= 0; + String str(buff, sizeof(buff), system_charset_info), *res; + + if (var->value->result_type() == STRING_RESULT) + { + if (!(res= var->value->val_str(&str))) + goto err; + (long) var->save_result.ulong_value= (ulong) + find_set(enum_names, res->c_ptr(), res->length(), &error, &error_len); + if (error_len) + { + strmake(buff, error, min(sizeof(buff), error_len)); + goto err; + } + } + else + { + ulonglong tmp= var->value->val_int(); + if (tmp >= enum_names->count) + { + llstr(tmp, buff); + goto err; + } + var->save_result.ulong_value= (ulong) tmp; // Save for update + } + return 0; + +err: + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff); + return 1; +} + + /* Return an Item for a variable. Used with @@[global.]variable_name @@ -999,6 +1040,40 @@ byte *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type) } +byte *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type) +{ + ulong val; + char buff[256]; + String tmp(buff, sizeof(buff), default_charset_info); + my_bool found= 0; + + tmp.length(0); + val= ((type == OPT_GLOBAL) ? global_system_variables.*offset : + thd->variables.*offset); + for (uint i= 0; val; val>>= 1, i++) + { + if (val & 1) + { + tmp.append(enum_names->type_names[i]); + tmp.append(','); + } + } + if (tmp.length()) + tmp.length(tmp.length() - 1); + return (byte*) thd->strdup(tmp.c_ptr()); +} + + +void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.*offset= 0; + else + thd->variables.*offset= global_system_variables.*offset; +} + + + bool sys_var_thd_bit::update(THD *thd, set_var *var) { int res= (*update_func)(thd, var); diff --git a/sql/set_var.h b/sql/set_var.h index 6f257e1ace3..5d7463d9fa8 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -28,7 +28,7 @@ class sys_var; class set_var; typedef struct system_variables SV; -extern TYPELIB bool_typelib, delay_key_write_typelib; +extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib; enum enum_var_type { @@ -56,6 +56,7 @@ public: virtual ~sys_var() {} virtual bool check(THD *thd, set_var *var) { return 0; } bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names); + bool check_set(THD *thd, set_var *var, TYPELIB *enum_names); virtual bool update(THD *thd, set_var *var)=0; virtual void set_default(THD *thd, enum_var_type type) {} virtual SHOW_TYPE type() { return SHOW_UNDEF; } @@ -273,6 +274,7 @@ public: class sys_var_thd_enum :public sys_var_thd { +protected: ulong SV::*offset; TYPELIB *enum_names; public: @@ -297,6 +299,21 @@ public: }; +class sys_var_thd_sql_mode :public sys_var_thd_enum +{ +public: + sys_var_thd_sql_mode(const char *name_arg, ulong SV::*offset_arg) + :sys_var_thd_enum(name_arg, offset_arg, &sql_mode_typelib) + {} + bool check(THD *thd, set_var *var) + { + return check_set(thd, var, enum_names); + } + void set_default(THD *thd, enum_var_type type); + byte *value_ptr(THD *thd, enum_var_type type); +}; + + class sys_var_thd_bit :public sys_var_thd { sys_update_func update_func; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4416f5259bd..5734b340744 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -193,7 +193,6 @@ void THD::init(void) pthread_mutex_unlock(&LOCK_global_system_variables); server_status= SERVER_STATUS_AUTOCOMMIT; options= thd_startup_options; - sql_mode=(uint) opt_sql_mode; open_options=ha_open_options; update_lock_default= (variables.low_priority_updates ? TL_WRITE_LOW_PRIORITY : diff --git a/sql/sql_class.h b/sql/sql_class.h index 253ec3d2918..227d541807a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -369,6 +369,7 @@ struct system_variables ulong table_type; ulong tmp_table_size; ulong tx_isolation; + ulong sql_mode; /* In slave thread we need to know in behalf of which @@ -431,7 +432,6 @@ public: uint client_capabilities; /* What the client supports */ /* Determines if which non-standard SQL behaviour should be enabled */ - uint sql_mode; ulong max_client_packet_length; ulong master_access; /* Global privileges from mysql.user */ ulong db_access; /* Privileges for current db */ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b656f698e89..1a33ac0760b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -122,7 +122,7 @@ void lex_init(void) state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT; state_map[(uchar)'@']= (uchar) STATE_USER_END; state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER; - if (opt_sql_mode & MODE_ANSI_QUOTES) + if (global_system_variables.sql_mode & MODE_ANSI_QUOTES) { state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER; } @@ -167,7 +167,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->convert_set= (lex->thd= thd)->variables.convert_set; lex->thd_charset= lex->thd->variables.thd_charset; lex->yacc_yyss=lex->yacc_yyvs=0; - lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); + lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->slave_thd_opt=0; lex->sql_command=SQLCOM_END; lex->safe_to_cache_query= 1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 81fb5a6d12c..1e2ce9e9a86 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -588,7 +588,7 @@ check_connections(THD *thd) thd->client_capabilities=uint2korr(net->read_pos); if (thd->client_capabilities & CLIENT_IGNORE_SPACE) - thd->sql_mode|= MODE_IGNORE_SPACE; + thd->variables.sql_mode|= MODE_IGNORE_SPACE; #ifdef HAVE_OPENSSL DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities)); if (thd->client_capabilities & CLIENT_SSL) @@ -3458,10 +3458,14 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); if (default_value) { + char *not_used; + uint not_used2; + thd->cuted_fields=0; String str,*res; res=default_value->val_str(&str); - (void) find_set(interval,res->ptr(),res->length()); + (void) find_set(interval, res->ptr(), res->length(), ¬_used, + ¬_used2); if (thd->cuted_fields) { net_printf(thd,ER_INVALID_DEFAULT,field_name); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index aab8d883204..5912f3021dc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6947,7 +6947,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields, if (!order) return 0; /* Everything is ok */ - if (thd->sql_mode & MODE_ONLY_FULL_GROUP_BY) + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) { Item *item; List_iterator<Item> li(fields); @@ -6969,7 +6969,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields, return 1; } } - if (thd->sql_mode & MODE_ONLY_FULL_GROUP_BY) + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) { /* Don't allow one to use fields that is not used in GROUP BY */ Item *item; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 281fa92de6a..451a0956cf8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1001,11 +1001,22 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) static void append_identifier(THD *thd, String *packet, const char *name) { + char qtype; + if ((thd->variables.sql_mode & MODE_ANSI_QUOTES) || + (thd->variables.sql_mode & MODE_POSTGRESQL) || + (thd->variables.sql_mode & MODE_ORACLE) || + (thd->variables.sql_mode & MODE_MSSQL) || + (thd->variables.sql_mode & MODE_DB2) || + (thd->variables.sql_mode & MODE_SAPDB)) + qtype= '\"'; + else + qtype= '`'; + if (thd->options & OPTION_QUOTE_SHOW_CREATE) { - packet->append("`", 1); + packet->append(&qtype, 1); packet->append(name); - packet->append("`", 1); + packet->append(&qtype, 1); } else { @@ -1017,6 +1028,16 @@ append_identifier(THD *thd, String *packet, const char *name) static int store_create_info(THD *thd, TABLE *table, String *packet) { + my_bool foreign_db_mode= ((thd->variables.sql_mode & MODE_POSTGRESQL) || + (thd->variables.sql_mode & MODE_ORACLE) || + (thd->variables.sql_mode & MODE_MSSQL) || + (thd->variables.sql_mode & MODE_DB2) || + (thd->variables.sql_mode & MODE_SAPDB)); + my_bool limited_mysql_mode= ((thd->variables.sql_mode & + MODE_NO_FIELD_OPTIONS) || + (thd->variables.sql_mode & MODE_MYSQL323) || + (thd->variables.sql_mode & MODE_MYSQL40)); + DBUG_ENTER("store_create_info"); DBUG_PRINT("enter",("table: %s",table->real_name)); @@ -1057,9 +1078,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) For string types dump collation name only if collation is not primary for the given charset */ - if (!field->binary() && !(field->charset()->state & MY_CS_PRIMARY)) + if (!field->binary() && !(field->charset()->state & MY_CS_PRIMARY) && + !limited_mysql_mode && !foreign_db_mode) { - packet->append(" collate ",9); + packet->append(" collate ", 9); packet->append(field->charset()->name); } if (flags & NOT_NULL_FLAG) @@ -1083,7 +1105,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(tmp,0); } - if (field->unireg_check == Field::NEXT_NUMBER) + if (field->unireg_check == Field::NEXT_NUMBER && !foreign_db_mode) packet->append(" auto_increment", 15 ); if (field->comment.length) @@ -1117,17 +1139,20 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append("KEY ", 4); if (!found_primary) - append_identifier(thd,packet,key_info->name); - - if (table->db_type == DB_TYPE_HEAP && - key_info->algorithm == HA_KEY_ALG_BTREE) - packet->append(" USING BTREE", 12); - - // +BAR: send USING only in non-default case: non-spatial rtree - if ((key_info->algorithm == HA_KEY_ALG_RTREE) && - !(key_info->flags & HA_SPATIAL)) - packet->append(" USING RTREE",12); + append_identifier(thd, packet, key_info->name); + if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) && + !limited_mysql_mode && !foreign_db_mode) + { + if (table->db_type == DB_TYPE_HEAP && + key_info->algorithm == HA_KEY_ALG_BTREE) + packet->append(" TYPE BTREE", 11); + + // +BAR: send USING only in non-default case: non-spatial rtree + if ((key_info->algorithm == HA_KEY_ALG_RTREE) && + !(key_info->flags & HA_SPATIAL)) + packet->append(" TYPE RTREE", 11); + } packet->append(" (", 2); for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) @@ -1166,67 +1191,70 @@ store_create_info(THD *thd, TABLE *table, String *packet) } packet->append("\n)", 2); - packet->append(" TYPE=", 6); - packet->append(file->table_type()); - char buff[128]; - char* p; - - if (table->table_charset) + if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode) { - packet->append(" CHARSET="); - packet->append(table->table_charset->csname); - if (!(table->table_charset->state & MY_CS_PRIMARY)) + packet->append(" TYPE=", 6); + packet->append(file->table_type()); + char buff[128]; + char* p; + + if (table->table_charset) { - packet->append(" COLLATE="); - packet->append(table->table_charset->name); + packet->append(" CHARSET="); + packet->append(table->table_charset->csname); + if (!(table->table_charset->state & MY_CS_PRIMARY)) + { + packet->append(" COLLATE="); + packet->append(table->table_charset->name); + } } - } - if (table->min_rows) - { - packet->append(" MIN_ROWS="); - p = longlong10_to_str(table->min_rows, buff, 10); - packet->append(buff, (uint) (p - buff)); - } + if (table->min_rows) + { + packet->append(" MIN_ROWS="); + p = longlong10_to_str(table->min_rows, buff, 10); + packet->append(buff, (uint) (p - buff)); + } - if (table->max_rows) - { - packet->append(" MAX_ROWS="); - p = longlong10_to_str(table->max_rows, buff, 10); - packet->append(buff, (uint) (p - buff)); - } - if (table->avg_row_length) - { - packet->append(" AVG_ROW_LENGTH="); - p=longlong10_to_str(table->avg_row_length, buff,10); - packet->append(buff, (uint) (p - buff)); - } + if (table->max_rows) + { + packet->append(" MAX_ROWS="); + p = longlong10_to_str(table->max_rows, buff, 10); + packet->append(buff, (uint) (p - buff)); + } + if (table->avg_row_length) + { + packet->append(" AVG_ROW_LENGTH="); + p=longlong10_to_str(table->avg_row_length, buff,10); + packet->append(buff, (uint) (p - buff)); + } - if (table->db_create_options & HA_OPTION_PACK_KEYS) - packet->append(" PACK_KEYS=1", 12); - if (table->db_create_options & HA_OPTION_NO_PACK_KEYS) - packet->append(" PACK_KEYS=0", 12); - if (table->db_create_options & HA_OPTION_CHECKSUM) - packet->append(" CHECKSUM=1", 11); - if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) - packet->append(" DELAY_KEY_WRITE=1",18); - if (table->row_type != ROW_TYPE_DEFAULT) - { - packet->append(" ROW_FORMAT=",12); - packet->append(ha_row_type[(uint) table->row_type]); - } - table->file->append_create_info(packet); - if (table->comment && table->comment[0]) - { - packet->append(" COMMENT=", 9); - append_unescaped(packet, table->comment, strlen(table->comment)); - } - if (file->raid_type) - { - char buff[100]; - sprintf(buff," RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld", - my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE); - packet->append(buff); + if (table->db_create_options & HA_OPTION_PACK_KEYS) + packet->append(" PACK_KEYS=1", 12); + if (table->db_create_options & HA_OPTION_NO_PACK_KEYS) + packet->append(" PACK_KEYS=0", 12); + if (table->db_create_options & HA_OPTION_CHECKSUM) + packet->append(" CHECKSUM=1", 11); + if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) + packet->append(" DELAY_KEY_WRITE=1",18); + if (table->row_type != ROW_TYPE_DEFAULT) + { + packet->append(" ROW_FORMAT=",12); + packet->append(ha_row_type[(uint) table->row_type]); + } + table->file->append_create_info(packet); + if (table->comment && table->comment[0]) + { + packet->append(" COMMENT=", 9); + append_unescaped(packet, table->comment, strlen(table->comment)); + } + if (file->raid_type) + { + char buff[100]; + sprintf(buff," RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld", + my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE); + packet->append(buff); + } } DBUG_RETURN(0); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 318d563b88a..5964ce68559 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -45,7 +45,7 @@ int yylex(void *yylval, void *yythd); inline Item *or_or_concat(THD *thd, Item* A, Item* B) { - return (thd->sql_mode & MODE_PIPES_AS_CONCAT ? + return (thd->variables.sql_mode & MODE_PIPES_AS_CONCAT ? (Item*) new Item_func_concat(A,B) : (Item*) new Item_cond_or(A,B)); } @@ -1129,7 +1129,7 @@ type: | TIME_SYM { $$=FIELD_TYPE_TIME; } | TIMESTAMP { - if (YYTHD->sql_mode & MODE_SAPDB) + if (YYTHD->variables.sql_mode & MODE_SAPDB) $$=FIELD_TYPE_DATETIME; else $$=FIELD_TYPE_TIMESTAMP; @@ -1200,7 +1200,7 @@ int_type: | BIGINT { $$=FIELD_TYPE_LONGLONG; }; real_type: - REAL { $$= YYTHD->sql_mode & MODE_REAL_AS_FLOAT ? + REAL { $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; |