diff --git a/client/client_priv.h b/client/client_priv.h index eb4473cb10f..b6bfc253854 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -38,4 +38,5 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, - OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM }; + OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, + OPT_COMPATIBLE }; diff --git a/client/mysqldump.c b/client/mysqldump.c index 9534cc68ed4..5eabce9b038 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -36,7 +36,7 @@ ** Added --single-transaction option 06/06/2002 by Peter Zaitsev */ -#define DUMP_VERSION "9.07" +#define DUMP_VERSION "10.0" #include #include @@ -69,21 +69,25 @@ static char *add_load_option(char *ptr, const char *object, const char *statement); +static ulong find_set(TYPELIB *lib, const char *x, uint length, + char **err_pos, uint *err_len); static char *field_escape(char *to,const char *from,uint length); -static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0, - lock_tables=0,ignore_errors=0,flush_logs=0,replace=0, - ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0, - opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0, +static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick= 1, extended_insert= 1, + lock_tables=1,ignore_errors=0,flush_logs=0,replace=0, + ignore=0,opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0, + opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0, opt_alldbs=0,opt_create_db=0,opt_first_slave=0, - opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0, + opt_autocommit=0,opt_master_data,opt_disable_keys=1,opt_xml=0, tty_password=0,opt_single_transaction=0; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0, - *where=0, *default_charset; -static uint opt_mysql_port=0; + *where=0, *default_charset, *opt_compatible_mode_str= 0, + *err_ptr= 0; +static ulong opt_compatible_mode= 0; +static uint opt_mysql_port= 0, err_len= 0; static my_string opt_mysql_unix_port=0; static int first_error=0; extern ulong net_buffer_length; @@ -93,7 +97,17 @@ FILE *md_result_file; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; #endif -static uint opt_protocol=0; +static uint opt_protocol= 0; + +const char *compatible_mode_names[]= +{ + "MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2", + "SAPDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", + NullS +}; +TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1, + "", compatible_mode_names}; + static struct my_option my_long_options[] = { @@ -102,13 +116,13 @@ static struct my_option my_long_options[] = (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"all", 'a', "Include all MySQL specific create options.", - (gptr*) &create_options, (gptr*) &create_options, 0, GET_BOOL, NO_ARG, 0, + (gptr*) &create_options, (gptr*) &create_options, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.", - (gptr*) &opt_drop, (gptr*) &opt_drop, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + (gptr*) &opt_drop, (gptr*) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"add-locks", OPT_LOCKS, "Add locks around insert statements.", - (gptr*) &opt_lock, (gptr*) &opt_lock, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + (gptr*) &opt_lock, (gptr*) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"allow-keywords", OPT_KEYWORDS, "Allow creation of column names that are keywords.", (gptr*) &opt_keywords, @@ -116,6 +130,10 @@ static struct my_option my_long_options[] = {"character-sets-dir", OPT_CHARSETS_DIR, "Directory where character sets are", (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"compatible", OPT_COMPATIBLE, + "Change the dump to be compatible with a given mode. By default tables are dumped without any restrictions. Legal modes are: mysql323, mysql40, postgresql, oracle, mssql, db2, sapdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option does a no operation on earlier server versions.", + (gptr*) &opt_compatible_mode_str, (gptr*) &opt_compatible_mode_str, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag, (gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use compression in server/client protocol.", @@ -135,11 +153,11 @@ static struct my_option my_long_options[] = 0, 0}, {"disable-keys", 'K', "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys, - (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"extended-insert", 'e', "Allows utilization of the new, much faster INSERT syntax.", (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, + 1, 0, 0, 0, 0, 0}, {"fields-terminated-by", OPT_FTB, "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated, (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -168,7 +186,7 @@ static struct my_option my_long_options[] = (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables, - (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"master-data", OPT_MASTER_DATA, "This will cause the master position and filename to be appended to your output. This will automagically enable --first-slave.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -178,8 +196,8 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0, 0}, {"single-transaction", OPT_TRANSACTION, "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.", - (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-db", 'n', "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}", (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, @@ -192,7 +210,7 @@ static struct my_option my_long_options[] = "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"opt", OPT_OPTIMIZE, - "Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys", + "Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys. Enabled by default, disable with --skip-opt.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server. If password is not given it's solicited on the tty.", @@ -207,7 +225,7 @@ static struct my_option my_long_options[] = {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory)", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"quick", 'q', "Don't buffer query, dump directly to stdout.", - (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"quote-names",'Q', "Quote table and column names with a `", (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -219,6 +237,9 @@ static struct my_option my_long_options[] = "Base name of shared memory", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif + {"skip-opt", OPT_SKIP_OPTIMIZATION, + "Disable --opt. Disables --add-locks, --all, --quick, --extended-insert, --lock-tables and --disable-keys.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -322,6 +343,7 @@ static void write_header(FILE *sql_file, char *db_name) return; } /* write_header */ + static void write_footer(FILE *sql_file) { if (opt_xml) @@ -329,6 +351,7 @@ static void write_footer(FILE *sql_file) fputs("\n", sql_file); } /* write_footer */ + static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) @@ -378,27 +401,48 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), usage(); exit(0); case (int) OPT_OPTIMIZE: - extended_insert=opt_drop=opt_lock=quick=create_options=opt_disable_keys= - lock_tables=1; + extended_insert= opt_drop= opt_lock= quick= create_options= + opt_disable_keys= lock_tables= 1; if (opt_single_transaction) lock_tables=0; break; + case (int) OPT_SKIP_OPTIMIZATION: + extended_insert= opt_drop= opt_lock= quick= create_options= + opt_disable_keys= lock_tables= 0; + break; case (int) OPT_TABLES: opt_databases=0; break; - case OPT_MYSQL_PROTOCOL: - { - if ((opt_protocol = find_type(argument, &sql_protocol_typelib,0)) == ~(ulong) 0) - { - fprintf(stderr, "Unknown option to protocol: %s\n", argument); - exit(1); + case (int) OPT_COMPATIBLE: + { + char buff[255]; + + opt_quoted= 1; + opt_compatible_mode_str= argument; + opt_compatible_mode= find_set(&compatible_mode_typelib, + argument, strlen(argument), + &err_ptr, &err_len); + if (err_len) + { + strmake(buff, err_ptr, min(sizeof(buff), err_len)); + fprintf(stderr, "Invalid mode to --compatible: %s\n", buff); + exit(1); + } + break; + } + case (int) OPT_MYSQL_PROTOCOL: + { + if ((opt_protocol= find_type(argument, &sql_protocol_typelib, 0)) + == ~(ulong) 0) + { + fprintf(stderr, "Unknown option to protocol: %s\n", argument); + exit(1); + } + break; } - break; - } } return 0; } - static int get_options(int *argc, char ***argv) { int ho_error; @@ -418,13 +462,8 @@ static int get_options(int *argc, char ***argv) "%s: You must use option --tab with --fields-...\n", my_progname); return(1); } - - if (opt_single_transaction && lock_tables) - { - fprintf(stderr, "%s: You can't use --lock-tables and --single-transaction at the same time.\n", my_progname); - return(1); - } - + if (opt_single_transaction) + lock_tables= 0; if (enclosed && opt_enclosed) { fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname); @@ -604,6 +643,31 @@ static uint getTableStructure(char *table, char* db) /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; + if (opt_compatible_mode) + { + char *end; + uint i; + + sprintf(buff, "/*!41000 SET @@sql_mode=\""); + end= strend(buff); + for (i= 0; opt_compatible_mode; opt_compatible_mode>>= 1, i++) + { + if (opt_compatible_mode & 1) + { + end= strmov(end, compatible_mode_names[i]); + end= strmov(end, ","); + } + } + end= strmov(--end, "\" */"); + if (mysql_query(sock, buff)) + { + fprintf(stderr, "%s: Can't set the compatible mode '%s' (%s)\n", + my_progname, table, mysql_error(sock)); + safe_exit(EX_MYSQLERR); + DBUG_RETURN(0); + } + } + sprintf(buff,"show create table `%s`",table); if (mysql_query(sock, buff)) { @@ -1399,6 +1463,48 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } /* dump_selected_tables */ + +static ulong find_set(TYPELIB *lib, const char *x, uint length, + char **err_pos, uint *err_len) +{ + const char *end= x + length; + ulong found= 0; + uint find; + char buff[255]; + + *err_pos= 0; // No error yet + while (end > x && my_isspace(system_charset_info, end[-1])) + end--; + + *err_len= 0; + if (x != end) + { + const char *start= x; + for (;;) + { + const char *pos= start; + uint var_len; + + for (; pos != end && *pos != ','; pos++) ; + var_len= (uint) (pos - start); + strmake(buff, start, min(sizeof(buff), var_len)); + find= find_type(buff, lib, var_len); + if (!find) + { + *err_pos= (char*) start; + *err_len= var_len; + } + else + found|= ((longlong) 1 << (find - 1)); + if (pos == end) + break; + start= pos + 1; + } + } + return found; +} + + /* Print a value with a prefix on file */ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, const char *prefix, const char *name, diff --git a/include/m_ctype.h b/include/m_ctype.h index d99fda8d2b9..8e3cffc5613 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -57,6 +57,7 @@ typedef struct unicase_info_st { #define MY_CS_LOADED 8 /* sets that are currently loaded */ #define MY_CS_BINSORT 16 /* if binary sort order */ #define MY_CS_PRIMARY 32 /* if primary collation */ +#define MY_CS_STRNXFRM 64 /* if strnxfrm is used for sort */ #define MY_CHARSET_UNDEFINED 0 #define MY_CHARSET_CURRENT (default_charset_info->number) @@ -133,15 +134,15 @@ typedef struct charset_info_st /* Charset dependant snprintf() */ int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt, ...); - int (*l10tostr)(struct charset_info_st *, char *to, uint n, int radix, long int val); - int (*ll10tostr)(struct charset_info_st *, char *to, uint n, int radix, longlong val); + int (*long10_to_str)(struct charset_info_st *, char *to, uint n, int radix, long int val); + int (*longlong10_to_str)(struct charset_info_st *, char *to, uint n, int radix, longlong val); /* String-to-number convertion routines */ - long (*strntol)(struct charset_info_st *, const char *s, uint l,char **e, int base); - ulong (*strntoul)(struct charset_info_st *, const char *s, uint l, char **e, int base); - longlong (*strntoll)(struct charset_info_st *, const char *s, uint l, char **e, int base); - ulonglong (*strntoull)(struct charset_info_st *, const char *s, uint l, char **e, int base); - double (*strntod)(struct charset_info_st *, char *s, uint l, char **e); + long (*strntol)(struct charset_info_st *, const char *s, uint l, int base, char **e, int *err); + ulong (*strntoul)(struct charset_info_st *, const char *s, uint l, int base, char **e, int *err); + longlong (*strntoll)(struct charset_info_st *, const char *s, uint l, int base, char **e, int *err); + ulonglong (*strntoull)(struct charset_info_st *, const char *s, uint l, int base, char **e, int *err); + double (*strntod)(struct charset_info_st *, char *s, uint l, char **e, int *err); } CHARSET_INFO; @@ -182,14 +183,14 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e); int my_snprintf_8bit(struct charset_info_st *, char *to, uint n, const char *fmt, ...); -long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); -ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); -longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); -ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); -double my_strntod_8bit(CHARSET_INFO *, char *s, uint l,char **e); +long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l, int base, char **e, int *err); +ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, uint l, int base, char **e, int *err); +longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, uint l, int base, char **e, int *err); +ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, uint l, int base, char **e, int *err); +double my_strntod_8bit(CHARSET_INFO *, char *s, uint l,char **e, int *err); -int my_l10tostr_8bit(CHARSET_INFO *, char *to, uint l, int radix, long int val); -int my_ll10tostr_8bit(CHARSET_INFO *, char *to, uint l, int radix, longlong val); +int my_long10_to_str_8bit(CHARSET_INFO *, char *to, uint l, int radix, long int val); +int my_longlong10_to_str_8bit(CHARSET_INFO *, char *to, uint l, int radix, longlong val); my_bool my_like_range_simple(CHARSET_INFO *cs, const char *ptr, uint ptr_length, @@ -253,7 +254,7 @@ int my_wildcmp_mb(CHARSET_INFO *, #define my_isvar(s,c) (my_isalnum(s,c) || (c) == '_') #define my_isvar_start(s,c) (my_isalpha(s,c) || (c) == '_') -#define use_strnxfrm(s) ((s)->strnxfrm != NULL) +#define use_strnxfrm(s) ((s)->state & MY_CS_STRNXFRM) #define my_strnxfrm(s, a, b, c, d) ((s)->strnxfrm((s), (a), (b), (c), (d))) #define my_strnncoll(s, a, b, c, d) ((s)->strnncoll((s), (a), (b), (c), (d))) #define my_like_range(s, a, b, c, d, e, f, g, h, i, j) \ @@ -273,11 +274,11 @@ int my_wildcmp_mb(CHARSET_INFO *, #define my_strcasecmp(s, a, b) ((s)->strcasecmp((s), (a), (b))) #define my_strncasecmp(s, a, b, l) ((s)->strncasecmp((s), (a), (b), (l))) -#define my_strntol(s, a, b, c, d) ((s)->strntol((s),(a),(b),(c),(d))) -#define my_strntoul(s, a, b, c, d) ((s)->strntoul((s),(a),(b),(c),(d))) -#define my_strntoll(s, a, b, c, d) ((s)->strntoll((s),(a),(b),(c),(d))) -#define my_strntoull(s, a, b, c,d) ((s)->strntoull((s),(a),(b),(c),(d))) -#define my_strntod(s, a, b, c ) ((s)->strntod((s),(a),(b),(c))) +#define my_strntol(s, a, b, c, d, e) ((s)->strntol((s),(a),(b),(c),(d),(e))) +#define my_strntoul(s, a, b, c, d, e) ((s)->strntoul((s),(a),(b),(c),(d),(e))) +#define my_strntoll(s, a, b, c, d, e) ((s)->strntoll((s),(a),(b),(c),(d),(e))) +#define my_strntoull(s, a, b, c,d, e) ((s)->strntoull((s),(a),(b),(c),(d),(e))) +#define my_strntod(s, a, b, c, d) ((s)->strntod((s),(a),(b),(c),(d))) /* XXX: still need to take care of this one */ diff --git a/include/mysql.h b/include/mysql.h index ce321f5b5ea..f25ccf79cf6 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -476,6 +476,7 @@ typedef struct st_mysql_stmt my_bool send_types_to_server; /* to indicate types supply to server */ my_bool param_buffers; /* to indicate the param bound buffers */ my_bool res_buffers; /* to indicate the output bound buffers */ + my_bool result_buffered; /* to indicate the results buffered */ } MYSQL_STMT; @@ -502,6 +503,7 @@ int STDCALL mysql_multi_query(MYSQL *mysql,const char *query, MYSQL_RES *STDCALL mysql_next_result(MYSQL *mysql); MYSQL_RES *STDCALL mysql_prepare_result(MYSQL_STMT *stmt); my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt); +int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt); /* new status messages */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 7b08d6b89b8..d4329c4873c 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -3602,7 +3602,8 @@ lock_release_off_kernel( ut_ad(lock_get_type(lock) == LOCK_TABLE); if (lock_get_mode(lock) != LOCK_IS - && (trx->insert_undo || trx->update_undo)) { + && 0 != ut_dulint_cmp(trx->undo_no, + ut_dulint_zero)) { /* The trx may have modified the table. We block the use of the MySQL query cache diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 7757050aad7..37eed9ab1b2 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -115,6 +115,7 @@ static sig_handler pipe_sig_handler(int sig); static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, const char *from, ulong length); static my_bool stmt_close(MYSQL_STMT *stmt, my_bool skip_list); +static unsigned int get_binary_length(uint type); static my_bool org_my_init_done=0; @@ -3839,7 +3840,7 @@ static my_bool read_prepare_result(MYSQL_STMT *stmt) if ((length= net_safe_read(mysql)) == packet_error) DBUG_RETURN(1); - pos=(uchar*) mysql->net.read_pos; + pos= (uchar*) mysql->net.read_pos; stmt->stmt_id= uint4korr(pos); pos+=4; field_count= uint2korr(pos); pos+=2; param_count= uint2korr(pos); pos+=2; @@ -3865,10 +3866,10 @@ static my_bool read_prepare_result(MYSQL_STMT *stmt) set_stmt_error(stmt, CR_OUT_OF_MEMORY); DBUG_RETURN(0); } - stmt->bind= (stmt->params + stmt->param_count); - stmt->field_count= (uint) field_count; - stmt->param_count= (ulong) param_count; - stmt->mysql->status= MYSQL_STATUS_READY; + stmt->bind= (stmt->params + param_count); + stmt->field_count= (uint) field_count; + stmt->param_count= (ulong) param_count; + mysql->status= MYSQL_STATUS_READY; DBUG_RETURN(0); } @@ -4102,8 +4103,18 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param) store_param_null(net, param); else { - /* Allocate for worst case (long string) */ - if ((my_realloc_str(net, 9 + *param->length))) + unsigned int length; + + /* + Allocate for worst case (long string), ignore the length + buffer for numeric/double types by assigning the default + length using get_binary_length + */ + + if (!(length= get_binary_length(param->buffer_type))) + length= *param->length; + + if ((my_realloc_str(net, 9 + length))) DBUG_RETURN(1); (*param->store_param_func)(net, param); } @@ -4133,6 +4144,8 @@ static my_bool execute(MYSQL_STMT * stmt, char *packet, ulong length) } stmt->state= MY_ST_EXECUTE; mysql_free_result(stmt->result); + stmt->result= (MYSQL_RES *)0; + stmt->result_buffered= 0; DBUG_RETURN(0); } @@ -4522,41 +4535,42 @@ static void send_data_double(MYSQL_BIND *param, double value) static void send_data_str(MYSQL_BIND *param, char *value, uint length) { char *buffer= param->buffer; + int err=0; switch(param->buffer_type) { case MYSQL_TYPE_TINY: { - uchar data= (uchar)my_strntol(system_charset_info,value,length,NULL,10); + uchar data= (uchar)my_strntol(system_charset_info,value,length,10,NULL,&err); *buffer= data; break; } case MYSQL_TYPE_SHORT: { - short data= (short)my_strntol(system_charset_info,value,length,NULL,10); + short data= (short)my_strntol(system_charset_info,value,length,10,NULL,&err); int2store(buffer, data); break; } case MYSQL_TYPE_LONG: { - int32 data= (int32)my_strntol(system_charset_info,value,length,NULL,10); + int32 data= (int32)my_strntol(system_charset_info,value,length,10,NULL,&err); int4store(buffer, data); break; } case MYSQL_TYPE_LONGLONG: { - longlong data= my_strntoll(system_charset_info,value,length,NULL,10); + longlong data= my_strntoll(system_charset_info,value,length,10,NULL,&err); int8store(buffer, data); break; } case MYSQL_TYPE_FLOAT: { - float data = (float)my_strntod(system_charset_info,value,length,NULL); + float data = (float)my_strntod(system_charset_info,value,length,NULL,&err); float4store(buffer, data); break; } case MYSQL_TYPE_DOUBLE: { - double data= my_strntod(system_charset_info,value,length,NULL); + double data= my_strntod(system_charset_info,value,length,NULL,&err); float8store(buffer, data); break; } @@ -4859,12 +4873,14 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind) Fetch row data to bind buffers */ -static void -stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) +static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) { MYSQL_BIND *bind, *end; MYSQL_FIELD *field, *field_end; uchar *null_ptr, bit; + + if (!row || !stmt->res_buffers) + return 0; null_ptr= row; row+= (stmt->field_count+9)/8; /* skip null bits */ @@ -4884,7 +4900,7 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) if (field->type == bind->buffer_type) (*bind->fetch_result)(bind, &row); else if (fetch_results(stmt, bind, field->type, &row)) - break; + return 1; } if (! (bit<<=1) & 255) { @@ -4892,23 +4908,9 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) null_ptr++; } } -} - -static int read_binary_data(MYSQL *mysql) -{ - /* TODO : Changes needed based on logic of use_result/store_result - Currently by default it is use_result. In case of - store_result, the data packet must point to already - read data. - */ - if (packet_error == net_safe_read(mysql)) - return -1; - if (mysql->net.read_pos[0] == 254) - return 1; /* End of data */ return 0; } - /* Fetch and return row data to bound buffers, if any */ @@ -4916,24 +4918,153 @@ static int read_binary_data(MYSQL *mysql) int STDCALL mysql_fetch(MYSQL_STMT *stmt) { MYSQL *mysql= stmt->mysql; - int res; + uchar *row; DBUG_ENTER("mysql_fetch"); - if (!(res= read_binary_data(mysql))) + row= (uchar *)0; + if (stmt->result_buffered) /* buffered */ { - if (stmt->res_buffers) - stmt_fetch_row(stmt, mysql->net.read_pos+1); - DBUG_RETURN(0); + MYSQL_RES *res; + + if (!(res= stmt->result) || !res->data_cursor) + goto no_data; + + row= (uchar *)res->data_cursor->data; + res->data_cursor= res->data_cursor->next; + res->current_row= (MYSQL_ROW)row; } - mysql->status= MYSQL_STATUS_READY; - if (res < 0) /* Network error */ + else /* un-buffered */ + { + if (packet_error == net_safe_read(mysql)) + { + set_stmt_errmsg(stmt,(char *)mysql->net.last_error, + mysql->net.last_errno); + DBUG_RETURN(1); + } + if (mysql->net.read_pos[0] == 254) + { + mysql->status= MYSQL_STATUS_READY; + goto no_data; + } + row= mysql->net.read_pos+1; + } + DBUG_RETURN(stmt_fetch_row(stmt, row)); + +no_data: + DBUG_PRINT("info", ("end of data")); + DBUG_RETURN(MYSQL_NO_DATA); /* no more data */ +} + +/* + Read all rows of data from server (binary format) +*/ + +static MYSQL_DATA *read_binary_rows(MYSQL_STMT *stmt) +{ + ulong pkt_len; + uchar *cp; + MYSQL *mysql= stmt->mysql; + MYSQL_DATA *result; + MYSQL_ROWS *cur, **prev_ptr; + NET *net = &mysql->net; + DBUG_ENTER("read_binary_rows"); + + mysql= mysql->last_used_con; + if ((pkt_len= net_safe_read(mysql)) == packet_error) { set_stmt_errmsg(stmt,(char *)mysql->net.last_error, mysql->net.last_errno); + DBUG_RETURN(0); + } + if (mysql->net.read_pos[0] == 254) /* end of data */ + return 0; + + if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + { + net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->last_error,ER(net->last_errno)); + DBUG_RETURN(0); + } + init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */ + result->alloc.min_malloc= sizeof(MYSQL_ROWS); + prev_ptr= &result->data; + result->rows= 0; + + while (*(cp=net->read_pos) != 254 || pkt_len >= 8) + { + result->rows++; + + if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,sizeof(MYSQL_ROWS))) || + !(cur->data= ((MYSQL_ROW) alloc_root(&result->alloc, pkt_len)))) + { + free_rows(result); + net->last_errno=CR_OUT_OF_MEMORY; + strmov(net->last_error,ER(net->last_errno)); + DBUG_RETURN(0); + } + *prev_ptr= cur; + prev_ptr= &cur->next; + memcpy(cur->data, (char*)cp+1, pkt_len-1); + + if ((pkt_len=net_safe_read(mysql)) == packet_error) + { + free_rows(result); + DBUG_RETURN(0); + } + } + *prev_ptr= 0; + if (pkt_len > 1) + { + mysql->warning_count= uint2korr(cp+1); + DBUG_PRINT("info",("warning_count: %ld", mysql->warning_count)); + } + DBUG_PRINT("exit",("Got %d rows",result->rows)); + DBUG_RETURN(result); +} + +/* + Store or buffer the binary results to stmt +*/ + +int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) +{ + MYSQL *mysql= stmt->mysql; + MYSQL_RES *result; + DBUG_ENTER("mysql_stmt_tore_result"); + + mysql= mysql->last_used_con; + + if (!stmt->field_count) + DBUG_RETURN(0); + if (mysql->status != MYSQL_STATUS_GET_RESULT) + { + strmov(mysql->net.last_error, + ER(mysql->net.last_errno= CR_COMMANDS_OUT_OF_SYNC)); + DBUG_RETURN(0); + } + mysql->status= MYSQL_STATUS_READY; /* server is ready */ + if (!(result= (MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+ + sizeof(ulong) * + stmt->field_count), + MYF(MY_WME | MY_ZEROFILL)))) + { + mysql->net.last_errno= CR_OUT_OF_MEMORY; + strmov(mysql->net.last_error, ER(mysql->net.last_errno)); DBUG_RETURN(1); } - DBUG_PRINT("info", ("end of data")); - DBUG_RETURN(MYSQL_NO_DATA); /* no more data */ + stmt->result_buffered= 1; + if (!(result->data= read_binary_rows(stmt))) + { + my_free((gptr) result,MYF(0)); + DBUG_RETURN(0); + } + mysql->affected_rows= result->row_count= result->data->rows; + result->data_cursor= result->data->data; + result->fields= stmt->fields; + result->field_count= stmt->field_count; + stmt->result= result; + DBUG_RETURN(0); /* Data buffered, must be fetched with mysql_fetch() */ } diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result new file mode 100644 index 00000000000..8ded3daf114 --- /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 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/mysys/charset.c b/mysys/charset.c index c89e1d60c7e..865441444bc 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -47,6 +47,7 @@ static void simple_cs_init_functions(CHARSET_INFO *cs) { cs->like_range = my_like_range_simple; cs->wildcmp = my_wildcmp_8bit; + cs->strnxfrm = my_strnxfrm_simple; cs->strnncoll = my_strnncoll_simple; cs->caseup_str = my_caseup_str_8bit; cs->casedn_str = my_casedn_str_8bit; diff --git a/sql/field.cc b/sql/field.cc index 467096a4a71..c287c716cc1 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); @@ -832,15 +840,17 @@ int Field_decimal::store(longlong nr) double Field_decimal::val_real(void) { - return my_strntod(my_charset_bin, ptr, field_length, NULL); + int err; + return my_strntod(my_charset_bin, ptr, field_length, NULL, &err); } longlong Field_decimal::val_int(void) { + int err; if (unsigned_flag) - return my_strntoull(my_charset_bin, ptr, field_length, NULL, 10); + return my_strntoull(my_charset_bin, ptr, field_length, 10, NULL, &err); else - return my_strntoll( my_charset_bin, ptr, field_length, NULL, 10); + return my_strntoll( my_charset_bin, ptr, field_length, 10, NULL, &err); } @@ -942,8 +952,9 @@ void Field_decimal::sql_type(String &res) const int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { + int err; char *end; - long tmp= my_strntol(cs, from, len, &end,10); + long tmp= my_strntol(cs, from, len, 10, &end, &err); int error= 0; if (unsigned_flag) @@ -1097,9 +1108,9 @@ String *Field_tiny::val_str(String *val_buffer, char *to=(char*) val_buffer->ptr(); if (unsigned_flag) - length= (uint) cs->l10tostr(cs,to,mlength, 10,(long) *((uchar*) ptr)); + length= (uint) cs->long10_to_str(cs,to,mlength, 10,(long) *((uchar*) ptr)); else - length= (uint) cs->l10tostr(cs,to,mlength,-10,(long) *((signed char*) ptr)); + length= (uint) cs->long10_to_str(cs,to,mlength,-10,(long) *((signed char*) ptr)); val_buffer->length(length); if (zerofill) @@ -1143,8 +1154,9 @@ void Field_tiny::sql_type(String &res) const int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { + int err; char *end; - long tmp= my_strntol(cs, from, len, &end, 10); + long tmp= my_strntol(cs, from, len, 10, &end, &err); int error= 0; if (unsigned_flag) { @@ -1340,9 +1352,9 @@ String *Field_short::val_str(String *val_buffer, shortget(j,ptr); if (unsigned_flag) - length=(uint) cs->l10tostr(cs, to, mlength, 10, (long) (uint16) j); + length=(uint) cs->long10_to_str(cs, to, mlength, 10, (long) (uint16) j); else - length=(uint) cs->l10tostr(cs, to, mlength,-10, (long) j); + length=(uint) cs->long10_to_str(cs, to, mlength,-10, (long) j); val_buffer->length(length); if (zerofill) prepend_zeros(val_buffer); @@ -1415,8 +1427,9 @@ void Field_short::sql_type(String &res) const int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { + int err; char *end; - long tmp= my_strntol(cs, from, len, &end, 10); + long tmp= my_strntol(cs, from, len, 10, &end, &err); int error= 0; if (unsigned_flag) @@ -1577,7 +1590,7 @@ String *Field_medium::val_str(String *val_buffer, char *to=(char*) val_buffer->ptr(); long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); - length=(uint) cs->l10tostr(cs,to,mlength,-10,j); + length=(uint) cs->long10_to_str(cs,to,mlength,-10,j); val_buffer->length(length); if (zerofill) prepend_zeros(val_buffer); /* purecov: inspected */ @@ -1651,16 +1664,15 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) error= 1; } else - tmp=(long) my_strntoul(cs,from,len,&end,10); + tmp=(long) my_strntoul(cs,from,len,10,&end,&error); } else - tmp=my_strntol(cs,from,len,&end,10); - if (my_errno || + tmp=my_strntol(cs,from,len,10,&end,&error); + if (error || (from+len != end && current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))) { current_thd->cuted_fields++; - error= 1; } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -1816,9 +1828,9 @@ String *Field_long::val_str(String *val_buffer, longget(j,ptr); if (unsigned_flag) - length=cs->l10tostr(cs,to,mlength, 10,(long) (uint32)j); + length=cs->long10_to_str(cs,to,mlength, 10,(long) (uint32)j); else - length=cs->l10tostr(cs,to,mlength,-10,(long) j); + length=cs->long10_to_str(cs,to,mlength,-10,(long) j); val_buffer->length(length); if (zerofill) prepend_zeros(val_buffer); @@ -1910,11 +1922,11 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) error= 1; } else - tmp=(longlong) my_strntoull(cs,from,len,&end,10); + tmp=(longlong) my_strntoull(cs,from,len,10,&end,&error); } else - tmp=my_strntoll(cs,from,len,&end,10); - if (my_errno || + tmp=my_strntoll(cs,from,len,10,&end,&error); + if (error || (from+len != end && current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))) current_thd->cuted_fields++; @@ -2038,7 +2050,7 @@ String *Field_longlong::val_str(String *val_buffer, #endif longlongget(j,ptr); - length=(uint) cs->ll10tostr(cs,to,mlength,unsigned_flag ? 10 : -10, j); + length=(uint) cs->longlong10_to_str(cs,to,mlength,unsigned_flag ? 10 : -10, j); val_buffer->length(length); if (zerofill) prepend_zeros(val_buffer); @@ -2122,14 +2134,14 @@ void Field_longlong::sql_type(String &res) const int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) { - errno=0; // my_strntod() changes errno - Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL)); - if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) + int err=0; + Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL,&err)); + if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) { current_thd->cuted_fields++; return 1; } - return (errno) ? 1 : 0; + return (err) ? 1 : 0; } @@ -2395,19 +2407,17 @@ void Field_float::sql_type(String &res) const int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) { - errno=0; // my_strntod() changes errno - int error= 0; - double j= my_strntod(cs,(char*) from,len,(char**)0); - if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) + int err= 0; + double j= my_strntod(cs,(char*) from,len,(char**)0,&err); + if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) { current_thd->cuted_fields++; - error= 1; } if (unsigned_flag && j < 0) { current_thd->cuted_fields++; j=0; - error= 1; + err= 1; } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -2417,7 +2427,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) else #endif doublestore(ptr,j); - return error; + return err; } @@ -3183,8 +3193,9 @@ void Field_time::sql_type(String &res) const int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { + int err; char *end; - long nr= my_strntol(cs, from, len, &end, 10); + long nr= my_strntol(cs, from, len, 10, &end, &err); if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) { @@ -3914,22 +3925,24 @@ int Field_string::store(longlong nr) char buff[64]; int l; CHARSET_INFO *cs=charset(); - l=cs->ll10tostr(cs,buff,sizeof(buff),-10,nr); + l=cs->longlong10_to_str(cs,buff,sizeof(buff),-10,nr); return Field_string::store(buff,(uint)l,cs); } double Field_string::val_real(void) { + int err; CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr,field_length,(char**)0); + return my_strntod(cs,ptr,field_length,(char**)0,&err); } longlong Field_string::val_int(void) { + int err; CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr,field_length,NULL,10); + return my_strntoll(cs,ptr,field_length,10,NULL,&err); } @@ -3956,23 +3969,11 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) void Field_string::sort_string(char *to,uint length) { - if (binary()) - memcpy((byte*) to,(byte*) ptr,(size_t) length); - else - { -#ifdef USE_STRCOLL - if (use_strnxfrm(field_charset)) { - uint tmp=my_strnxfrm(field_charset, + uint tmp=my_strnxfrm(field_charset, (unsigned char *)to, length, (unsigned char *) ptr, field_length); - if (tmp < length) - bzero(to + tmp, length - tmp); - } - else -#endif - for (char *from=ptr,*end=ptr+length ; from != end ;) - *to++=(char) field_charset->sort_order[(uint) (uchar) *from++]; - } + if (tmp < length) + bzero(to + tmp, length - tmp); } @@ -4093,24 +4094,26 @@ int Field_varstring::store(longlong nr) char buff[64]; int l; CHARSET_INFO *cs=charset(); - l=cs->ll10tostr(cs,buff,sizeof(buff),-10,nr); + l=cs->longlong10_to_str(cs,buff,sizeof(buff),-10,nr); return Field_varstring::store(buff,(uint)l,cs); } double Field_varstring::val_real(void) { + int err; uint length=uint2korr(ptr)+2; CHARSET_INFO *cs=charset(); - return my_strntod(cs,ptr+2,length,(char**)0); + return my_strntod(cs,ptr+2,length,(char**)0,&err); } longlong Field_varstring::val_int(void) { + int err; uint length=uint2korr(ptr)+2; CHARSET_INFO *cs=charset(); - return my_strntoll(cs,ptr+2,length,NULL,10); + return my_strntoll(cs,ptr+2,length,10,NULL,&err); } @@ -4137,27 +4140,9 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr) void Field_varstring::sort_string(char *to,uint length) { uint tot_length=uint2korr(ptr); - if (binary()) - memcpy((byte*) to,(byte*) ptr+2,(size_t) tot_length); - else - { -#ifdef USE_STRCOLL - if (use_strnxfrm(field_charset)) - tot_length=my_strnxfrm(field_charset, + tot_length=my_strnxfrm(field_charset, (unsigned char *) to, length, (unsigned char *)ptr+2, tot_length); - else - { -#endif - char *tmp=to; - if (tot_length > length) - tot_length=length; - for (char *from=ptr+2,*end=from+tot_length ; from != end ;) - *tmp++=(char) field_charset->sort_order[(uint) (uchar) *from++]; -#ifdef USE_STRCOLL - } -#endif - } if (tot_length < length) bzero(to+tot_length,length-tot_length); } @@ -4436,24 +4421,26 @@ int Field_blob::store(longlong nr) double Field_blob::val_real(void) { + int err; char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0.0; uint32 length=get_length(ptr); CHARSET_INFO *cs=charset(); - return my_strntod(cs,blob,length,(char**)0); + return my_strntod(cs,blob,length,(char**)0,&err); } longlong Field_blob::val_int(void) { + int err; char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0; uint32 length=get_length(ptr); - return my_strntoll(charset(),blob,length,NULL,10); + return my_strntoll(charset(),blob,length,10,NULL,&err); } @@ -4613,38 +4600,19 @@ void Field_blob::sort_string(char *to,uint length) { char *blob; uint blob_length=get_length(); -#ifdef USE_STRCOLL - uint blob_org_length=blob_length; -#endif + if (!blob_length) bzero(to,length); else { - if (blob_length > length) - blob_length=length; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); - if (binary()) - { - memcpy(to,blob,blob_length); - to+=blob_length; - } - else - { -#ifdef USE_STRCOLL - if (use_strnxfrm(field_charset)) - { - blob_length=my_strnxfrm(field_charset, - (unsigned char *)to, length, - (unsigned char *)blob, blob_org_length); - if (blob_length >= length) - return; - to+=blob_length; - } - else -#endif - for (char *end=blob+blob_length ; blob != end ;) - *to++=(char) field_charset->sort_order[(uint) (uchar) *blob++]; - } + + blob_length=my_strnxfrm(field_charset, + (unsigned char *)to, length, + (unsigned char *)blob, blob_length); + if (blob_length >= length) + return; + to+=blob_length; bzero(to,length-blob_length); } } @@ -4887,7 +4855,7 @@ uint find_enum(TYPELIB *lib,const char *x, uint length) int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { - int error= 0; + int err= 0; uint tmp=find_enum(typelib,from,length); if (!tmp) { @@ -4895,20 +4863,18 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { /* This is for reading numbers with LOAD DATA INFILE */ char *end; - my_errno=0; - tmp=(uint) my_strntoul(cs,from,length,&end,10); - if (my_errno || end != from+length || tmp > typelib->count) + tmp=(uint) my_strntoul(cs,from,length,10,&end,&err); + if (err || end != from+length || tmp > typelib->count) { tmp=0; current_thd->cuted_fields++; - error=1; } } else current_thd->cuted_fields++; } store_type((ulonglong) tmp); - return error; + return err; } @@ -5037,38 +5003,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. -ulonglong find_set(TYPELIB *lib,const char *x,uint length) + 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, 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++; @@ -5079,25 +5059,26 @@ 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); + int err= 0; + 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 */ char *end; - my_errno=0; - tmp=my_strntoull(cs,from,length,&end,10); - if (my_errno || end != from+length || + tmp=my_strntoull(cs,from,length,10,&end,&err); + if (err || end != from+length || tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) { tmp=0; - error=1; } else current_thd->cuted_fields--; // Remove warning from find_set } store_type(tmp); - return error; + return err; } 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.cc b/sql/item.cc index 925ee9ac0f4..ecc63aa4b95 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -378,10 +378,11 @@ int Item_param::save_in_field(Field *field, bool no_conversions) double Item_param::val() { + int err; switch (item_result_type) { case STRING_RESULT: return (double) my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0); + str_value.length(), (char**) 0, &err); case INT_RESULT: return (double)int_value; default: @@ -392,9 +393,12 @@ double Item_param::val() longlong Item_param::val_int() { + int err; switch (item_result_type) { case STRING_RESULT: - return my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); + return my_strntoll(str_value.charset(), + str_value.ptr(),str_value.length(),10, + (char**) 0,&err); case REAL_RESULT: return (longlong) (real_value+(real_value > 0 ? 0.5 : -0.5)); default: @@ -1263,17 +1267,19 @@ void Item_cache_str::store(Item *item) } double Item_cache_str::val() { + int err; if (value) return my_strntod(value->charset(), (char*) value->ptr(), - value->length(), (char**) 0); + value->length(), (char**) 0, &err); else return (double)0; } longlong Item_cache_str::val_int() { + int err; if (value) return my_strntoll(value->charset(), value->ptr(), - value->length(), (char**) 0, 10); + value->length(), 10, (char**) 0, &err); else return (longlong)0; } diff --git a/sql/item.h b/sql/item.h index 907c293d454..03e9a542eea 100644 --- a/sql/item.h +++ b/sql/item.h @@ -344,13 +344,15 @@ public: enum Type type() const { return STRING_ITEM; } double val() { + int err; return my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(), (char**) 0); + str_value.length(), (char**) 0, &err); } longlong val_int() { + int err; return my_strntoll(str_value.charset(), str_value.ptr(), - str_value.length(), (char**) 0, 10); + str_value.length(), 10, (char**) 0, &err); } String *val_str(String*) { return (String*) &str_value; } int save_in_field(Field *field, bool no_conversions); @@ -599,12 +601,16 @@ public: enum_field_types field_type() const { return cached_field_type; } double val() { + int err; return (null_value ? 0.0 : my_strntod(str_value.charset(), (char*) str_value.ptr(), - str_value.length(),NULL)); + str_value.length(),NULL,&err)); } longlong val_int() - { return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); } + { + int err; + return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),10, (char**) 0,&err); + } String *val_str(String*); void make_field(Send_field *field) { item->make_field(field); } void copy(); 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/item_func.h b/sql/item_func.h index 11793b11bdb..a015f6e69ce 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -812,13 +812,15 @@ public: String *val_str(String *); double val() { + int err; String *res; res=val_str(&str_value); - return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0) : 0.0; + return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0,&err) : 0.0; } longlong val_int() { + int err; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),(char**) 0,10) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4358f14f08e..2b9bdfe9a1e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -52,17 +52,19 @@ uint nr_of_decimals(const char *str) double Item_str_func::val() { + int err; String *res; res=val_str(&str_value); return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - NULL) : 0.0; + NULL, &err) : 0.0; } longlong Item_str_func::val_int() { + int err; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),NULL,10) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,NULL,&err) : (longlong) 0; } @@ -1956,6 +1958,7 @@ String *Item_func_conv::val_str(String *str) longlong dec; int from_base= (int) args[1]->val_int(); int to_base= (int) args[2]->val_int(); + int err; if (args[0]->null_value || args[1]->null_value || args[2]->null_value || abs(to_base) > 36 || abs(to_base) < 2 || @@ -1966,9 +1969,9 @@ String *Item_func_conv::val_str(String *str) } null_value=0; if (from_base < 0) - dec= my_strntoll(res->charset(),res->ptr(),res->length(),&endptr,-from_base); + dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err); else - dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),&endptr,from_base); + dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),from_base,&endptr,&err); ptr= longlong2str(dec,ans,to_base); if (str->copy(ans,(uint32) (ptr-ans), thd_charset())) return &empty_string; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b15fceda686..2a96594af4e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -336,13 +336,14 @@ void Item_sum_variance::update_field(int offset) double Item_sum_hybrid::val() { + int err; if (null_value) return 0.0; switch (hybrid_type) { case STRING_RESULT: String *res; res=val_str(&str_value); return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), - (char**) 0) : 0.0); + (char**) 0, &err) : 0.0); case INT_RESULT: if (unsigned_flag) return ulonglong2double(sum_int); diff --git a/sql/item_sum.h b/sql/item_sum.h index ffc9558822d..c49311082e8 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -483,14 +483,16 @@ public: String *val_str(String *); double val() { + int err; String *res; res=val_str(&str_value); return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(), - (char**) 0) : 0.0; + (char**) 0, &err) : 0.0; } longlong val_int() { + int err; String *res; res=val_str(&str_value); - return res ? my_strntoll(res->charset(),res->ptr(),res->length(),(char**) 0,10) : (longlong) 0; + return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec(); 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..f30034049f0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -424,12 +424,12 @@ double log_10[32]; /* 10 potences */ I_List 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': @@ -4665,9 +4666,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), berkeley_lock_type=berkeley_lock_types[type-1]; else { + int err; char *end; uint length= strlen(argument); - long value= my_strntol(my_charset_latin1, argument, length, &end, 10); + long value= my_strntol(my_charset_latin1, argument, length, 10, &end, &err); if (test_if_int(argument,(uint) length, end, my_charset_latin1)) berkeley_lock_scan_time= value; else @@ -4730,16 +4732,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/procedure.h b/sql/procedure.h index bc77803230f..03a45488b03 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -59,7 +59,7 @@ public: void set(double nr) { value=nr; } void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) - { value=my_strntod(cs,(char*) str,length,(char**)0); } + { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } double val() { return value; } longlong val_int() { return (longlong) value; } String *val_str(String *s) { s->set(value,decimals,thd_charset()); return s; } @@ -77,7 +77,7 @@ public: void set(double nr) { value=(longlong) nr; } void set(longlong nr) { value=nr; } void set(const char *str,uint length, CHARSET_INFO *cs) - { value=my_strntoll(cs,str,length,NULL,10); } + { int err; value=my_strntoll(cs,str,length,10,NULL,&err); } double val() { return (double) value; } longlong val_int() { return value; } String *val_str(String *s) { s->set(value, thd_charset()); return s; } @@ -98,14 +98,16 @@ public: { str_value.copy(str,length,cs); } double val() { + int err; CHARSET_INFO *cs=str_value.charset(); return my_strntod(cs, (char*) str_value.ptr(), str_value.length(), - (char**) 0); + (char**) 0, &err); } longlong val_int() { + int err; CHARSET_INFO *cs=str_value.charset(); - return my_strntoll(cs,str_value.ptr(),str_value.length(),NULL,10); + return my_strntoll(cs,str_value.ptr(),str_value.length(),10,NULL,&err); } String *val_str(String*) { 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_prepare.cc b/sql/sql_prepare.cc index 3907995676f..69228c6ec4c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -333,53 +333,6 @@ static bool setup_params_data(PREP_STMT *stmt) DBUG_RETURN(0); } -/* - Validates insert fields -*/ - -static int check_prepare_fields(THD *thd,TABLE *table, List &fields, - List &values, ulong counter) -{ - if (fields.elements == 0 && values.elements != 0) - { - if (values.elements != table->fields) - { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); - return -1; - } - } - else - { - if (fields.elements != values.elements) - { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); - return -1; - } - TABLE_LIST table_list; - bzero((char*) &table_list,sizeof(table_list)); - table_list.db= table->table_cache_key; - table_list.real_name= table_list.alias= table->table_name; - table_list.table= table; - table_list.grant= table->grant; - - thd->dupp_field=0; - if (setup_tables(&table_list) || - setup_fields(thd,&table_list,fields,1,0,0)) - return -1; - if (thd->dupp_field) - { - my_error(ER_FIELD_SPECIFIED_TWICE,MYF(0), thd->dupp_field->field_name); - return -1; - } - } - return 0; -} - - /* Validate the following information for INSERT statement: - field existance @@ -519,21 +472,6 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, DBUG_RETURN(0); } - -/* - Check the access privileges -*/ - -static bool check_prepare_access(THD *thd, TABLE_LIST *tables, - uint type) -{ - if (check_access(thd,type,tables->db,&tables->grant.privilege)) - return 1; - if (grant_option && check_grant(thd,type,tables)) - return 1; - return 0; -} - /* Send the prepare query results back to client */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 63c0d8b785f..ee0775c06e5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6949,7 +6949,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List &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 li(fields); @@ -6971,7 +6971,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List &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..3ec45c8eca9 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,72 @@ 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 && + !(thd->variables.sql_mode & MODE_MYSQL323) && + !(thd->variables.sql_mode & MODE_MYSQL40)) { - 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_string.cc b/sql/sql_string.cc index 4c499af8f9e..646621ac2eb 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -100,7 +100,7 @@ bool String::set(longlong num, CHARSET_INFO *cs) if (alloc(l)) return TRUE; - str_length=(uint32) cs->ll10tostr(cs,Ptr,l,-10,num); + str_length=(uint32) cs->longlong10_to_str(cs,Ptr,l,-10,num); str_charset=cs; return FALSE; } @@ -111,7 +111,7 @@ bool String::set(ulonglong num, CHARSET_INFO *cs) if (alloc(l)) return TRUE; - str_length=(uint32) cs->ll10tostr(cs,Ptr,l,10,num); + str_length=(uint32) cs->longlong10_to_str(cs,Ptr,l,10,num); str_charset=cs; return FALSE; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 971a110bc9b..bcfe3bf9964 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; }; diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 408c7f8fe35..3d26918f1c8 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6218,7 +6218,7 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_big5 = { 1, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ "big5", /* cs name */ "big5", /* name */ "", /* comment */ @@ -6250,8 +6250,8 @@ CHARSET_INFO my_charset_big5 = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index e20afff1470..3cf5bb763cd 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -254,7 +254,14 @@ static int my_wildcmp_bin(CHARSET_INFO *cs, return(str != str_end ? 1 : 0); } - +static int my_strnxfrm_bin(CHARSET_INFO *cs __attribute__((unused)), + uchar * dest, uint len, + const uchar *src, + uint srclen __attribute__((unused))) +{ + memcpy(dest,src,len= min(len,srclen)); + return len; +} static CHARSET_INFO my_charset_bin_st = { @@ -271,7 +278,7 @@ static CHARSET_INFO my_charset_bin_st = NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_binary, /* strnncoll */ - NULL, /* strxnfrm */ + my_strnxfrm_bin, /* strxnfrm */ my_like_range_simple, /* like_range */ my_wildcmp_bin, /* wildcmp */ 1, /* mbmaxlen */ @@ -291,8 +298,8 @@ static CHARSET_INFO my_charset_bin_st = my_hash_sort_bin, /* hash_sort */ 255, /* max_sort_char */ my_snprintf_8bit, /* snprintf */ - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index bb0afe98032..8feb83cbeb4 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -596,7 +596,7 @@ static MY_UNI_IDX idx_uni_8859_2[]={ CHARSET_INFO my_charset_czech = { 2, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */ "latin2", /* cs name */ "czech", /* name */ "", /* comment */ @@ -628,8 +628,8 @@ CHARSET_INFO my_charset_czech = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 814f43166c4..ff7d0e9a5ae 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8648,7 +8648,7 @@ CHARSET_INFO my_charset_euc_kr = NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_mb, /* wildcmp */ 2, /* mbmaxlen */ @@ -8668,8 +8668,8 @@ CHARSET_INFO my_charset_euc_kr = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index d575e48a59a..a94778118e3 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5698,7 +5698,7 @@ CHARSET_INFO my_charset_gb2312 = NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_mb, /* wildcmp */ 2, /* mbmaxlen */ @@ -5718,8 +5718,8 @@ CHARSET_INFO my_charset_gb2312 = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 0094a93e5f8..7c48e239f2d 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9873,7 +9873,7 @@ my_mb_wc_gbk(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_gbk = { 28, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ "gbk", /* cs name */ "gbk", /* name */ "", /* comment */ @@ -9905,8 +9905,8 @@ CHARSET_INFO my_charset_gbk = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 166e059ef42..6891e4cf944 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -414,7 +414,7 @@ static my_bool my_like_range_latin1_de(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_latin1_de = { 31, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */ "latin1", /* cs name */ "latin1_de", /* name */ "", /* comment */ @@ -446,8 +446,8 @@ CHARSET_INFO my_charset_latin1_de = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 9bcafa9f164..4ecd3717ca1 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -17,7 +17,6 @@ #include #include "m_string.h" #include "m_ctype.h" -#include "my_sys.h" /* defines errno */ #include #include "stdarg.h" @@ -29,11 +28,13 @@ int my_strnxfrm_simple(CHARSET_INFO * cs, const uchar *src, uint srclen) { uchar *map= cs->sort_order; + const uchar *end; DBUG_ASSERT(len >= srclen); - for ( ; len > 0 ; len-- ) + len= min(len,srclen); + for ( end=src+len; src < end ; ) *dest++= map[*src++]; - return srclen; + return len; } int my_strnncoll_simple(CHARSET_INFO * cs, const uchar *s, uint slen, @@ -201,7 +202,8 @@ void my_hash_sort_simple(CHARSET_INFO *cs, long my_strntol_8bit(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative; register ulong cutoff; @@ -211,10 +213,12 @@ long my_strntol_8bit(CHARSET_INFO *cs, register unsigned char c; const char *save, *e; int overflow; - + +#if 0 if (base < 0 || base == 1 || base > 36) base = 10; - +#endif + s = nptr; e = nptr+l; @@ -239,9 +243,12 @@ long my_strntol_8bit(CHARSET_INFO *cs, else negative = 0; +#if 0 if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x')) s += 2; +#endif +#if 0 if (base == 0) { if (*s == '0') @@ -257,6 +264,7 @@ long my_strntol_8bit(CHARSET_INFO *cs, else base = 10; } +#endif save = s; cutoff = ((ulong)~0L) / (unsigned long int) base; @@ -301,14 +309,14 @@ long my_strntol_8bit(CHARSET_INFO *cs, if (overflow) { - my_errno=(ERANGE); + err[0]= ERANGE; return negative ? LONG_MIN : LONG_MAX; } return (negative ? -((long) i) : (long) i); noconv: - my_errno=(EDOM); + err[0]= EDOM; if (endptr != NULL) *endptr = (char *) nptr; return 0L; @@ -316,7 +324,8 @@ noconv: ulong my_strntoul_8bit(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative; register ulong cutoff; @@ -327,9 +336,11 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, const char *save, *e; int overflow; +#if 0 if (base < 0 || base == 1 || base > 36) base = 10; - +#endif + s = nptr; e = nptr+l; @@ -353,9 +364,12 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, else negative = 0; +#if 0 if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x')) s += 2; +#endif +#if 0 if (base == 0) { if (*s == '0') @@ -371,6 +385,7 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, else base = 10; } +#endif save = s; cutoff = ((ulong)~0L) / (unsigned long int) base; @@ -407,14 +422,14 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, if (overflow) { - my_errno=(ERANGE); + err[0]= ERANGE; return ((ulong)~0L); } return (negative ? -((long) i) : (long) i); noconv: - my_errno=(EDOM); + err[0]= EDOM; if (endptr != NULL) *endptr = (char *) nptr; return 0L; @@ -422,7 +437,8 @@ noconv: longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr,int *err) { int negative; register ulonglong cutoff; @@ -433,8 +449,10 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *save; int overflow; +#if 0 if (base < 0 || base == 1 || base > 36) base = 10; +#endif s = nptr; e = nptr+l; @@ -459,9 +477,12 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), else negative = 0; +#if 0 if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x')) s += 2; +#endif +#if 0 if (base == 0) { if (*s == '0') @@ -477,6 +498,7 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), else base = 10; } +#endif save = s; @@ -522,14 +544,14 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), if (overflow) { - my_errno=(ERANGE); + err[0]= ERANGE; return negative ? LONGLONG_MIN : LONGLONG_MAX; } return (negative ? -((longlong) i) : (longlong) i); noconv: - my_errno=(EDOM); + err[0]= EDOM; if (endptr != NULL) *endptr = (char *) nptr; return 0L; @@ -537,7 +559,8 @@ noconv: ulonglong my_strntoull_8bit(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative; register ulonglong cutoff; @@ -548,8 +571,10 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, const char *save; int overflow; +#if 0 if (base < 0 || base == 1 || base > 36) base = 10; +#endif s = nptr; e = nptr+l; @@ -574,9 +599,12 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, else negative = 0; +#if 0 if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x')) s += 2; +#endif +#if 0 if (base == 0) { if (*s == '0') @@ -592,6 +620,7 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, else base = 10; } +#endif save = s; @@ -629,14 +658,14 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, if (overflow) { - my_errno=(ERANGE); + err[0]= ERANGE; return (~(ulonglong) 0); } return (negative ? -((longlong) i) : (longlong) i); noconv: - my_errno=(EDOM); + err[0]= EDOM; if (endptr != NULL) *endptr = (char *) nptr; return 0L; @@ -665,7 +694,8 @@ noconv: double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), - char *str, uint length, char **end) + char *str, uint length, + char **end, int *err __attribute__ ((unused))) { char end_char; double result; @@ -686,7 +716,7 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), Assume len >= 1 */ -int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), +int my_long10_to_str_8bit(CHARSET_INFO *cs __attribute__((unused)), char *dst, uint len, int radix, long int val) { char buffer[66]; @@ -725,7 +755,7 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), } -int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), +int my_longlong10_to_str_8bit(CHARSET_INFO *cs __attribute__((unused)), char *dst, uint len, int radix, longlong val) { char buffer[65]; diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 3949be5e215..b3d81bb9c8a 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4460,7 +4460,7 @@ my_mb_wc_sjis(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_sjis = { 13, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ "sjis", /* cs name */ "sjis", /* name */ "", /* comment */ @@ -4492,8 +4492,8 @@ CHARSET_INFO my_charset_sjis = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 7168026eea5..b07b08bba9f 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -688,7 +688,7 @@ void ThNormalize(uchar* ptr, uint field_length, const uchar* from, uint length) CHARSET_INFO my_charset_tis620 = { 18, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ "tis620", /* cs name */ "tis620", /* name */ "", /* comment */ @@ -720,8 +720,8 @@ CHARSET_INFO my_charset_tis620 = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 0a0024594e4..eaf39ff0aa7 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8442,7 +8442,7 @@ CHARSET_INFO my_charset_ujis = NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ NULL, /* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_mb, /* wildcmp */ 3, /* mbmaxlen */ @@ -8462,8 +8462,8 @@ CHARSET_INFO my_charset_ujis = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 4f72a4c2334..2418a6ab574 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -21,9 +21,12 @@ #include #include "m_string.h" #include "m_ctype.h" -#include "my_sys.h" /* defines errno */ #include +#ifndef EILSEQ +#define EILSEQ ENOENT +#endif + #ifdef HAVE_CHARSET_utf8 #define HAVE_UNIDATA #endif @@ -1958,7 +1961,7 @@ static int my_mbcharlen_utf8(CHARSET_INFO *cs __attribute__((unused)) , uint c) CHARSET_INFO my_charset_utf8 = { 33, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ "utf8", /* cs name */ "utf8", /* name */ "", /* comment */ @@ -1990,8 +1993,8 @@ CHARSET_INFO my_charset_utf8 = my_hash_sort_utf8, /* hash_sort */ 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -2446,7 +2449,8 @@ static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused)) long my_strntol_ucs2(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative=0; int overflow; @@ -2475,16 +2479,18 @@ long my_strntol_ucs2(CHARSET_INFO *cs, { if (endptr !=NULL ) *endptr = (char*)s; - my_errno = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; + err[0] = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; return 0; } s+=cnv; } while (1); bs: - + +#if 0 if (base <= 0 || base == 1 || base > 36) base = 10; +#endif overflow = 0; res = 0; @@ -2518,7 +2524,7 @@ bs: { if (endptr !=NULL ) *endptr = (char*)s; - my_errno=EILSEQ; + err[0]=EILSEQ; return 0; } else @@ -2533,7 +2539,7 @@ bs: if (s == save) { - my_errno=EDOM; + err[0]=EDOM; return 0L; } @@ -2547,7 +2553,7 @@ bs: if (overflow) { - my_errno=(ERANGE); + err[0]=ERANGE; return negative ? LONG_MIN : LONG_MAX; } @@ -2556,7 +2562,8 @@ bs: ulong my_strntoul_ucs2(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative=0; int overflow; @@ -2585,17 +2592,19 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs, { if (endptr !=NULL ) *endptr = (char*)s; - my_errno = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; + err[0] = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; return 0; } s+=cnv; } while (1); bs: - + +#if 0 if (base <= 0 || base == 1 || base > 36) base = 10; - +#endif + overflow = 0; res = 0; save = s; @@ -2628,7 +2637,7 @@ bs: { if (endptr !=NULL ) *endptr = (char*)s; - my_errno=EILSEQ; + err[0]=EILSEQ; return 0; } else @@ -2643,13 +2652,13 @@ bs: if (s == save) { - my_errno=EDOM; + err[0]=EDOM; return 0L; } if (overflow) { - my_errno=(ERANGE); + err[0]=(ERANGE); return ((ulong)~0L); } @@ -2660,7 +2669,8 @@ bs: longlong my_strntoll_ucs2(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative=0; int overflow; @@ -2689,17 +2699,19 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs, { if (endptr !=NULL ) *endptr = (char*)s; - my_errno = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; + err[0] = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; return 0; } s+=cnv; } while (1); bs: - + +#if 0 if (base <= 0 || base == 1 || base > 36) base = 10; - +#endif + overflow = 0; res = 0; save = s; @@ -2732,7 +2744,7 @@ bs: { if (endptr !=NULL ) *endptr = (char*)s; - my_errno=EILSEQ; + err[0]=EILSEQ; return 0; } else @@ -2747,7 +2759,7 @@ bs: if (s == save) { - my_errno=EDOM; + err[0]=EDOM; return 0L; } @@ -2761,7 +2773,7 @@ bs: if (overflow) { - my_errno=(ERANGE); + err[0]=ERANGE; return negative ? LONGLONG_MIN : LONGLONG_MAX; } @@ -2772,7 +2784,8 @@ bs: ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, - const char *nptr, uint l, char **endptr, int base) + const char *nptr, uint l, int base, + char **endptr, int *err) { int negative=0; int overflow; @@ -2801,7 +2814,7 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, { if (endptr !=NULL ) *endptr = (char*)s; - my_errno = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; + err[0]= (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM; return 0; } s+=cnv; @@ -2809,9 +2822,11 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, bs: +#if 0 if (base <= 0 || base == 1 || base > 36) base = 10; - +#endif + overflow = 0; res = 0; save = s; @@ -2844,7 +2859,7 @@ bs: { if (endptr !=NULL ) *endptr = (char*)s; - my_errno=EILSEQ; + err[0]= EILSEQ; return 0; } else @@ -2859,13 +2874,13 @@ bs: if (s == save) { - my_errno=EDOM; + err[0]= EDOM; return 0L; } if (overflow) { - my_errno=(ERANGE); + err[0]= ERANGE; return (~(ulonglong) 0); } @@ -2874,7 +2889,8 @@ bs: double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), - char *nptr, uint length, char **endptr) + char *nptr, uint length, + char **endptr, int *err __attribute__ ((unused))) { char buf[256]; double res; @@ -3019,7 +3035,7 @@ cnv: CHARSET_INFO my_charset_ucs2 = { 35, /* number */ - MY_CS_COMPILED|MY_CS_PRIMARY, /* state */ + MY_CS_COMPILED|MY_CS_PRIMARY|MY_CS_STRNXFRM, /* state */ "ucs2", /* cs name */ "ucs2", /* name */ "", /* comment */ diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 358cede442c..6ec96693fec 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -622,7 +622,7 @@ static my_bool my_like_range_win1250ch(CHARSET_INFO *cs __attribute__((unused)), CHARSET_INFO my_charset_win1250ch = { 34, /* number */ - MY_CS_COMPILED, /* state */ + MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */ "cp1250", /* cs name */ "cp1250_czech", /* name */ "", /* comment */ @@ -654,8 +654,8 @@ CHARSET_INFO my_charset_win1250ch = my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, diff --git a/strings/ctype.c b/strings/ctype.c index c2a7e928493..04ae5917da2 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2823,7 +2823,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_1, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -2843,8 +2843,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -2869,7 +2869,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_cp1251, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -2889,8 +2889,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -2914,7 +2914,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_cp1257, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -2934,8 +2934,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -2959,7 +2959,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_2, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -2979,8 +2979,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3005,7 +3005,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_1, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3025,8 +3025,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3050,7 +3050,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3070,8 +3070,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3095,7 +3095,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3115,8 +3115,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3140,7 +3140,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3160,8 +3160,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3186,7 +3186,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_1, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3206,8 +3206,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3231,7 +3231,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3251,8 +3251,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3276,7 +3276,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3296,8 +3296,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3321,7 +3321,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3341,8 +3341,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3366,7 +3366,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_2, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3386,8 +3386,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3411,7 +3411,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_koi8_r, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3431,8 +3431,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3456,7 +3456,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_koi8_u, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3476,8 +3476,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3502,7 +3502,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_2, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3522,8 +3522,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3547,7 +3547,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_8859_9, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3567,8 +3567,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3593,7 +3593,7 @@ static CHARSET_INFO compiled_charsets[] = { NULL, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3613,8 +3613,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3639,7 +3639,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_us_ascii, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3659,8 +3659,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3684,7 +3684,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_cp1250, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3704,8 +3704,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3729,7 +3729,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_cp1251, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3749,8 +3749,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3774,7 +3774,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_armscii_8, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3794,8 +3794,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3819,7 +3819,7 @@ static CHARSET_INFO compiled_charsets[] = { idx_uni_cp1251, /* tab_from_uni */ 0, /* strxfrm_multiply */ my_strnncoll_simple,/* strnncoll */ - NULL, /* strnxfrm */ + my_strnxfrm_simple, /* strnxfrm */ my_like_range_simple,/* like_range */ my_wildcmp_8bit, /* wildcmp */ 1, /* mbmaxlen */ @@ -3839,8 +3839,8 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_l10tostr_8bit, - my_ll10tostr_8bit, + my_long10_to_str_8bit, + my_longlong10_to_str_8bit, my_strntol_8bit, my_strntoul_8bit, my_strntoll_8bit, @@ -3983,6 +3983,7 @@ typedef struct my_cs_file_info static int fill_uchar(uchar *a,uint size,const char *str, uint len) { + int err=0; uint i= 0; const char *s, *b, *e=str+len; @@ -3993,7 +3994,7 @@ static int fill_uchar(uchar *a,uint size,const char *str, uint len) for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ; if (s == b || i > size) break; - a[i]= my_strntoul(my_charset_latin1,b,s-b,NULL,16); + a[i]= my_strntoul(my_charset_latin1,b,s-b,16,NULL,&err); } return 0; } @@ -4001,6 +4002,8 @@ static int fill_uchar(uchar *a,uint size,const char *str, uint len) static int fill_uint16(uint16 *a,uint size,const char *str, uint len) { uint i= 0; + int err; + const char *s, *b, *e=str+len; for (s=str ; s < e ; i++) { @@ -4009,7 +4012,7 @@ static int fill_uint16(uint16 *a,uint size,const char *str, uint len) for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ; if (s == b || i > size) break; - a[i]= my_strntol(my_charset_latin1,b,s-b,NULL,16); + a[i]= my_strntol(my_charset_latin1,b,s-b,16,NULL,&err); } return 0; } @@ -4051,6 +4054,7 @@ static int cs_value(MY_XML_PARSER *st,const char *attr, uint len) struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data; struct my_cs_file_section_st *s; int state= (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0; + int err; #ifndef DBUG_OFF if(0){ @@ -4062,7 +4066,7 @@ static int cs_value(MY_XML_PARSER *st,const char *attr, uint len) switch (state) { case _CS_ID: - i->cs.number= my_strntoul(my_charset_latin1,attr,len,(char**)NULL,0); + i->cs.number= my_strntoul(my_charset_latin1,attr,len,10,(char**)NULL,&err); break; case _CS_COLNAME: i->cs.name=mstr(i->name,attr,len,MY_CS_NAME_SIZE-1);