diff options
author | sasha@mysql.sashanet.com <> | 2001-08-09 19:16:15 -0600 |
---|---|---|
committer | sasha@mysql.sashanet.com <> | 2001-08-09 19:16:15 -0600 |
commit | f6836bf81abb42523349ac6cf0b8807fa9e69c3e (patch) | |
tree | ed06f905f1515a2117cc0c243c526264fccaac77 /sql | |
parent | d9737f20f838f189ef1f3d25df7739770f3b52b9 (diff) | |
parent | be4f7bbdcf89e5fa2a9e8193cda1d317918d7d07 (diff) | |
download | mariadb-git-f6836bf81abb42523349ac6cf0b8807fa9e69c3e.tar.gz |
merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/Makefile.am | 6 | ||||
-rw-r--r-- | sql/ha_berkeley.cc | 23 | ||||
-rw-r--r-- | sql/ha_berkeley.h | 3 | ||||
-rw-r--r-- | sql/ha_innobase.cc | 41 | ||||
-rw-r--r-- | sql/ha_innobase.h | 1 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 20 | ||||
-rw-r--r-- | sql/log_event.cc | 19 | ||||
-rw-r--r-- | sql/log_event.h | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 7 | ||||
-rw-r--r-- | sql/mysqlbinlog.cc | 469 | ||||
-rw-r--r-- | sql/mysqld.cc | 23 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 17 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 4 |
18 files changed, 124 insertions, 527 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index 02ac8aa6cc7..d3c3ff541fd 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -27,7 +27,6 @@ INCLUDES = @MT_INCLUDES@ \ -I$(srcdir) -I../include -I.. -I. $(openssl_includes) WRAPLIBS= @WRAPLIBS@ SUBDIRS = share -bin_PROGRAMS = mysqlbinlog libexec_PROGRAMS = mysqld noinst_PROGRAMS = gen_lex_hash gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ @@ -83,12 +82,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc \ mini_client.cc mini_client_errors.c \ - md5.c stacktrace.c sql_union.cc + md5.c stacktrace.c gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) -mysqlbinlog_SOURCES = mysqlbinlog.cc mini_client.cc net_serv.cc \ - mini_client_errors.c password.c -mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) $(mysqld_LDADD) DEFS = -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 6907da855b9..25f8148e52f 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -888,7 +888,7 @@ int ha_berkeley::write_row(byte * record) if (changed_keys & 1) { if ((new_error = remove_key(sub_trans, keynr, record, - (DBT*) 0, &prim_key))) + &prim_key))) break; /* purecov: inspected */ } } @@ -970,7 +970,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed, { // Primary key changed or we are updating a key that can have duplicates. // Delete the old row and add a new one - if (!(error=remove_key(trans, primary_key, old_row, (DBT *) 0, old_key))) + if (!(error=remove_key(trans, primary_key, old_row, old_key))) { if (!(error=pack_row(&row, new_row, 0))) { @@ -1034,7 +1034,7 @@ int ha_berkeley::restore_keys(DB_TXN *trans, key_map changed_keys, if (changed_keys & 1) { if (changed_keys != 1 && - (error = remove_key(trans, keynr, new_row, (DBT*) 0, new_key))) + (error = remove_key(trans, keynr, new_row, new_key))) break; /* purecov: inspected */ if ((error = key_file[keynr]->put(key_file[keynr], trans, create_key(&tmp_key, keynr, key_buff2, @@ -1105,8 +1105,7 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) continue; if (key_cmp(keynr, old_row, new_row) || primary_key_changed) { - if ((error=remove_key(sub_trans, keynr, old_row, (DBT*) 0, - &old_prim_key))) + if ((error=remove_key(sub_trans, keynr, old_row, &old_prim_key))) { if (using_ignore && /* purecov: inspected */ (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)) @@ -1172,11 +1171,9 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row) Delete one key This uses key_buff2, when keynr != primary key, so it's important that a function that calls this doesn't use this buffer for anything else. - packed_record may be NULL if the key is unique */ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record, - DBT *packed_record, DBT *prim_key) { int error; @@ -1207,13 +1204,9 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record, if (!(error=key_file[keynr]->cursor(key_file[keynr], trans, &tmp_cursor, 0))) { - if (!(error=cursor->c_get(tmp_cursor, - (keynr == primary_key ? - prim_key : - create_key(&key, keynr, key_buff2, record)), - (keynr == primary_key ? - packed_record : prim_key), - DB_GET_BOTH | DB_RMW))) + if (!(error=tmp_cursor->c_get(tmp_cursor, + create_key(&key, keynr, key_buff2, record), + prim_key, DB_GET_BOTH | DB_RMW))) { // This shouldn't happen error=tmp_cursor->c_del(tmp_cursor,0); } @@ -1236,7 +1229,7 @@ int ha_berkeley::remove_keys(DB_TXN *trans, const byte *record, { if (keys & 1) { - int new_error=remove_key(trans, keynr, record, new_record, prim_key); + int new_error=remove_key(trans, keynr, record, prim_key); if (new_error) { result=new_error; // Return last error /* purecov: inspected */ diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 9e657d72da1..3eb793937ae 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -69,8 +69,7 @@ class ha_berkeley: public handler int key_length = MAX_KEY_LENGTH); DBT *pack_key(DBT *key, uint keynr, char *buff, const byte *key_ptr, uint key_length); - int remove_key(DB_TXN *trans, uint keynr, const byte *record, - DBT *packed_record, DBT *prim_key); + int remove_key(DB_TXN *trans, uint keynr, const byte *record, DBT *prim_key); int remove_keys(DB_TXN *trans,const byte *record, DBT *new_record, DBT *prim_key, key_map keys); int restore_keys(DB_TXN *trans, key_map changed_keys, uint primary_key, diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 8ea700de789..7bd71363915 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -822,11 +822,11 @@ ha_innobase::open( if (NULL == (ib_table = dict_table_get(norm_name, NULL))) { - fprintf(stderr, "\ -Cannot find table %s from the internal data dictionary\n\ -of InnoDB though the .frm file for the table exists. Maybe you have deleted\n\ -and created again an InnoDB database but forgotten to delete the\n\ -corresponding .frm files of old InnoDB tables?\n", + fprintf(stderr, +"Cannot find table %s from the internal data dictionary\n" +"of InnoDB though the .frm file for the table exists. Maybe you have deleted\n" +"and created again an InnoDB database but forgotten to delete the\n" +"corresponding .frm files of old InnoDB tables?\n", norm_name); free_share(share); @@ -2660,6 +2660,37 @@ ha_innobase::records_in_range( } /************************************************************************* +Gives an UPPER BOUND to the number of rows in a table. This is used in +filesort.cc and the upper bound must hold. TODO: Since the number of +rows in a table may change after this function is called, we still may +get a 'Sort aborted' error in filesort.cc of MySQL. The ultimate fix is to +improve the algorithm of filesort.cc. */ + +ha_rows +ha_innobase::estimate_number_of_rows(void) +/*======================================*/ + /* out: upper bound of rows, currently 32-bit int + or uint */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + dict_table_t* ib_table; + + DBUG_ENTER("info"); + + ib_table = prebuilt->table; + + dict_update_statistics(ib_table); + + data_file_length = ((ulonglong) + ib_table->stat_clustered_index_size) + * UNIV_PAGE_SIZE; + + /* The minimum clustered index record size is 20 bytes */ + + return((ha_rows) (1000 + data_file_length / 20)); +} + +/************************************************************************* How many seeks it will take to read through the table. This is to be comparable to the number returned by records_in_range so that we can decide if we should scan the table or use keys. */ diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index 4dbff654337..d129e00ba6e 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -137,6 +137,7 @@ class ha_innobase: public handler enum ha_rkey_function start_search_flag, const byte *end_key,uint end_key_len, enum ha_rkey_function end_search_flag); + ha_rows estimate_number_of_rows(); int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 63e2cf7c201..0a86e833134 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -35,7 +35,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = -{ "DEFAULT", "BACKUP", "FORCE", "QUICK"}; +{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", myisam_recover_names}; diff --git a/sql/item_func.cc b/sql/item_func.cc index b76bee78b2e..66a50eb0ec0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1954,13 +1954,17 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) maybe_null=1; join_key=0; - /* Why testing for const_item ? Monty */ - /* I'll remove it later, but this should include modifications to - find_best and auto_close as complement to auto_init code above. SerG */ - /* I'd rather say now that const_item is assumed in quite a bit of - places, so it would be difficult to remove. SerG */ + /* Serg: + I'd rather say now that const_item is assumed in quite a bit of + places, so it would be difficult to remove; If it would ever to be + removed, this should include modifications to find_best and auto_close + as complement to auto_init code above. + */ if (Item_func::fix_fields(thd,tlist) || !const_item()) + { + my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); return 1; + } while ((item=li++)) { @@ -1969,12 +1973,18 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) if (item->type() == Item::REF_ITEM) li.replace(item= *((Item_ref *)item)->ref); if (item->type() != Item::FIELD_ITEM || !item->used_tables()) + { + my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); return 1; + } used_tables_cache|=item->used_tables(); } /* check that all columns come from the same table */ if (count_bits(used_tables_cache) != 1) + { + my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); return 1; + } const_item_cache=0; table=((Item_field *)fields.head())->field->table; return 0; diff --git a/sql/log_event.cc b/sql/log_event.cc index 14524216076..ca01e418992 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -404,15 +404,26 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, #endif // MYSQL_CLIENT -// allocates memory - the caller is responsible for clean-up +#ifndef MYSQL_CLIENT +#define UNLOCK_MUTEX if(log_lock) pthread_mutex_unlock(log_lock); +#else +#define UNLOCK_MUTEX +#endif +// allocates memory - the caller is responsible for clean-up +#ifndef MYSQL_CLIENT Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock) +#else +Log_event* Log_event::read_log_event(IO_CACHE* file) +#endif { char head[LOG_EVENT_HEADER_LEN]; - if(log_lock) pthread_mutex_lock(log_lock); +#ifndef MYSQL_CLIENT + if(log_lock) pthread_mutex_lock(log_lock); +#endif if (my_b_read(file, (byte *) head, sizeof(head))) { - if (log_lock) pthread_mutex_unlock(log_lock); + UNLOCK_MUTEX; return 0; } @@ -449,7 +460,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock) if((res = read_log_event(buf, data_len))) res->register_temp_buf(buf); err: - if (log_lock) pthread_mutex_unlock(log_lock); + UNLOCK_MUTEX; if(error) { sql_print_error(error); diff --git a/sql/log_event.h b/sql/log_event.h index d16d76bed37..4c24f640465 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -233,10 +233,13 @@ public: virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0; void print_timestamp(FILE* file, time_t *ts = 0); void print_header(FILE* file); -#endif +#ifndef MYSQL_CLIENT // if mutex is 0, the read will proceed without mutex static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock); +#else // avoid having to link mysqlbinlog against libpthread + static Log_event* read_log_event(IO_CACHE* file); +#endif static Log_event* read_log_event(const char* buf, int event_len); const char* get_type_str(); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d02a2eb729e..6326e3d07c2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -177,6 +177,13 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define SELECT_NO_UNLOCK (QUERY_NO_GOOD_INDEX_USED*2) #define TMP_TABLE_ALL_COLUMNS (SELECT_NO_UNLOCK*2) +#define MODE_REAL_AS_FLOAT 1 +#define MODE_PIPES_AS_CONCAT 2 +#define MODE_ANSI_QUOTES 4 +#define MODE_IGNORE_SPACE 8 +#define MODE_SERIALIZABLE 16 +#define MODE_ONLY_FULL_GROUP_BY 32 + #define RAID_BLOCK_SIZE 1024 /* BINLOG_DUMP options */ diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc deleted file mode 100644 index 5edfe6e0591..00000000000 --- a/sql/mysqlbinlog.cc +++ /dev/null @@ -1,469 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - - -#define MYSQL_CLIENT -#undef MYSQL_SERVER -#include <global.h> -#include <m_string.h> -#include <my_sys.h> -#include <getopt.h> -#include <thr_alarm.h> -#define MYSQL_SERVER // We want the C++ version of net -#include <mysql.h> -#include "log_event.h" -#include "mini_client.h" - -#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) - -char server_version[SERVER_VERSION_LENGTH]; -uint32 server_id = 0; - -// needed by net_serv.c -ulong bytes_sent = 0L, bytes_received = 0L; -ulong mysqld_net_retry_count = 10L; -ulong net_read_timeout= NET_READ_TIMEOUT; -ulong net_write_timeout= NET_WRITE_TIMEOUT; -uint test_flags = 0; -FILE *result_file; - -#ifndef DBUG_OFF -static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlog.trace"; -#endif - -static struct option long_options[] = -{ -#ifndef DBUG_OFF - {"debug", optional_argument, 0, '#'}, -#endif - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, - {"offset", required_argument, 0, 'o'}, - {"password", required_argument, 0, 'p'}, - {"port", required_argument, 0, 'P'}, - {"position", required_argument, 0, 'j'}, - {"result-file", required_argument, 0, 'r'}, - {"short-form", no_argument, 0, 's'}, - {"table", required_argument, 0, 't'}, - {"user", required_argument, 0, 'u'}, - {"version", no_argument, 0, 'V'}, -}; - -void sql_print_error(const char *format,...); - -static bool short_form = 0; -static ulonglong offset = 0; -static const char* host = "localhost"; -static int port = MYSQL_PORT; -static const char* user = "test"; -static const char* pass = ""; -static ulonglong position = 0; -static bool use_remote = 0; -static short binlog_flags = 0; -static MYSQL* mysql = NULL; -static const char* table = 0; - -static void dump_local_log_entries(const char* logname); -static void dump_remote_log_entries(const char* logname); -static void dump_log_entries(const char* logname); -static void dump_remote_file(NET* net, const char* fname); -static void dump_remote_table(NET* net, const char* db, const char* table); -static void die(const char* fmt, ...); -static MYSQL* safe_connect(); - - -void sql_print_error(const char *format,...) -{ - va_list args; - va_start(args, format); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - va_end(args); -} - -static void die(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - fprintf(stderr, "ERROR: "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - exit(1); -} - -static void print_version() -{ - printf("%s Ver 1.4 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); -} - - -static void usage() -{ - print_version(); - puts("By Sasha, for your professional use\n\ -This software comes with NO WARRANTY: see the file PUBLIC for details\n"); - - printf("\ -Dumps a MySQL binary log in a format usable for viewing or for pipeing to\n\ -the mysql command line client\n\n"); - printf("Usage: %s [options] log-files\n",my_progname); - puts("Options:"); -#ifndef DBUG_OFF - printf("-#, --debug[=...] Output debug log. (%s)\n", - default_dbug_option); -#endif - printf("\ --?, --help Display this help and exit\n\ --s, --short-form Just show the queries, no extra info\n\ --o, --offset=N Skip the first N entries\n\ --h, --host=server Get the binlog from server\n\ --P, --port=port Use port to connect to the remote server\n\ --u, --user=username Connect to the remove server as username\n\ --p, --password=password Password to connect to remote server\n\ --r, --result-file=file Direct output to a given file\n\ --j, --position=N Start reading the binlog at position N\n\ --t, --table=name Get raw table dump using COM_TABLE_DUMB\n\ --V, --version Print version and exit.\n\ -"); -} - -static void dump_remote_file(NET* net, const char* fname) -{ - char buf[FN_REFLEN+1]; - uint len = (uint) strlen(fname); - buf[0] = 0; - memcpy(buf + 1, fname, len + 1); - if(my_net_write(net, buf, len +2) || net_flush(net)) - die("Failed requesting the remote dump of %s", fname); - for(;;) - { - uint packet_len = my_net_read(net); - if(packet_len == 0) - { - if(my_net_write(net, "", 0) || net_flush(net)) - die("Failed sending the ack packet"); - - // we just need to send something, as the server will read but - // not examine the packet - this is because mysql_load() sends an OK when it is done - break; - } - else if(packet_len == packet_error) - die("Failed reading a packet during the dump of %s ", fname); - - if(!short_form) - (void)my_fwrite(result_file, (byte*) net->read_pos, packet_len,MYF(0)); - } - - fflush(result_file); -} - -static int parse_args(int *argc, char*** argv) -{ - int c, opt_index = 0; - - result_file = stdout; - while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:r:t:?V", long_options, - &opt_index)) != EOF) - { - switch(c) - { -#ifndef DBUG_OFF - case '#': - DBUG_PUSH(optarg ? optarg : default_dbug_option); - break; -#endif - case 's': - short_form = 1; - break; - - case 'o': - offset = strtoull(optarg,(char**) 0, 10); - break; - - case 'j': - position = strtoull(optarg,(char**) 0, 10); - break; - - case 'h': - use_remote = 1; - host = my_strdup(optarg, MYF(0)); - break; - - case 'P': - use_remote = 1; - port = atoi(optarg); - break; - - case 'p': - use_remote = 1; - pass = my_strdup(optarg, MYF(0)); - break; - - case 'r': - if (!(result_file = my_fopen(optarg, O_WRONLY | O_BINARY, MYF(MY_WME)))) - exit(1); - break; - - case 'u': - use_remote = 1; - user = my_strdup(optarg, MYF(0)); - break; - - case 't': - table = my_strdup(optarg, MYF(0)); - break; - - case 'V': - print_version(); - exit(0); - - case '?': - default: - usage(); - exit(0); - - } - } - - (*argc)-=optind; - (*argv)+=optind; - - return 0; -} - -static MYSQL* safe_connect() -{ - MYSQL *local_mysql = mc_mysql_init(NULL); - if(!local_mysql) - die("Failed on mc_mysql_init"); - - if(!mc_mysql_connect(local_mysql, host, user, pass, 0, port, 0, 0)) - die("failed on connect: %s", mc_mysql_error(local_mysql)); - - return local_mysql; -} - -static void dump_log_entries(const char* logname) -{ - if(use_remote) - dump_remote_log_entries(logname); - else - dump_local_log_entries(logname); -} - -static void dump_remote_table(NET* net, const char* db, const char* table) -{ - char buf[1024]; - char * p = buf; - uint table_len = (uint) strlen(table); - uint db_len = (uint) strlen(db); - if(table_len + db_len > sizeof(buf) - 2) - die("Buffer overrun"); - - *p++ = db_len; - memcpy(p, db, db_len); - p += db_len; - *p++ = table_len; - memcpy(p, table, table_len); - - if(mc_simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1)) - die("Error sending the table dump command"); - - for(;;) - { - uint packet_len = my_net_read(net); - if(packet_len == 0) break; // end of file - if(packet_len == packet_error) - die("Error reading packet in table dump"); - my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME)); - fflush(result_file); - } -} - - -static void dump_remote_log_entries(const char* logname) -{ - char buf[128]; - char last_db[FN_REFLEN+1] = ""; - uint len; - NET* net = &mysql->net; - if(!position) position = 4; // protect the innocent from spam - if (position < 4) - { - position = 4; - // warn the guity - sql_print_error("Warning: The position in the binary log can't be less than 4.\nStarting from position 4\n"); - } - int4store(buf, position); - int2store(buf + 4, binlog_flags); - len = (uint) strlen(logname); - int4store(buf + 6, 0); - memcpy(buf + 10, logname,len); - if(mc_simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1)) - die("Error sending the log dump command"); - - for(;;) - { - len = mc_net_safe_read(mysql); - if (len == packet_error) - die("Error reading packet from server: %s", mc_mysql_error(mysql)); - if(len == 1 && net->read_pos[0] == 254) - break; // end of data - DBUG_PRINT("info",( "len= %u, net->read_pos[5] = %d\n", - len, net->read_pos[5])); - Log_event * ev = Log_event::read_log_event( - (const char*) net->read_pos + 1 , - len - 1); - if(ev) - { - ev->print(result_file, short_form, last_db); - if(ev->get_type_code() == LOAD_EVENT) - dump_remote_file(net, ((Load_log_event*)ev)->fname); - delete ev; - } - else - die("Could not construct log event object"); - } -} - -static void dump_local_log_entries(const char* logname) -{ - File fd = -1; - IO_CACHE cache,*file= &cache; - ulonglong rec_count = 0; - char last_db[FN_REFLEN+1] = ""; - - if (logname && logname[0] != '-') - { - if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) - exit(1); - if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0, - MYF(MY_WME | MY_NABP))) - exit(1); - } - else - { - if (init_io_cache(file, fileno(result_file), 0, READ_CACHE, (my_off_t) 0, - 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) - exit(1); - if (position) - { - /* skip 'position' characters from stdout */ - byte buff[IO_SIZE]; - my_off_t length,tmp; - for (length= (my_off_t) position ; length > 0 ; length-=tmp) - { - tmp=min(length,sizeof(buff)); - if (my_b_read(file,buff, (uint) tmp)) - exit(1); - } - } - file->pos_in_file=position; - file->seek_not_done=0; - } - - if (!position) - { - char magic[4]; - if (my_b_read(file, (byte*) magic, sizeof(magic))) - die("I/O error reading binlog magic number"); - if(memcmp(magic, BINLOG_MAGIC, 4)) - die("Bad magic number; The file is probably not a MySQL binary log"); - } - - for (;;) - { - char llbuff[21]; - my_off_t old_off = my_b_tell(file); - - Log_event* ev = Log_event::read_log_event(file, 0); - if (!ev) - { - if (file->error) - die("\ -Could not read entry at offset %s : Error in log format or read error", - llstr(old_off,llbuff)); - // file->error == 0 means EOF, that's OK, we break in this case - break; - } - if (rec_count >= offset) - { - if (!short_form) - fprintf(result_file, "# at %s\n",llstr(old_off,llbuff)); - - ev->print(result_file, short_form, last_db); - } - rec_count++; - delete ev; - } - if(fd >= 0) - my_close(fd, MYF(MY_WME)); - end_io_cache(file); -} - - -int main(int argc, char** argv) -{ - MY_INIT(argv[0]); - parse_args(&argc, (char***)&argv); - - if(!argc && !table) - { - usage(); - return -1; - } - - if(use_remote) - { -#ifndef __WIN__ - init_thr_alarm(10); // need to do this manually -#endif - mysql = safe_connect(); - } - - if (table) - { - if(!use_remote) - die("You must specify connection parameter to get table dump"); - char* db = (char*)table; - char* tbl = (char*) strchr(table, '.'); - if(!tbl) - die("You must use database.table syntax to specify the table"); - *tbl++ = 0; - dump_remote_table(&mysql->net, db, tbl); - } - else - { - while(--argc >= 0) - { - dump_log_entries(*(argv++)); - } - } - if (result_file != stdout) - my_fclose(result_file, MYF(0)); - if (use_remote) - mc_mysql_close(mysql); - return 0; -} - -/* - We must include this here as it's compiled with different options for - the server -*/ - -#include "log_event.cc" diff --git a/sql/mysqld.cc b/sql/mysqld.cc index dad4a1c2427..09c464dd15b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -220,7 +220,7 @@ static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; static pthread_t select_thread; static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, - opt_ansi_mode=0,opt_myisam_log=0, + opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0, opt_show_slave_auth_info = 0, opt_old_rpl_compat = 0; @@ -320,6 +320,7 @@ char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; const char *first_keyword="first"; const char **errmesg; /* Error messages */ const char *myisam_recover_options_str="OFF"; +const char *sql_mode_str="OFF"; const char *default_tx_isolation_name; enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED; @@ -333,6 +334,12 @@ double log_10[32]; /* 10 potences */ I_List<THD> threads,thread_cache; time_t start_time; +ulong opt_sql_mode = 0L; +const char *sql_mode_names[] = +{ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", + "SERIALIZE","ONLY_FULL_GROUP_BY", NullS }; +TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"", + sql_mode_names}; MY_BITMAP temp_pool; bool use_temp_pool=0; @@ -1525,7 +1532,7 @@ static void open_log(MYSQL_LOG *log, const char *hostname, // get rid of extention if the log is binary to avoid problems if (type == LOG_BIN) { - char* p = strrchr(opt_name, FN_EXTCHAR); + char* p = strrchr((char*) opt_name, FN_EXTCHAR); if (p) *p = 0; } @@ -2520,6 +2527,7 @@ enum options { OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT, + OPT_SQL_MODE, OPT_SLAVE_LOAD_TMPDIR}; static struct option long_options[] = { @@ -2664,6 +2672,7 @@ static struct option long_options[] = { {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR}, {"slave-load-tmpdir", required_argument, 0, (int) OPT_SLAVE_LOAD_TMPDIR}, {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, + {"sql-mode", required_argument, 0, (int) OPT_SQL_MODE}, #include "sslopt-longopts.h" #ifdef __WIN__ {"standalone", no_argument, 0, (int) OPT_STANDALONE}, @@ -2832,7 +2841,6 @@ CHANGEABLE_VAR changeable_vars[] = { struct show_var_st init_vars[]= { - {"ansi_mode", (char*) &opt_ansi_mode, SHOW_BOOL}, {"back_log", (char*) &back_log, SHOW_LONG}, {"basedir", mysql_home, SHOW_CHAR}, #ifdef HAVE_BERKELEY_DB @@ -2939,6 +2947,7 @@ struct show_var_st init_vars[]= { {"slow_launch_time", (char*) &slow_launch_time, SHOW_LONG}, {"socket", (char*) &mysql_unix_port, SHOW_CHAR_PTR}, {"sort_buffer", (char*) &sortbuff_size, SHOW_LONG}, + {"sql_mode", (char*) &sql_mode_str, SHOW_CHAR_PTR}, {"table_cache", (char*) &table_cache_size, SHOW_LONG}, {"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR}, {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG}, @@ -3122,6 +3131,9 @@ static void usage(void) Don't give threads different priorities.\n\ --socket=... Socket file to use for connection\n\ -t, --tmpdir=path Path for temporary files\n\ + --sql-mode=option[,option[,option...]] where option can be one of:\n\ + REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES,\n\ + IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY.\n\ --transaction-isolation\n\ Default transaction isolation level\n\ --temp-pool Use a pool of temporary files\n\ @@ -3277,8 +3289,9 @@ static void get_options(int argc,char **argv) opt_warnings=1; break; case 'a': - opt_ansi_mode=1; - thd_startup_options|=OPTION_ANSI_MODE; + opt_sql_mode = (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | + MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | MODE_SERIALIZABLE + | MODE_ONLY_FULL_GROUP_BY); default_tx_isolation= ISO_SERIALIZABLE; break; case 'b': diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d0ff5d962db..13c673fdb33 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -125,6 +125,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), server_status=SERVER_STATUS_AUTOCOMMIT; update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE; options=thd_startup_options; + sql_mode=(uint) opt_sql_mode; inactive_timeout=net_wait_timeout; open_options=ha_open_options; tx_isolation=session_tx_isolation=default_tx_isolation; diff --git a/sql/sql_class.h b/sql/sql_class.h index 3f212a8f8c6..d149f087c1f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -240,7 +240,7 @@ public: char *query,*thread_stack; char *host,*user,*priv_user,*db,*ip; const char *proc_info; - uint client_capabilities,max_packet_length; + uint client_capabilities,sql_mode,max_packet_length; uint master_access,db_access; TABLE *open_tables,*temporary_tables, *handler_tables; MYSQL_LOCK *lock,*locked_tables; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 8f77931a05f..0e77757b13b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -121,7 +121,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 (thd_startup_options & OPTION_ANSI_MODE) + if (opt_sql_mode & MODE_ANSI_QUOTES) { state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER; } @@ -149,7 +149,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->select->ftfunc_list.empty(); lex->convert_set=(lex->thd=thd)->convert_set; lex->yacc_yyss=lex->yacc_yyvs=0; - lex->ignore_space=test(thd->client_capabilities & CLIENT_IGNORE_SPACE); + lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); return lex; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6c3205c2feb..1655d54e9fc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -417,6 +417,8 @@ check_connections(THD *thd) return(ER_OUT_OF_RESOURCES); thd->client_capabilities=uint2korr(net->read_pos); + if (thd->client_capabilities & CLIENT_IGNORE_SPACE) + thd->sql_mode|= MODE_IGNORE_SPACE; #ifdef HAVE_OPENSSL DBUG_PRINT("info", ("pkt_len:%d, client capabilities: %d", @@ -541,8 +543,6 @@ pthread_handler_decl(handle_one_connection,arg) thd->options |= OPTION_BIG_SELECTS; if (thd->client_capabilities & CLIENT_COMPRESS) net->compress=1; // Use compression - if (thd->options & OPTION_ANSI_MODE) - thd->client_capabilities|=CLIENT_IGNORE_SPACE; thd->proc_info=0; // Remove 'login' thd->command=COM_SLEEP; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cd6caf213f8..3a1d36796b2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2701,12 +2701,12 @@ static void update_depend_map(JOIN *join) for (i=0 ; i < ref->key_parts ; i++,item++) depend_map|=(*item)->used_tables(); ref->depend_map=depend_map; - for (JOIN_TAB *join_tab2=join->join_tab; + for (JOIN_TAB **tab=join->map2table; depend_map ; - join_tab2++,depend_map>>=1 ) + tab++,depend_map>>=1 ) { if (depend_map & 1) - ref->depend_map|=join_tab2->ref.depend_map; + ref->depend_map|=(*tab)->ref.depend_map; } } } @@ -2723,12 +2723,12 @@ static void update_depend_map(JOIN *join, ORDER *order) order->depend_map=depend_map=order->item[0]->used_tables(); if (!(order->depend_map & RAND_TABLE_BIT)) // Not item_sum() or RAND() { - for (JOIN_TAB *join_tab=join->join_tab; + for (JOIN_TAB **tab=join->map2table; depend_map ; - join_tab++, depend_map>>=1) + tab++, depend_map>>=1) { if (depend_map & 1) - order->depend_map|=join_tab->ref.depend_map; + order->depend_map|=(*tab)->ref.depend_map; } } } @@ -5552,6 +5552,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, { if ((error=file->delete_row(record))) goto err; + error=file->rnd_next(record); continue; } if (copy_blobs(first_field)) @@ -6063,7 +6064,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields, if (!order) return 0; /* Everything is ok */ - if (thd->options & OPTION_ANSI_MODE) + if (thd->sql_mode & MODE_ONLY_FULL_GROUP_BY) { Item *item; List_iterator<Item> li(fields); @@ -6085,7 +6086,7 @@ setup_group(THD *thd,TABLE_LIST *tables,List<Item> &fields, return 1; } } - if (thd->options & OPTION_ANSI_MODE) + if (thd->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_yacc.yy b/sql/sql_yacc.yy index c6ae2241603..5537206089b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -35,7 +35,7 @@ int yylex(void *yylval); inline Item *or_or_concat(Item* A, Item* B) { - return (current_thd->options & OPTION_ANSI_MODE ? + return (current_thd->sql_mode & MODE_PIPES_AS_CONCAT ? (Item*) new Item_func_concat(A,B) : (Item*) new Item_cond_or(A,B)); } @@ -949,7 +949,7 @@ int_type: | BIGINT { $$=FIELD_TYPE_LONGLONG; } real_type: - REAL { $$= current_thd->options & OPTION_ANSI_MODE ? + REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; } |