summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorsasha@mysql.sashanet.com <>2001-08-09 19:16:15 -0600
committersasha@mysql.sashanet.com <>2001-08-09 19:16:15 -0600
commitf6836bf81abb42523349ac6cf0b8807fa9e69c3e (patch)
treeed06f905f1515a2117cc0c243c526264fccaac77 /sql
parentd9737f20f838f189ef1f3d25df7739770f3b52b9 (diff)
parentbe4f7bbdcf89e5fa2a9e8193cda1d317918d7d07 (diff)
downloadmariadb-git-f6836bf81abb42523349ac6cf0b8807fa9e69c3e.tar.gz
merged
Diffstat (limited to 'sql')
-rw-r--r--sql/Makefile.am6
-rw-r--r--sql/ha_berkeley.cc23
-rw-r--r--sql/ha_berkeley.h3
-rw-r--r--sql/ha_innobase.cc41
-rw-r--r--sql/ha_innobase.h1
-rw-r--r--sql/ha_myisam.cc2
-rw-r--r--sql/item_func.cc20
-rw-r--r--sql/log_event.cc19
-rw-r--r--sql/log_event.h5
-rw-r--r--sql/mysql_priv.h7
-rw-r--r--sql/mysqlbinlog.cc469
-rw-r--r--sql/mysqld.cc23
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_lex.cc4
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc17
-rw-r--r--sql/sql_yacc.yy4
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; }