Added support sql_mode, which can be used to produce various outputs

of SHOW CREATE TABLE 'name'. Depending on the mode, the output can
be compatible with various databases, including earlier versions of
MySQL
.
parent 5743f94b
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;
--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;
...@@ -248,7 +248,15 @@ void Field_str::add_binary_or_charset(String &res) const ...@@ -248,7 +248,15 @@ void Field_str::add_binary_or_charset(String &res) const
{ {
if (binary()) if (binary())
res.append(" 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(" character set ");
res.append(field_charset->csname); res.append(field_charset->csname);
...@@ -5037,38 +5045,52 @@ void Field_enum::sql_type(String &res) const ...@@ -5037,38 +5045,52 @@ void Field_enum::sql_type(String &res) const
} }
/**************************************************************************** /*
** set type. set type.
** This is a string which can have a collection of different values. This is a string which can have a collection of different values.
** Each string value is separated with a ','. Each string value is separated with a ','.
** For example "One,two,five" For example "One,two,five"
** If one uses this string in a number context one gets the bits as a longlong If one uses this string in a number context one gets the bits as a longlong
** number. 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])) while (end > x && my_isspace(system_charset_info, end[-1]))
end--; end--;
ulonglong found=0; *err_len= 0;
ulonglong found= 0;
if (x != end) if (x != end)
{ {
const char *start=x; const char *start= x;
bool error= 0; bool error= 0;
for (;;) for (;;)
{ {
const char *pos=start; const char *pos= start;
for (; pos != end && *pos != field_separator ; pos++) ; uint var_len;
uint find=find_enum(lib,start,(uint) (pos-start));
for (; pos != end && *pos != field_separator; pos++) ;
var_len= (uint) (pos - start);
uint find= find_enum(lib, start, var_len);
if (!find) if (!find)
error=1; {
*err_pos= (char*) start;
*err_len= var_len;
error= 1;
}
else else
found|= ((longlong) 1 << (find-1)); found|= ((longlong) 1 << (find - 1));
if (pos == end) if (pos == end)
break; break;
start=pos+1; start= pos + 1;
} }
if (error) if (error)
current_thd->cuted_fields++; current_thd->cuted_fields++;
...@@ -5080,7 +5102,10 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length) ...@@ -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 Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
{ {
int error= 0; int error= 0;
ulonglong tmp=find_set(typelib,from,length); char *not_used;
uint not_used2;
ulonglong tmp= find_set(typelib, from, length, &not_used, &not_used2);
if (!tmp && length && length < 22) if (!tmp && length && length < 22)
{ {
/* This is for reading numbers with LOAD DATA INFILE */ /* This is for reading numbers with LOAD DATA INFILE */
......
...@@ -1095,7 +1095,8 @@ uint32 calc_pack_length(enum_field_types type,uint32 length); ...@@ -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(Field *field);
bool set_field_to_null_with_conversions(Field *field, bool no_conversions); bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
uint find_enum(TYPELIB *typelib,const char *x, uint length); 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, bool test_if_int(const char *str, int length, const char *int_end,
CHARSET_INFO *cs); CHARSET_INFO *cs);
......
...@@ -394,7 +394,7 @@ void Item_func_minus::fix_length_and_dec() ...@@ -394,7 +394,7 @@ void Item_func_minus::fix_length_and_dec()
{ {
Item_num_op::fix_length_and_dec(); Item_num_op::fix_length_and_dec();
if (unsigned_flag && if (unsigned_flag &&
(current_thd->sql_mode & MODE_NO_UNSIGNED_SUBTRACTION)) (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
unsigned_flag=0; unsigned_flag=0;
} }
......
...@@ -209,6 +209,11 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); ...@@ -209,6 +209,11 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
#define MODE_MSSQL 512 #define MODE_MSSQL 512
#define MODE_DB2 1024 #define MODE_DB2 1024
#define MODE_SAPDB 2048 #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 #define RAID_BLOCK_SIZE 1024
......
...@@ -424,12 +424,12 @@ double log_10[32]; /* 10 potences */ ...@@ -424,12 +424,12 @@ double log_10[32]; /* 10 potences */
I_List<THD> threads,thread_cache; I_List<THD> threads,thread_cache;
time_t start_time; time_t start_time;
ulong opt_sql_mode = 0L;
const char *sql_mode_names[] = const char *sql_mode_names[] =
{ {
"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
"SERIALIZE", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION", "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 NullS
}; };
TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"", TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"",
...@@ -4301,7 +4301,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -4301,7 +4301,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_endinfo=1; /* unireg: memory allocation */ opt_endinfo=1; /* unireg: memory allocation */
break; break;
case 'a': case 'a':
opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | global_system_variables.sql_mode=
(MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT |
MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE |
MODE_ONLY_FULL_GROUP_BY); MODE_ONLY_FULL_GROUP_BY);
global_system_variables.tx_isolation= ISO_SERIALIZABLE; global_system_variables.tx_isolation= ISO_SERIALIZABLE;
...@@ -4730,14 +4731,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -4730,14 +4731,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
} }
case OPT_SQL_MODE: case OPT_SQL_MODE:
{ {
sql_mode_str = argument; sql_mode_str= argument;
if ((opt_sql_mode = if ((global_system_variables.sql_mode=
find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0) find_bit_type(argument, &sql_mode_typelib)) == ~(ulong) 0)
{ {
fprintf(stderr, "Unknown option to sql-mode: %s\n", argument); fprintf(stderr, "Unknown option to sql-mode: %s\n", argument);
exit(1); exit(1);
} }
global_system_variables.tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ? global_system_variables.tx_isolation=
((global_system_variables.sql_mode & MODE_SERIALIZABLE) ?
ISO_SERIALIZABLE : ISO_SERIALIZABLE :
ISO_REPEATABLE_READ); ISO_REPEATABLE_READ);
break; break;
......
...@@ -215,6 +215,8 @@ sys_var_long_ptr sys_slow_launch_time("slow_launch_time", ...@@ -215,6 +215,8 @@ sys_var_long_ptr sys_slow_launch_time("slow_launch_time",
&slow_launch_time); &slow_launch_time);
sys_var_thd_ulong sys_sort_buffer("sort_buffer_size", sys_var_thd_ulong sys_sort_buffer("sort_buffer_size",
&SV::sortbuff_size); &SV::sortbuff_size);
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, sys_var_thd_enum sys_table_type("table_type", &SV::table_type,
&ha_table_typelib); &ha_table_typelib);
sys_var_long_ptr sys_table_cache_size("table_cache", sys_var_long_ptr sys_table_cache_size("table_cache",
...@@ -391,6 +393,7 @@ sys_var *sys_variables[]= ...@@ -391,6 +393,7 @@ sys_var *sys_variables[]=
&sys_sql_big_tables, &sys_sql_big_tables,
&sys_sql_low_priority_updates, &sys_sql_low_priority_updates,
&sys_sql_max_join_size, &sys_sql_max_join_size,
&sys_sql_mode,
&sys_sql_warnings, &sys_sql_warnings,
&sys_table_cache_size, &sys_table_cache_size,
&sys_table_type, &sys_table_type,
...@@ -541,7 +544,7 @@ struct show_var_st init_vars[]= { ...@@ -541,7 +544,7 @@ struct show_var_st init_vars[]= {
{"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR}, {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR},
#endif #endif
{sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS}, {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}, {"table_cache", (char*) &table_cache_size, SHOW_LONG},
{sys_table_type.name, (char*) &sys_table_type, SHOW_SYS}, {sys_table_type.name, (char*) &sys_table_type, SHOW_SYS},
{sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS}, {sys_thread_cache_size.name,(char*) &sys_thread_cache_size, SHOW_SYS},
...@@ -923,6 +926,44 @@ err: ...@@ -923,6 +926,44 @@ err:
return 1; 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 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) ...@@ -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) bool sys_var_thd_bit::update(THD *thd, set_var *var)
{ {
int res= (*update_func)(thd, var); int res= (*update_func)(thd, var);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
class sys_var; class sys_var;
class set_var; class set_var;
typedef struct system_variables SV; 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 enum enum_var_type
{ {
...@@ -56,6 +56,7 @@ public: ...@@ -56,6 +56,7 @@ public:
virtual ~sys_var() {} virtual ~sys_var() {}
virtual bool check(THD *thd, set_var *var) { return 0; } virtual bool check(THD *thd, set_var *var) { return 0; }
bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names); 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 bool update(THD *thd, set_var *var)=0;
virtual void set_default(THD *thd, enum_var_type type) {} virtual void set_default(THD *thd, enum_var_type type) {}
virtual SHOW_TYPE type() { return SHOW_UNDEF; } virtual SHOW_TYPE type() { return SHOW_UNDEF; }
...@@ -273,6 +274,7 @@ public: ...@@ -273,6 +274,7 @@ public:
class sys_var_thd_enum :public sys_var_thd class sys_var_thd_enum :public sys_var_thd
{ {
protected:
ulong SV::*offset; ulong SV::*offset;
TYPELIB *enum_names; TYPELIB *enum_names;
public: public:
...@@ -297,6 +299,21 @@ 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 class sys_var_thd_bit :public sys_var_thd
{ {
sys_update_func update_func; sys_update_func update_func;
......
...@@ -193,7 +193,6 @@ void THD::init(void) ...@@ -193,7 +193,6 @@ void THD::init(void)
pthread_mutex_unlock(&LOCK_global_system_variables); pthread_mutex_unlock(&LOCK_global_system_variables);
server_status= SERVER_STATUS_AUTOCOMMIT; server_status= SERVER_STATUS_AUTOCOMMIT;
options= thd_startup_options; options= thd_startup_options;
sql_mode=(uint) opt_sql_mode;
open_options=ha_open_options; open_options=ha_open_options;
update_lock_default= (variables.low_priority_updates ? update_lock_default= (variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY : TL_WRITE_LOW_PRIORITY :
......
...@@ -369,6 +369,7 @@ struct system_variables ...@@ -369,6 +369,7 @@ struct system_variables
ulong table_type; ulong table_type;
ulong tmp_table_size; ulong tmp_table_size;
ulong tx_isolation; ulong tx_isolation;
ulong sql_mode;
/* /*
In slave thread we need to know in behalf of which In slave thread we need to know in behalf of which
...@@ -431,7 +432,6 @@ public: ...@@ -431,7 +432,6 @@ public:
uint client_capabilities; /* What the client supports */ uint client_capabilities; /* What the client supports */
/* Determines if which non-standard SQL behaviour should be enabled */ /* Determines if which non-standard SQL behaviour should be enabled */
uint sql_mode;
ulong max_client_packet_length; ulong max_client_packet_length;
ulong master_access; /* Global privileges from mysql.user */ ulong master_access; /* Global privileges from mysql.user */
ulong db_access; /* Privileges for current db */ ulong db_access; /* Privileges for current db */
......
...@@ -122,7 +122,7 @@ void lex_init(void) ...@@ -122,7 +122,7 @@ void lex_init(void)
state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT; state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
state_map[(uchar)'@']= (uchar) STATE_USER_END; state_map[(uchar)'@']= (uchar) STATE_USER_END;
state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER; 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; state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
} }
...@@ -167,7 +167,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) ...@@ -167,7 +167,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->convert_set= (lex->thd= thd)->variables.convert_set; lex->convert_set= (lex->thd= thd)->variables.convert_set;
lex->thd_charset= lex->thd->variables.thd_charset; lex->thd_charset= lex->thd->variables.thd_charset;
lex->yacc_yyss=lex->yacc_yyvs=0; 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->slave_thd_opt=0;
lex->sql_command=SQLCOM_END; lex->sql_command=SQLCOM_END;
lex->safe_to_cache_query= 1; lex->safe_to_cache_query= 1;
......
...@@ -588,7 +588,7 @@ check_connections(THD *thd) ...@@ -588,7 +588,7 @@ check_connections(THD *thd)
thd->client_capabilities=uint2korr(net->read_pos); thd->client_capabilities=uint2korr(net->read_pos);
if (thd->client_capabilities & CLIENT_IGNORE_SPACE) if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
thd->sql_mode|= MODE_IGNORE_SPACE; thd->variables.sql_mode|= MODE_IGNORE_SPACE;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities)); DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities));
if (thd->client_capabilities & CLIENT_SSL) if (thd->client_capabilities & CLIENT_SSL)
...@@ -3458,10 +3458,14 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ...@@ -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); set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1);
if (default_value) if (default_value)
{ {
char *not_used;
uint not_used2;
thd->cuted_fields=0; thd->cuted_fields=0;
String str,*res; String str,*res;
res=default_value->val_str(&str); res=default_value->val_str(&str);
(void) find_set(interval,res->ptr(),res->length()); (void) find_set(interval, res->ptr(), res->length(), &not_used,
&not_used2);
if (thd->cuted_fields) if (thd->cuted_fields)
{ {
net_printf(thd,ER_INVALID_DEFAULT,field_name); net_printf(thd,ER_INVALID_DEFAULT,field_name);
......
...@@ -6947,7 +6947,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields, ...@@ -6947,7 +6947,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
if (!order) if (!order)
return 0; /* Everything is ok */ 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; Item *item;
List_iterator<Item> li(fields); List_iterator<Item> li(fields);
...@@ -6969,7 +6969,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields, ...@@ -6969,7 +6969,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields,
return 1; 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 */ /* Don't allow one to use fields that is not used in GROUP BY */
Item *item; Item *item;
......
...@@ -1001,11 +1001,22 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) ...@@ -1001,11 +1001,22 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
static void static void
append_identifier(THD *thd, String *packet, const char *name) 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) if (thd->options & OPTION_QUOTE_SHOW_CREATE)
{ {
packet->append("`", 1); packet->append(&qtype, 1);
packet->append(name); packet->append(name);
packet->append("`", 1); packet->append(&qtype, 1);
} }
else else
{ {
...@@ -1017,6 +1028,16 @@ append_identifier(THD *thd, String *packet, const char *name) ...@@ -1017,6 +1028,16 @@ append_identifier(THD *thd, String *packet, const char *name)
static int static int
store_create_info(THD *thd, TABLE *table, String *packet) 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_ENTER("store_create_info");
DBUG_PRINT("enter",("table: %s",table->real_name)); DBUG_PRINT("enter",("table: %s",table->real_name));
...@@ -1057,9 +1078,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1057,9 +1078,10 @@ store_create_info(THD *thd, TABLE *table, String *packet)
For string types dump collation name only if For string types dump collation name only if
collation is not primary for the given charset 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); packet->append(field->charset()->name);
} }
if (flags & NOT_NULL_FLAG) if (flags & NOT_NULL_FLAG)
...@@ -1083,7 +1105,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1083,7 +1105,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
packet->append(tmp,0); 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 ); packet->append(" auto_increment", 15 );
if (field->comment.length) if (field->comment.length)
...@@ -1117,17 +1139,20 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1117,17 +1139,20 @@ store_create_info(THD *thd, TABLE *table, String *packet)
packet->append("KEY ", 4); packet->append("KEY ", 4);
if (!found_primary) if (!found_primary)
append_identifier(thd,packet,key_info->name); 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 && if (table->db_type == DB_TYPE_HEAP &&
key_info->algorithm == HA_KEY_ALG_BTREE) key_info->algorithm == HA_KEY_ALG_BTREE)
packet->append(" USING BTREE", 12); packet->append(" TYPE BTREE", 11);
// +BAR: send USING only in non-default case: non-spatial rtree // +BAR: send USING only in non-default case: non-spatial rtree
if ((key_info->algorithm == HA_KEY_ALG_RTREE) && if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
!(key_info->flags & HA_SPATIAL)) !(key_info->flags & HA_SPATIAL))
packet->append(" USING RTREE",12); packet->append(" TYPE RTREE", 11);
}
packet->append(" (", 2); packet->append(" (", 2);
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
...@@ -1166,6 +1191,8 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1166,6 +1191,8 @@ store_create_info(THD *thd, TABLE *table, String *packet)
} }
packet->append("\n)", 2); packet->append("\n)", 2);
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
{
packet->append(" TYPE=", 6); packet->append(" TYPE=", 6);
packet->append(file->table_type()); packet->append(file->table_type());
char buff[128]; char buff[128];
...@@ -1228,6 +1255,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1228,6 +1255,7 @@ store_create_info(THD *thd, TABLE *table, String *packet)
my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE); my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE);
packet->append(buff); packet->append(buff);
} }
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -45,7 +45,7 @@ int yylex(void *yylval, void *yythd); ...@@ -45,7 +45,7 @@ int yylex(void *yylval, void *yythd);
inline Item *or_or_concat(THD *thd, Item* A, Item* B) 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)); (Item*) new Item_func_concat(A,B) : (Item*) new Item_cond_or(A,B));
} }
...@@ -1129,7 +1129,7 @@ type: ...@@ -1129,7 +1129,7 @@ type:
| TIME_SYM { $$=FIELD_TYPE_TIME; } | TIME_SYM { $$=FIELD_TYPE_TIME; }
| TIMESTAMP | TIMESTAMP
{ {
if (YYTHD->sql_mode & MODE_SAPDB) if (YYTHD->variables.sql_mode & MODE_SAPDB)
$$=FIELD_TYPE_DATETIME; $$=FIELD_TYPE_DATETIME;
else else
$$=FIELD_TYPE_TIMESTAMP; $$=FIELD_TYPE_TIMESTAMP;
...@@ -1200,7 +1200,7 @@ int_type: ...@@ -1200,7 +1200,7 @@ int_type:
| BIGINT { $$=FIELD_TYPE_LONGLONG; }; | BIGINT { $$=FIELD_TYPE_LONGLONG; };
real_type: 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; } FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; }
| DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; }
| DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment