summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/Makefile.am6
-rw-r--r--sql/examples/ha_archive.cc60
-rw-r--r--sql/examples/ha_archive.h4
-rw-r--r--sql/field.cc109
-rw-r--r--sql/field.h4
-rw-r--r--sql/filesort.cc4
-rw-r--r--sql/ha_federated.cc296
-rwxr-xr-xsql/ha_federated.h8
-rw-r--r--sql/ha_innodb.cc5
-rw-r--r--sql/ha_ndbcluster.cc77
-rw-r--r--sql/ha_ndbcluster.h1
-rw-r--r--sql/handler.cc14
-rw-r--r--sql/item_create.cc5
-rw-r--r--sql/item_sum.cc6
-rw-r--r--sql/item_timefunc.cc17
-rw-r--r--sql/key.cc4
-rw-r--r--sql/mysql_priv.h9
-rw-r--r--sql/mysqld.cc19
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/set_var.cc14
-rw-r--r--sql/set_var.h2
-rw-r--r--sql/share/Makefile.am5
-rw-r--r--sql/sql_acl.cc4
-rw-r--r--sql/sql_analyse.cc40
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_help.cc7
-rw-r--r--sql/sql_insert.cc47
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_select.cc11
-rw-r--r--sql/sql_show.cc18
-rw-r--r--sql/table.cc6
31 files changed, 553 insertions, 254 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 8ff55898ba4..3c520ac971c 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -22,7 +22,7 @@ MYSQLBASEdir= $(prefix)
INCLUDES = @MT_INCLUDES@ @ZLIB_INCLUDES@ \
@bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \
-I$(top_srcdir)/include -I$(top_srcdir)/regex \
- -I$(srcdir) $(openssl_includes) -I$(top_srcdir)/extra
+ -I$(srcdir) $(openssl_includes) -I$(top_builddir)/include
WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
@@ -115,6 +115,7 @@ DEFS = -DMYSQL_SERVER \
# Don't put lex_hash.h in BUILT_SOURCES as this will give infinite recursion
BUILT_SOURCES = sql_yacc.cc sql_yacc.h
EXTRA_DIST = udf_example.cc $(BUILT_SOURCES)
+DISTCLEANFILES = lex_hash.h
AM_YFLAGS = -d
mysql_tzinfo_to_sql.cc:
@@ -160,8 +161,5 @@ sql_lex.o: lex_hash.h
udf_example.so: udf_example.cc
$(CXXCOMPILE) -shared -o $@ $<
-distclean:
- rm -f lex_hash.h
-
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc
index dccff88bf1f..436c72702a0 100644
--- a/sql/examples/ha_archive.cc
+++ b/sql/examples/ha_archive.cc
@@ -117,7 +117,6 @@
/* Variables for archive share methods */
pthread_mutex_t archive_mutex;
static HASH archive_open_tables;
-static int archive_init= 0;
/* The file extension */
#define ARZ ".ARZ" // The data file
@@ -143,6 +142,46 @@ static byte* archive_get_key(ARCHIVE_SHARE *share,uint *length,
return (byte*) share->table_name;
}
+
+/*
+ Initialize the archive handler.
+
+ SYNOPSIS
+ archive_db_init()
+ void
+
+ RETURN
+ FALSE OK
+ TRUE Error
+*/
+
+bool archive_db_init()
+{
+ VOID(pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST));
+ return (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
+ (hash_get_key) archive_get_key, 0, 0));
+}
+
+
+/*
+ Release the archive handler.
+
+ SYNOPSIS
+ archive_db_end()
+ void
+
+ RETURN
+ FALSE OK
+*/
+
+bool archive_db_end()
+{
+ hash_free(&archive_open_tables);
+ VOID(pthread_mutex_destroy(&archive_mutex));
+ return FALSE;
+}
+
+
/*
This method reads the header of a datafile and returns whether or not it was successful.
*/
@@ -269,23 +308,6 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
uint length;
char *tmp_name;
- if (!archive_init)
- {
- /* Hijack a mutex for init'ing the storage engine */
- pthread_mutex_lock(&LOCK_mysql_create_db);
- if (!archive_init)
- {
- VOID(pthread_mutex_init(&archive_mutex,MY_MUTEX_INIT_FAST));
- if (hash_init(&archive_open_tables,system_charset_info,32,0,0,
- (hash_get_key) archive_get_key,0,0))
- {
- pthread_mutex_unlock(&LOCK_mysql_create_db);
- return NULL;
- }
- archive_init++;
- }
- pthread_mutex_unlock(&LOCK_mysql_create_db);
- }
pthread_mutex_lock(&archive_mutex);
length=(uint) strlen(table_name);
@@ -371,6 +393,7 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
(void)write_meta_file(share->meta_file, share->rows_recorded, FALSE);
if (gzclose(share->archive_write) == Z_ERRNO)
rc= 1;
+ my_close(share->meta_file,MYF(0));
my_free((gptr) share, MYF(0));
}
pthread_mutex_unlock(&archive_mutex);
@@ -787,6 +810,7 @@ int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt)
goto error;
}
(void)write_meta_file(meta_file, rows_recorded, TRUE);
+ my_close(meta_file,MYF(0));
rc= 0;
}
diff --git a/sql/examples/ha_archive.h b/sql/examples/ha_archive.h
index 07bc7baa400..a511b5c67d6 100644
--- a/sql/examples/ha_archive.h
+++ b/sql/examples/ha_archive.h
@@ -105,3 +105,7 @@ public:
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
};
+
+bool archive_db_init(void);
+bool archive_db_end(void);
+
diff --git a/sql/field.cc b/sql/field.cc
index 7d0e69681c0..aa2c5805bfe 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -524,6 +524,115 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
return tmp;
}
+/*
+ SYNOPSIS
+ Field::quote_data()
+ unquoted_string Pointer pointing to the value of a field
+
+ DESCRIPTION
+ Simple method that passes the field type to the method "type_quote"
+ To get a true/false value as to whether the value in string1 needs
+ to be enclosed with quotes. This ensures that values in the final
+ sql statement to be passed to the remote server will be quoted properly
+
+ RETURN_VALUE
+ void Immediately - if string doesn't need quote
+ void Upon prepending/appending quotes on each side of variable
+
+*/
+bool Field::quote_data(String *unquoted_string)
+{
+ char escaped_string[IO_SIZE];
+ char *unquoted_string_buffer= (char *)(unquoted_string->ptr());
+ uint need_quotes;
+
+ DBUG_ENTER("Field::quote_data");
+ // this is the same call that mysql_real_escape_string() calls
+ escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
+ unquoted_string->ptr(), unquoted_string->length());
+
+
+ if (is_null())
+ DBUG_RETURN(0);
+
+ need_quotes= needs_quotes();
+
+ if (need_quotes == 0)
+ {
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ // reset string, then re-append with quotes and escaped values
+ unquoted_string->length(0);
+ if (unquoted_string->append("'"))
+ DBUG_RETURN(1);
+ if (unquoted_string->append((char *)escaped_string))
+ DBUG_RETURN(1);
+ if (unquoted_string->append("'"))
+ DBUG_RETURN(1);
+ }
+ //DBUG_PRINT("Field::quote_data",
+ // ("FINAL quote_flag %d unquoted_string %s escaped_string %s",
+ //needs_quotes, unquoted_string->c_ptr_quick(), escaped_string));
+ DBUG_RETURN(0);
+}
+
+/*
+ Quote a field type if needed
+
+ SYNOPSIS
+ Field::type_quote
+
+ DESCRIPTION
+ Simple method to give true/false whether a field should be quoted.
+ Used when constructing INSERT and UPDATE queries to the remote server
+ see write_row and update_row
+
+ RETURN VALUE
+ 0 if value is of type NOT needing quotes
+ 1 if value is of type needing quotes
+*/
+bool Field::needs_quotes(void)
+{
+ DBUG_ENTER("Field::type_quote");
+
+ switch(type()) {
+ //FIX this when kernel is fixed
+ case MYSQL_TYPE_VARCHAR :
+ case FIELD_TYPE_STRING :
+ case FIELD_TYPE_VAR_STRING :
+ case FIELD_TYPE_YEAR :
+ case FIELD_TYPE_NEWDATE :
+ case FIELD_TYPE_TIME :
+ case FIELD_TYPE_TIMESTAMP :
+ case FIELD_TYPE_DATE :
+ case FIELD_TYPE_DATETIME :
+ case FIELD_TYPE_TINY_BLOB :
+ case FIELD_TYPE_BLOB :
+ case FIELD_TYPE_MEDIUM_BLOB :
+ case FIELD_TYPE_LONG_BLOB :
+ case FIELD_TYPE_GEOMETRY :
+ DBUG_RETURN(1);
+
+ case FIELD_TYPE_DECIMAL :
+ case FIELD_TYPE_TINY :
+ case FIELD_TYPE_SHORT :
+ case FIELD_TYPE_INT24 :
+ case FIELD_TYPE_LONG :
+ case FIELD_TYPE_FLOAT :
+ case FIELD_TYPE_DOUBLE :
+ case FIELD_TYPE_LONGLONG :
+ case FIELD_TYPE_NULL :
+ case FIELD_TYPE_SET :
+ case FIELD_TYPE_ENUM :
+ DBUG_RETURN(0);
+
+ default: DBUG_RETURN(0);
+ }
+ DBUG_RETURN(0);
+
+}
/****************************************************************************
Field_null, a field that always return NULL
diff --git a/sql/field.h b/sql/field.h
index fd1ef09d14f..af300c8d471 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -228,6 +228,8 @@ public:
ptr= old_ptr;
return str;
}
+ bool quote_data(String *unquoted_string);
+ bool needs_quotes(void);
virtual bool send_binary(Protocol *protocol);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
@@ -1228,7 +1230,7 @@ public:
int cmp(const char *a, const char *b)
{ return cmp_binary(a, b); }
int key_cmp(const byte *a, const byte *b)
- { return cmp_binary(a, b); }
+ { return cmp_binary((char *) a, (char *) b); }
int key_cmp(const byte *str, uint length);
int cmp_offset(uint row_offset);
void get_key_image(char *buff, uint length, imagetype type);
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 21f75fa5ea0..c4dbb82d8a5 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1184,7 +1184,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
{
sortorder->need_strxnfrm= 1;
*multi_byte_charset= 1;
- sortorder->length= sortorder->length*cs->strxfrm_multiply;
+ sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
}
}
if (sortorder->field->maybe_null())
@@ -1197,7 +1197,7 @@ sortlength(SORT_FIELD *sortorder, uint s_length, bool *multi_byte_charset)
sortorder->length=sortorder->item->max_length;
if (use_strnxfrm((cs=sortorder->item->collation.collation)))
{
- sortorder->length= sortorder->length*cs->strxfrm_multiply;
+ sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
sortorder->need_strxnfrm= 1;
*multi_byte_charset= 1;
}
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index ea8633febe6..5185e0bbe9a 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -123,8 +123,8 @@
ha_federated::write_row
<for every field/column>
- ha_federated::quote_data
- ha_federated::quote_data
+ Field::quote_data
+ Field::quote_data
</for every field/column>
ha_federated::reset
@@ -136,18 +136,18 @@
ha_federated::index_init
ha_federated::index_read
ha_federated::index_read_idx
- ha_federated::quote_data
+ Field::quote_data
ha_federated::rnd_next
ha_federated::convert_row_to_internal_format
ha_federated::update_row
<quote 3 cols, new and old data>
- <ha_federated::quote_data
- <ha_federated::quote_data
- <ha_federated::quote_data
- <ha_federated::quote_data
- <ha_federated::quote_data
- <ha_federated::quote_data
+ Field::quote_data
+ Field::quote_data
+ Field::quote_data
+ Field::quote_data
+ Field::quote_data
+ Field::quote_data
</quote 3 cols, new and old data>
ha_federated::extra
@@ -415,7 +415,7 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, uint table_create_fla
share->scheme= my_strdup(table->s->comment, MYF(0));
- if (share->username= strstr(share->scheme, "://"))
+ if ((share->username= strstr(share->scheme, "://")))
{
share->scheme[share->username - share->scheme] = '\0';
if (strcmp(share->scheme, "mysql") != 0)
@@ -429,18 +429,18 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, uint table_create_fla
}
share->username+= 3;
- if (share->hostname= strchr(share->username, '@'))
+ if ((share->hostname= strchr(share->username, '@')))
{
share->username[share->hostname - share->username]= '\0';
share->hostname++;
- if (share->password= strchr(share->username, ':'))
+ if ((share->password= strchr(share->username, ':')))
{
share->username[share->password - share->username]= '\0';
share->password++;
share->username= share->username;
// make sure there isn't an extra / or @
- if (strchr(share->password, '/') || strchr(share->hostname, '@'))
+ if ((strchr(share->password, '/') || strchr(share->hostname, '@')))
{
DBUG_PRINT("ha_federated::parse_url",
("this connection string is not in the correct format!!!\n"));
@@ -453,14 +453,14 @@ static int parse_url(FEDERATED_SHARE *share, TABLE *table, uint table_create_fla
user:@hostname:port/database/table
Then password is a null string, so set to NULL
*/
- if (share->password[0] == '\0')
+ if ((share->password[0] == '\0'))
share->password= NULL;
}
else
share->username= share->username;
// make sure there isn't an extra / or @
- if (strchr(share->username, '/') || strchr(share->hostname, '@'))
+ if ((strchr(share->username, '/')) || (strchr(share->hostname, '@')))
{
DBUG_PRINT("ha_federated::parse_url",
("this connection string is not in the correct format!!!\n"));
@@ -469,12 +469,12 @@ Then password is a null string, so set to NULL
DBUG_RETURN(-1);
}
- if (share->database= strchr(share->hostname, '/'))
+ if ((share->database= strchr(share->hostname, '/')))
{
share->hostname[share->database - share->hostname]= '\0';
share->database++;
- if (share->sport= strchr(share->hostname, ':'))
+ if ((share->sport= strchr(share->hostname, ':')))
{
share->hostname[share->sport - share->hostname]= '\0';
share->sport++;
@@ -484,7 +484,7 @@ Then password is a null string, so set to NULL
share->port= atoi(share->sport);
}
- if (share->table_base_name= strchr(share->database, '/'))
+ if ((share->table_base_name= strchr(share->database, '/')))
{
share->database[share->table_base_name - share->database]= '\0';
share->table_base_name++;
@@ -507,7 +507,7 @@ Then password is a null string, so set to NULL
DBUG_RETURN(-1);
}
// make sure there's not an extra /
- if (strchr(share->table_base_name, '/'))
+ if ((strchr(share->table_base_name, '/')))
{
DBUG_PRINT("ha_federated::parse_url",
("this connection string is not in the correct format!!!\n"));
@@ -586,126 +586,117 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
DBUG_RETURN(0);
}
-/*
- SYNOPSIS
- quote_data()
- unquoted_string Pointer pointing to the value of a field
- field MySQL Field pointer to field being checked for type
-
- DESCRIPTION
- Simple method that passes the field type to the method "type_quote"
- To get a true/false value as to whether the value in string1 needs
- to be enclosed with quotes. This ensures that values in the final
- sql statement to be passed to the remote server will be quoted properly
-
- RETURN_VALUE
- void Immediately - if string doesn't need quote
- void Upon prepending/appending quotes on each side of variable
-
-*/
-void ha_federated::quote_data(String *unquoted_string, Field *field )
+bool ha_federated::create_where_from_key(
+ String *to,
+ KEY *key_info,
+ const byte *key,
+ uint key_length
+ )
{
- char escaped_string[IO_SIZE];
- char *unquoted_string_buffer;
-
- unquoted_string_buffer= unquoted_string->c_ptr_quick();
-
- int quote_flag;
- DBUG_ENTER("ha_federated::quote_data");
- // this is the same call that mysql_real_escape_string() calls
- escape_string_for_mysql(&my_charset_bin, (char *)escaped_string,
- unquoted_string->c_ptr_quick(), unquoted_string->length());
-
- DBUG_PRINT("ha_federated::quote_data",
- ("escape_string_for_mysql unescaped %s escaped %s",
- unquoted_string->c_ptr_quick(), escaped_string));
-
- if (field->is_null())
- {
- DBUG_PRINT("ha_federated::quote_data",
- ("NULL, no quoted needed for unquoted_string %s, returning.",
- unquoted_string->c_ptr_quick()));
- DBUG_VOID_RETURN;
- }
+ uint second_loop= 0;
+ KEY_PART_INFO *key_part;
+ bool needs_quotes;
- quote_flag= type_quote(field->type());
-
- if (quote_flag == 0)
- {
- DBUG_PRINT("ha_federated::quote_data",
- ("quote flag 0 no quoted needed for unquoted_string %s, returning.",
- unquoted_string->c_ptr_quick()));
- DBUG_VOID_RETURN;
- }
- else
+ DBUG_ENTER("ha_federated::create_where_from_key");
+ for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++)
{
- // reset string, then re-append with quotes and escaped values
- unquoted_string->length(0);
- unquoted_string->append("'");
- unquoted_string->append((char *)escaped_string);
- unquoted_string->append("'");
- }
- DBUG_PRINT("ha_federated::quote_data",
- ("FINAL quote_flag %d unquoted_string %s escaped_string %s",
- quote_flag, unquoted_string->c_ptr_quick(), escaped_string));
- DBUG_VOID_RETURN;
-}
-
-/*
- Quote a field type if needed
+ Field *field= key_part->field;
+ needs_quotes= field->needs_quotes();
+ //bool needs_quotes= type_quote(field->type());
+ DBUG_PRINT("ha_federated::create_where_from_key", ("key name %s type %d", field->field_name, field->type()));
+ uint length= key_part->length;
+
+ if (second_loop++ && to->append(" AND ",5))
+ DBUG_RETURN(1);
+ if (to->append('`') || to->append(field->field_name) ||
+ to->append("` ",2))
+ DBUG_RETURN(1); // Out of memory
+
+ if (key_part->null_bit)
+ {
+ if (*key++)
+ {
+ if (to->append("IS NULL",7))
+ DBUG_PRINT("ha_federated::create_where_from_key", ("NULL type %s", to->c_ptr_quick()));
+ DBUG_RETURN(1);
+ key_length-= key_part->store_length;
+ key+= key_part->store_length-1;
+ continue;
+ }
+ key_length--;
+ }
+ if (to->append("= "))
+ DBUG_RETURN(1);
+ if (needs_quotes && to->append("'"))
+ DBUG_RETURN(1);
+ if (key_part->type == HA_KEYTYPE_BIT)
+ {
+ /* This is can be threated as a hex string */
+ Field_bit *field= (Field_bit *) (key_part->field);
+ char buff[64+2], *ptr;
+ byte *end= (byte *)(key) + length;
+
+ buff[0]='0';
+ buff[1]='x';
+ for (ptr= buff+2 ; key < end ; key++)
+ {
+ uint tmp= (uint) (uchar) *key;
+ *ptr++=_dig_vec_upper[tmp >> 4];
+ *ptr++=_dig_vec_upper[tmp & 15];
+ }
+ if (to->append(buff, (uint) (ptr-buff)))
+ DBUG_RETURN(1);
- SYNOPSIS
- ha_federated::type_quote
- int field Enumerated field type number
+ DBUG_PRINT("ha_federated::create_where_from_key", ("bit type %s", to->c_ptr_quick()));
+ key_length-= length;
+ continue;
+ }
+ if (key_part->key_part_flag & HA_BLOB_PART)
+ {
+ uint blob_length= uint2korr(key);
+ key+= HA_KEY_BLOB_LENGTH;
+ key_length-= HA_KEY_BLOB_LENGTH;
+ if (append_escaped(to, (char *)(key), blob_length))
+ DBUG_RETURN(1);
+
+ DBUG_PRINT("ha_federated::create_where_from_key", ("blob type %s", to->c_ptr_quick()));
+ length= key_part->length;
+ }
+ else if (key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ length= uint2korr(key);
+ key+= HA_KEY_BLOB_LENGTH;
+ if (append_escaped(to, (char *)(key), length))
+ DBUG_RETURN(1);
- DESCRIPTION
- Simple method to give true/false whether a field should be quoted.
- Used when constructing INSERT and UPDATE queries to the remote server
- see write_row and update_row
+ DBUG_PRINT("ha_federated::create_where_from_key", ("varchar type %s", to->c_ptr_quick()));
+ }
+ else
+ {
+ DBUG_PRINT("ha_federated::create_where_from_key", ("else block, unknown type so far"));
+ char buff[MAX_FIELD_WIDTH];
+ String str(buff, sizeof(buff), field->charset()), *res;
- RETURN VALUE
- 0 if value is of type NOT needing quotes
- 1 if value is of type needing quotes
-*/
-uint ha_federated::type_quote(int type)
-{
- DBUG_ENTER("ha_federated::type_quote");
- DBUG_PRINT("ha_federated::type_quote", ("field type %d", type));
-
- switch(type) {
- //FIX this is a bug, fix when kernel is fixed
- case MYSQL_TYPE_VARCHAR :
- case FIELD_TYPE_STRING :
- case FIELD_TYPE_VAR_STRING :
- case FIELD_TYPE_YEAR :
- case FIELD_TYPE_NEWDATE :
- case FIELD_TYPE_TIME :
- case FIELD_TYPE_TIMESTAMP :
- case FIELD_TYPE_DATE :
- case FIELD_TYPE_DATETIME :
- case FIELD_TYPE_TINY_BLOB :
- case FIELD_TYPE_BLOB :
- case FIELD_TYPE_MEDIUM_BLOB :
- case FIELD_TYPE_LONG_BLOB :
- case FIELD_TYPE_GEOMETRY :
- DBUG_RETURN(1);
+ res= field->val_str(&str, (char *)(key));
+ if (field->result_type() == STRING_RESULT)
+ {
+ if (append_escaped(to, (char *) res->ptr(), res->length()))
+ DBUG_RETURN(1);
+ res= field->val_str(&str, (char *)(key));
- case FIELD_TYPE_DECIMAL :
- case FIELD_TYPE_TINY :
- case FIELD_TYPE_SHORT :
- case FIELD_TYPE_INT24 :
- case FIELD_TYPE_LONG :
- case FIELD_TYPE_FLOAT :
- case FIELD_TYPE_DOUBLE :
- case FIELD_TYPE_LONGLONG :
- case FIELD_TYPE_NULL :
- case FIELD_TYPE_SET :
- case FIELD_TYPE_ENUM :
+ DBUG_PRINT("ha_federated::create_where_from_key", ("else block, string type", to->c_ptr_quick()));
+ }
+ else if (to->append(res->ptr(), res->length()))
+ DBUG_RETURN(1);
+ }
+ if (needs_quotes && to->append("'"))
+ DBUG_RETURN(1);
+ DBUG_PRINT("ha_federated::create_where_from_key", ("final value for 'to' %s", to->c_ptr_quick()));
+ key+= length;
+ key_length-= length;
DBUG_RETURN(0);
-
- default: DBUG_RETURN(0);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
int load_conn_info(FEDERATED_SHARE *share, TABLE *table)
@@ -975,7 +966,7 @@ int ha_federated::write_row(byte * buf)
int x= 0, num_fields= 0;
Field **field;
ulong current_query_id= 1;
- ulong tmp_query_id;
+ ulong tmp_query_id= 1;
int all_fields_have_same_query_id= 1;
char insert_buffer[IO_SIZE];
@@ -1060,7 +1051,8 @@ int ha_federated::write_row(byte * buf)
insert_string.append((*field)->field_name);
// quote these fields if they require it
- quote_data(&insert_field_value_string, *field);
+
+ (*field)->quote_data(&insert_field_value_string);
// append the value
values_string.append(insert_field_value_string);
insert_field_value_string.length(0);
@@ -1068,9 +1060,10 @@ int ha_federated::write_row(byte * buf)
// append commas between both fields and fieldnames
insert_string.append(',');
values_string.append(',');
- DBUG_PRINT("ha_federated::write_row",
- ("insert_string %s values_string %s insert_field_value_string %s",
- insert_string.c_ptr_quick(), values_string.c_ptr_quick(), insert_field_value_string.c_ptr_quick()));
+ DBUG_PRINT("ha_federated::write_row",
+ ("insert_string %s values_string %s insert_field_value_string %s",
+ insert_string.c_ptr_quick(), values_string.c_ptr_quick(),
+ insert_field_value_string.c_ptr_quick()));
}
}
@@ -1137,8 +1130,8 @@ int ha_federated::update_row(
byte * new_data
)
{
- uint x= 0;
- uint has_a_primary_key;
+ int x= 0;
+ uint has_a_primary_key= 0;
int primary_key_field_num;
char old_field_value_buffer[IO_SIZE], new_field_value_buffer[IO_SIZE];
char update_buffer[IO_SIZE], where_buffer[IO_SIZE];
@@ -1205,7 +1198,7 @@ int ha_federated::update_row(
{
// otherwise =
(*field)->val_str(&new_field_value);
- quote_data(&new_field_value, *field);
+ (*field)->quote_data(&new_field_value);
if ( has_a_primary_key )
{
@@ -1223,7 +1216,7 @@ int ha_federated::update_row(
{
(*field)->val_str(&old_field_value,
(char *)(old_data + (*field)->offset()));
- quote_data(&old_field_value, *field);
+ (*field)->quote_data(&old_field_value);
where_string.append(old_field_value);
}
}
@@ -1235,7 +1228,7 @@ int ha_federated::update_row(
{
(*field)->val_str(&old_field_value,
(char *)(old_data + (*field)->offset()));
- quote_data(&old_field_value, *field);
+ (*field)->quote_data(&old_field_value);
where_string.append(old_field_value);
}
}
@@ -1312,7 +1305,7 @@ int ha_federated::delete_row(const byte * buf)
{
delete_string.append("=");
(*field)->val_str(&data_string);
- quote_data(&data_string, *field);
+ (*field)->quote_data(&data_string);
}
delete_string.append(data_string);
@@ -1366,8 +1359,11 @@ int ha_federated::index_read_idx(byte * buf, uint index, const byte * key,
__attribute__((unused)))
{
char index_value[IO_SIZE];
+ char key_value[IO_SIZE];
+ char test_value[IO_SIZE];
String index_string(index_value, sizeof(index_value), &my_charset_bin);
index_string.length(0);
+ uint keylen;
char sql_query_buffer[IO_SIZE];
String sql_query(sql_query_buffer, sizeof(sql_query_buffer), &my_charset_bin);
@@ -1376,20 +1372,20 @@ int ha_federated::index_read_idx(byte * buf, uint index, const byte * key,
DBUG_ENTER("ha_federated::index_read_idx");
statistic_increment(table->in_use->status_var.ha_read_key_count,&LOCK_status);
- index_string.length(0);
- sql_query.length(0);
-
sql_query.append(share->select_query);
sql_query.append(" WHERE ");
- sql_query.append(table->key_info[index].key_part->field->field_name);
- sql_query.append(" = ");
- table->key_info[index].key_part->field->val_str(&index_string, (char *)(key));
- quote_data(&index_string, table->key_info[index].key_part->field);
+ keylen= strlen((char *)(key));
+ create_where_from_key(&index_string, &table->key_info[index], key, keylen);
sql_query.append(index_string);
DBUG_PRINT("ha_federated::index_read_idx",
- ("sql_query %s", sql_query.c_ptr_quick()));
+ ("current key %d key value %s index_string value %s length %d", index, (char *)(key),index_string.c_ptr_quick(),
+ index_string.length()));
+
+ DBUG_PRINT("ha_federated::index_read_idx",
+ ("current position %d sql_query %s", current_position,
+ sql_query.c_ptr_quick()));
if (mysql_real_query(mysql, sql_query.c_ptr_quick(), sql_query.length()))
{
@@ -1540,7 +1536,7 @@ int ha_federated::rnd_pos(byte * buf, byte *pos)
{
DBUG_ENTER("ha_federated::rnd_pos");
statistic_increment(table->in_use->status_var.ha_read_rnd_count,&LOCK_status);
- memcpy(current_position, pos, sizeof(MYSQL_ROW_OFFSET)); // pos is not aligned
+ memcpy_fixed(&current_position, pos, sizeof(MYSQL_ROW_OFFSET)); // pos is not aligned
result->current_row= 0;
result->data_cursor= current_position;
DBUG_RETURN(rnd_next(buf));
diff --git a/sql/ha_federated.h b/sql/ha_federated.h
index c11960a836f..56f5e6de4b7 100755
--- a/sql/ha_federated.h
+++ b/sql/ha_federated.h
@@ -71,10 +71,8 @@ private:
return 0 on success
return errorcode otherwise
*/
- //FIX
uint convert_row_to_internal_format(byte *buf, MYSQL_ROW row);
- uint type_quote(int type);
- void quote_data(String *string1, Field *field);
+ bool ha_federated::create_where_from_key(String *to, KEY *key_info, const byte *key, uint key_length);
public:
ha_federated(TABLE *table): handler(table),
@@ -104,7 +102,7 @@ public:
{
return (HA_TABLE_SCAN_ON_INDEX | HA_NOT_EXACT_COUNT |
HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_AUTO_PART_KEY |
- HA_TABLE_SCAN_ON_INDEX);
+ HA_TABLE_SCAN_ON_INDEX | HA_CAN_INDEX_BLOBS);
}
/*
This is a bitmap of flags that says how the storage engine
@@ -132,7 +130,7 @@ public:
/*
The next method will never be called if you do not implement indexes.
*/
- virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows) { return (double) rows / 20.0+1; }
/*
Everything below are methods that we implment in ha_federated.cc.
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 18ab6f42d28..01580586bf6 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -5787,11 +5787,12 @@ ha_innobase::store_lock(
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
/* If we are not doing a LOCK TABLE or DISCARD/IMPORT
- TABLESPACE, then allow multiple writers */
+ TABLESPACE or TRUNCATE TABLE, then allow multiple writers */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
lock_type <= TL_WRITE) && !thd->in_lock_tables
- && !thd->tablespace_op) {
+ && !thd->tablespace_op
+ && thd->lex->sql_command != SQLCOM_TRUNCATE) {
lock_type = TL_WRITE_ALLOW_WRITE;
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index badb486d16b..c12055a1d63 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1055,6 +1055,42 @@ int ha_ndbcluster::get_metadata(const char *path)
DBUG_RETURN(build_index_list(table, ILBP_OPEN));
}
+static int fix_unique_index_attr_order(NDB_INDEX_DATA &data,
+ const NDBINDEX *index,
+ KEY *key_info)
+{
+ DBUG_ENTER("fix_unique_index_attr_order");
+ unsigned sz= index->getNoOfIndexColumns();
+
+ if (data.unique_index_attrid_map)
+ my_free((char*)data.unique_index_attrid_map, MYF(0));
+ data.unique_index_attrid_map= (unsigned char*)my_malloc(sz,MYF(MY_WME));
+
+ KEY_PART_INFO* key_part= key_info->key_part;
+ KEY_PART_INFO* end= key_part+key_info->key_parts;
+ DBUG_ASSERT(key_info->key_parts == sz);
+ for (unsigned i= 0; key_part != end; key_part++, i++)
+ {
+ const char *field_name= key_part->field->field_name;
+ unsigned name_sz= strlen(field_name);
+ if (name_sz >= NDB_MAX_ATTR_NAME_SIZE)
+ name_sz= NDB_MAX_ATTR_NAME_SIZE-1;
+#ifndef DBUG_OFF
+ data.unique_index_attrid_map[i]= 255;
+#endif
+ for (unsigned j= 0; j < sz; j++)
+ {
+ const NdbDictionary::Column *c= index->getColumn(j);
+ if (strncmp(field_name, c->getName(), name_sz) == 0)
+ {
+ data.unique_index_attrid_map[i]= j;
+ break;
+ }
+ }
+ DBUG_ASSERT(data.unique_index_attrid_map[i] != 255);
+ }
+ DBUG_RETURN(0);
+}
int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase)
{
@@ -1129,7 +1165,8 @@ int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase)
const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname);
if (!index) DBUG_RETURN(1);
m_index[i].unique_index= (void *) index;
- }
+ error= fix_unique_index_attr_order(m_index[i], index, key_info);
+ }
}
DBUG_RETURN(error);
@@ -1187,6 +1224,11 @@ void ha_ndbcluster::release_metadata()
{
m_index[i].unique_index= NULL;
m_index[i].index= NULL;
+ if (m_index[i].unique_index_attrid_map)
+ {
+ my_free((char *)m_index[i].unique_index_attrid_map, MYF(0));
+ m_index[i].unique_index_attrid_map= NULL;
+ }
}
DBUG_VOID_RETURN;
@@ -1355,7 +1397,7 @@ ha_ndbcluster::set_index_key(NdbOperation *op,
const byte* ptr= key_part->null_bit ? key_ptr + 1 : key_ptr;
char buf[256];
shrink_varchar(field, ptr, buf);
- if (set_ndb_key(op, field, i, ptr))
+ if (set_ndb_key(op, field, m_index[active_index].unique_index_attrid_map[i], ptr))
ERR_RETURN(m_active_trans->getNdbError());
key_ptr+= key_part->store_length;
}
@@ -1858,13 +1900,10 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
// Set bound if not cancelled via type -1
if (p.bound_type != -1)
{
- char truncated_field_name[NDB_MAX_ATTR_NAME_SIZE];
- strnmov(truncated_field_name,field->field_name,sizeof(truncated_field_name));
- truncated_field_name[sizeof(truncated_field_name)-1]= '\0';
const char* ptr= p.bound_ptr;
char buf[256];
shrink_varchar(field, ptr, buf);
- if (op->setBound(truncated_field_name, p.bound_type, ptr))
+ if (op->setBound(i, p.bound_type, ptr))
ERR_RETURN(op->getNdbError());
}
}
@@ -3634,14 +3673,14 @@ static int create_ndb_column(NDBCOL &col,
col.setLength(1);
break;
// Date types
- case MYSQL_TYPE_TIMESTAMP:
- col.setType(NDBCOL::Unsigned);
- col.setLength(1);
- break;
case MYSQL_TYPE_DATETIME:
col.setType(NDBCOL::Datetime);
col.setLength(1);
break;
+ case MYSQL_TYPE_DATE: // ?
+ col.setType(NDBCOL::Char);
+ col.setLength(field->pack_length());
+ break;
case MYSQL_TYPE_NEWDATE:
col.setType(NDBCOL::Date);
col.setLength(1);
@@ -3650,10 +3689,13 @@ static int create_ndb_column(NDBCOL &col,
col.setType(NDBCOL::Time);
col.setLength(1);
break;
- case MYSQL_TYPE_DATE: // ?
- case MYSQL_TYPE_YEAR:
- col.setType(NDBCOL::Char);
- col.setLength(field->pack_length());
+ case MYSQL_TYPE_YEAR:
+ col.setType(NDBCOL::Year);
+ col.setLength(1);
+ break;
+ case MYSQL_TYPE_TIMESTAMP:
+ col.setType(NDBCOL::Timestamp);
+ col.setLength(1);
break;
// Char types
case MYSQL_TYPE_STRING:
@@ -4192,9 +4234,10 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
for (i= 0; i < MAX_KEY; i++)
{
- m_index[i].type= UNDEFINED_INDEX;
- m_index[i].unique_index= NULL;
- m_index[i].index= NULL;
+ m_index[i].type= UNDEFINED_INDEX;
+ m_index[i].unique_index= NULL;
+ m_index[i].index= NULL;
+ m_index[i].unique_index_attrid_map= NULL;
}
DBUG_VOID_RETURN;
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 52b7a0ac915..c660d8f618d 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -52,6 +52,7 @@ typedef struct ndb_index_data {
NDB_INDEX_TYPE type;
void *index;
void *unique_index;
+ unsigned char *unique_index_attrid_map;
} NDB_INDEX_DATA;
typedef struct st_ndbcluster_share {
diff --git a/sql/handler.cc b/sql/handler.cc
index b1b741dfee9..059d1feaed1 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -373,6 +373,16 @@ int ha_init()
opt_using_transactions=1;
}
#endif
+#ifdef HAVE_ARCHIVE_DB
+ if (have_archive_db == SHOW_OPTION_YES)
+ {
+ if (archive_db_init())
+ {
+ have_archive_db= SHOW_OPTION_DISABLED;
+ error= 1;
+ }
+ }
+#endif
return error;
}
@@ -404,6 +414,10 @@ int ha_panic(enum ha_panic_function flag)
if (have_ndbcluster == SHOW_OPTION_YES)
error|=ndbcluster_end();
#endif
+#ifdef HAVE_ARCHIVE_DB
+ if (have_archive_db == SHOW_OPTION_YES)
+ error|= archive_db_end();
+#endif
if (ha_finish_errors())
error= 1;
return error;
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 8a5aeb6c9b7..9fb44658dd5 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -370,13 +370,14 @@ Item *create_func_space(Item *a)
{
uint dummy_errors;
sp= new Item_string("",0,cs);
- sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
+ if (sp)
+ sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
}
else
{
sp= new Item_string(" ",1,cs);
}
- return new Item_func_repeat(sp, a);
+ return sp ? new Item_func_repeat(sp, a) : 0;
}
Item *create_func_soundex(Item* a)
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index be89aa3f86d..29837c3afbd 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1234,7 +1234,7 @@ int composite_key_cmp(void* arg, byte* key1, byte* key2)
{
Field* f = *field;
int len = *lengths++;
- int res = f->cmp(key1, key2);
+ int res = f->cmp((char *) key1, (char *) key2);
if (res)
return res;
key1 += len;
@@ -1688,7 +1688,7 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
{
int res;
uint offset= (uint) (field->ptr - record);
- if ((res= field->cmp(key1 + offset, key2 + offset)))
+ if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
return res;
}
}
@@ -1722,7 +1722,7 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
{
int res;
uint offset= (uint) (field->ptr - record);
- if ((res= field->cmp(key1 + offset, key2 + offset)))
+ if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
return (*order_item)->asc ? res : -res;
}
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 32813454fef..5a069aee554 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2134,7 +2134,6 @@ String *Item_char_typecast::val_str(String *str)
String *res;
uint32 length;
-#if 0
if (!charset_conversion)
{
if (!(res= args[0]->val_str(str)))
@@ -2144,7 +2143,6 @@ String *Item_char_typecast::val_str(String *str)
}
}
else
-#endif
{
// Convert character set if differ
uint dummy_errors;
@@ -2182,9 +2180,18 @@ String *Item_char_typecast::val_str(String *str)
void Item_char_typecast::fix_length_and_dec()
{
uint32 char_length;
- charset_conversion= !my_charset_same(args[0]->collation.collation, cast_cs) &&
- args[0]->collation.collation != &my_charset_bin &&
- cast_cs != &my_charset_bin;
+ /*
+ We always force character set conversion if cast_cs
+ is a multi-byte character set. It garantees that the
+ result of CAST is a well-formed string.
+ For single-byte character sets we allow just to copy
+ from the argument. A single-byte character sets string
+ is always well-formed.
+ */
+ charset_conversion= (cast_cs->mbmaxlen > 1) ||
+ !my_charset_same(args[0]->collation.collation, cast_cs) &&
+ args[0]->collation.collation != &my_charset_bin &&
+ cast_cs != &my_charset_bin;
collation.set(cast_cs, DERIVATION_IMPLICIT);
char_length= (cast_length >= 0) ? cast_length :
args[0]->max_length/args[0]->collation.collation->mbmaxlen;
diff --git a/sql/key.cc b/sql/key.cc
index aec294e370a..c5ed60b129c 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -135,7 +135,7 @@ void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length)
{
key_length-= HA_KEY_BLOB_LENGTH;
length= min(key_length, key_part->length);
- key_part->field->get_key_image(to_key, length, Field::itRAW);
+ key_part->field->get_key_image((char *) to_key, length, Field::itRAW);
to_key+= HA_KEY_BLOB_LENGTH;
}
else
@@ -217,7 +217,7 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info,
{
key_length-= HA_KEY_BLOB_LENGTH;
length= min(key_length, key_part->length);
- key_part->field->set_key_image(from_key, length);
+ key_part->field->set_key_image((char *) from_key, length);
from_key+= HA_KEY_BLOB_LENGTH;
}
else
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 5a222a1ce10..bd0e1455eb2 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -712,6 +712,10 @@ void free_des_key_file();
/* sql_do.cc */
bool mysql_do(THD *thd, List<Item> &values);
+/* sql_analyse.h */
+bool append_escaped(String *to_str, String *from_str);
+bool append_escaped(String *to_str, char *from, uint from_len);
+
/* sql_show.cc */
bool mysqld_show_open_tables(THD *thd,const char *wild);
bool mysqld_show_logs(THD *thd);
@@ -978,7 +982,7 @@ extern Gt_creator gt_creator;
extern Lt_creator lt_creator;
extern Ge_creator ge_creator;
extern Le_creator le_creator;
-extern char language[LIBLEN],reg_ext[FN_EXTLEN];
+extern char language[FN_REFLEN], reg_ext[FN_EXTLEN];
extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN];
extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
extern char log_error_file[FN_REFLEN];
@@ -1001,8 +1005,7 @@ extern ulong ha_read_count, ha_discover_count;
extern ulong table_cache_size;
extern ulong max_connections,max_connect_errors, connect_timeout;
extern ulong slave_net_timeout;
-extern ulong max_user_connections;
-extern my_bool timed_mutexes;
+extern uint max_user_connections;
extern ulong what_to_log,flush_time;
extern ulong query_buff_size, thread_stack,thread_stack_min;
extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index db18c275a4d..ae27af1e755 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -333,9 +333,9 @@ ulong delayed_insert_errors,flush_time, thread_created;
ulong specialflag=0;
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
ulong max_connections,max_used_connections,
- max_connect_errors, max_user_connections = 0;
+ max_connect_errors;
+uint max_user_connections= 0;
ulong thread_id=1L,current_pid;
-my_bool timed_mutexes= 0;
ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0;
@@ -351,7 +351,7 @@ char *default_tz_name;
char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
char* log_error_file_ptr= log_error_file;
char mysql_real_data_home[FN_REFLEN],
- language[LIBLEN],reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
+ language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
*mysqld_user,*mysqld_chroot, *opt_init_file,
*opt_init_connect, *opt_init_slave,
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
@@ -3036,12 +3036,11 @@ You should consider changing lower_case_table_names to 1 or 2",
(test_if_case_insensitive(mysql_real_data_home) == 1)))
{
if (global_system_variables.log_warnings)
- sql_print_warning("\
-You have forced lower_case_table_names to 2 through a command-line \
-option, even though your file system '%s' is case sensitive. This means \
-that you can create a table that you can then no longer access. \
-You should consider changing lower_case_table_names to 0.",
+ sql_print_warning("lower_case_table_names was set to 2, even though your "
+ "the file system '%s' is case sensitive. Now setting "
+ "lower_case_table_names to 0 to avoid future problems.",
mysql_real_data_home);
+ lower_case_table_names= 0;
}
select_thread=pthread_self();
@@ -5262,8 +5261,8 @@ The minimum value for this variable is 4096.",
REQUIRED_ARG, 32, 1, ~0L, 0, 1, 0},
{"max_user_connections", OPT_MAX_USER_CONNECTIONS,
"The maximum number of active connections for a single user (0 = no limit).",
- (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_ULONG,
- REQUIRED_ARG, 0, 1, ~0L, 0, 1, 0},
+ (gptr*) &max_user_connections, (gptr*) &max_user_connections, 0, GET_UINT,
+ REQUIRED_ARG, 0, 1, ~0, 0, 1, 0},
{"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
"After this many write locks, allow some read locks to run in between.",
(gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c3b84564504..e5799bfd509 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1891,7 +1891,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
else
{
double n_blocks=
- ceil((double)param->table->file->data_file_length / IO_SIZE);
+ ceil(ulonglong2double(param->table->file->data_file_length) / IO_SIZE);
double busy_blocks=
n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(records)));
if (busy_blocks < 1.0)
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 552d2692c3c..d09de8550f0 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -28,7 +28,7 @@
- If the variable is thread specific, add it to 'system_variables' struct.
If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
- If the variable should be changed from the command line, add a definition
- of it in the my_option structure list in mysqld.dcc
+ of it in the my_option structure list in mysqld.cc
- Don't forget to initialize new fields in global_system_variables and
max_system_variables!
- If the variable should show up in 'show variables' add it to the
@@ -587,6 +587,7 @@ sys_var *sys_variables[]=
&sys_max_tmp_tables,
&sys_max_user_connections,
&sys_max_write_lock_count,
+ &sys_multi_range_count,
&sys_myisam_data_pointer_size,
&sys_myisam_max_extra_sort_file_size,
&sys_myisam_max_sort_file_size,
@@ -736,7 +737,7 @@ struct show_var_st init_vars[]= {
{"have_crypt", (char*) &have_crypt, SHOW_HAVE},
{"have_csv", (char*) &have_csv_db, SHOW_HAVE},
{"have_example_engine", (char*) &have_example_db, SHOW_HAVE},
- {"have_federated_db", (char*) &have_federated_db, SHOW_HAVE},
+ {"have_federated_engine", (char*) &have_federated_db, SHOW_HAVE},
{"have_geometry", (char*) &have_geometry, SHOW_HAVE},
{"have_innodb", (char*) &have_innodb, SHOW_HAVE},
{"have_isam", (char*) &have_isam, SHOW_HAVE},
@@ -832,6 +833,7 @@ struct show_var_st init_vars[]= {
{sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
{sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
{sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
+ {sys_multi_range_count.name, (char*) &sys_multi_range_count, SHOW_SYS},
{sys_myisam_data_pointer_size.name, (char*) &sys_myisam_data_pointer_size, SHOW_SYS},
{sys_myisam_max_extra_sort_file_size.name,
(char*) &sys_myisam_max_extra_sort_file_size,
@@ -1605,6 +1607,14 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
var_type= OPT_GLOBAL;
}
switch (type()) {
+ case SHOW_INT:
+ {
+ uint value;
+ pthread_mutex_lock(&LOCK_global_system_variables);
+ value= *(uint*) value_ptr(thd, var_type, base);
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return new Item_uint((int32) value);
+ }
case SHOW_LONG:
{
ulong value;
diff --git a/sql/set_var.h b/sql/set_var.h
index 7c9f11041c8..0f30f764ed5 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -740,7 +740,7 @@ public:
return type != OPT_GLOBAL || !option_limits;
}
void set_default(THD *thd, enum_var_type type);
- SHOW_TYPE type() { return SHOW_LONG; }
+ SHOW_TYPE type() { return SHOW_INT; }
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am
index cfbbb36c489..608bbdb7ae6 100644
--- a/sql/share/Makefile.am
+++ b/sql/share/Makefile.am
@@ -14,10 +14,11 @@ dist-hook:
all: english/errmsg.sys
# Use the english errmsg.sys as a flag that all errmsg.sys needs to be
-# created. Normally these are created by extra/Makefile.am
+# created. Normally these are created by extra/Makefile
english/errmsg.sys: errmsg.txt
- $(top_builddir)/extra/comp_err --charset=$(srcdir)/charsets --out-dir=$(top_builddir)/sql/share/ --header_file=$(top_builddir)/extra/mysqld_error.h --state_file=$(top_builddir)/extra/sql_state.h --in_file=errmsg.txt
+ rm $(top_builddir)/include/mysqld_error.h
+ (cd $(top_builddir)/extra && $(MAKE))
install-data-local:
for lang in @AVAILABLE_LANGUAGES@; \
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f9d95b2cde5..71d042eda02 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1494,12 +1494,12 @@ static bool update_user_table(THD *thd, const char *host, const char *user,
DBUG_RETURN(1); /* purecov: deadcode */
table->field[0]->store(host,(uint) strlen(host), system_charset_info);
table->field[1]->store(user,(uint) strlen(user), system_charset_info);
- key_copy(user_key, table->record[0], table->key_info,
+ key_copy((byte *) user_key, table->record[0], table->key_info,
table->key_info->key_length);
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
if (table->file->index_read_idx(table->record[0], 0,
- user_key, table->key_info->key_length,
+ (byte *) user_key, table->key_info->key_length,
HA_READ_KEY_EXACT))
{
my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH),
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index ce58c585061..3f97cab1511 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -59,7 +59,8 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
return compare_ulonglong(s,t);
}
-static bool append_escaped(String *to_str, String *from_str);
+bool append_escaped(String *to_str, String *from_str);
+bool append_escaped(String *to_str, char *from, uint from_len);
Procedure *
proc_analyse_init(THD *thd, ORDER *param, select_result *result,
@@ -1052,7 +1053,7 @@ uint check_ulonglong(const char *str, uint length)
1 Out of memory
*/
-static bool append_escaped(String *to_str, String *from_str)
+bool append_escaped(String *to_str, String *from_str)
{
char *from, *end, c;
@@ -1086,3 +1087,38 @@ static bool append_escaped(String *to_str, String *from_str)
}
return 0;
}
+
+bool append_escaped(String *to_str, char *from, uint from_len)
+{
+ char *end, c;
+
+ if (to_str->realloc(to_str->length() + from_len))
+ return 1;
+
+ end= from + from_len;
+
+ for (; from < end; from++)
+ {
+ c= *from;
+ switch (c) {
+ case '\0':
+ c= '0';
+ break;
+ case '\032':
+ c= 'Z';
+ break;
+ case '\\':
+ case '\'':
+ break;
+ default:
+ goto normal_character;
+ }
+ if (to_str->append('\\'))
+ return 1;
+
+ normal_character:
+ if (to_str->append(c))
+ return 1;
+ }
+ return 0;
+}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index f635aa62000..240208584e7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1281,6 +1281,7 @@ public:
unit= u;
return 0;
}
+ virtual int prepare2(void) { return 0; }
/*
Because of peculiarities of prepared statements protocol
we need to know number of columns in the result set (if
@@ -1380,6 +1381,7 @@ class select_insert :public select_result_interceptor {
enum_duplicates duplic, bool ignore);
~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
+ int prepare2(void);
bool send_data(List<Item> &items);
virtual void store_values(List<Item> &values);
void send_error(uint errcode,const char *err);
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 7bf28a439b6..759b535da53 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -558,8 +558,13 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
{
if (!cond->fixed)
cond->fix_fields(thd, tables, &cond); // can never fail
+
+ /* Assume that no indexes cover all required fields */
+ table->used_keys.clear_all();
+
SQL_SELECT *res= make_select(table,0,0,cond,error);
- if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)))
+ if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
+ (res->quick && res->quick->reset()))
{
delete res;
res=0;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index ceb31f76953..4cb62d5e9d7 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1802,13 +1802,22 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
thd->lex->current_select->options|= OPTION_BUFFER_RESULT;
thd->lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
}
-
+ else
+ {
+ /*
+ We must not yet prepare the result table if it is the same as one of the
+ source tables (INSERT SELECT). The preparation may disable
+ indexes on the result table, which may be used during the select, if it
+ is the same table (Bug #6034). Do the preparation after the select phase
+ in select_insert::prepare2().
+ */
+ if (info.ignore || info.handle_duplicates != DUP_ERROR)
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ table->file->start_bulk_insert((ha_rows) 0);
+ }
restore_record(table,s->default_values); // Get empty record
table->next_number_field=table->found_next_number_field;
thd->cuted_fields=0;
- if (info.ignore || info.handle_duplicates != DUP_ERROR)
- table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- table->file->start_bulk_insert((ha_rows) 0);
thd->no_trans_update= 0;
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
@@ -1819,6 +1828,36 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
+/*
+ Finish the preparation of the result table.
+
+ SYNOPSIS
+ select_insert::prepare2()
+ void
+
+ DESCRIPTION
+ If the result table is the same as one of the source tables (INSERT SELECT),
+ the result table is not finally prepared at the join prepair phase.
+ Do the final preparation now.
+
+ RETURN
+ 0 OK
+*/
+
+int select_insert::prepare2(void)
+{
+ DBUG_ENTER("select_insert::prepare2");
+
+ if (thd->lex->current_select->options & OPTION_BUFFER_RESULT)
+ {
+ if (info.ignore || info.handle_duplicates != DUP_ERROR)
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+ table->file->start_bulk_insert((ha_rows) 0);
+ }
+ return 0;
+}
+
+
void select_insert::cleanup()
{
/* select_insert/select_create are never re-used in prepared statement */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c0bcaf771a5..7205baae59e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5339,6 +5339,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->table_name, information_schema_name.str);
DBUG_RETURN(0);
}
+ ptr->schema_table_name= ptr->table_name;
ptr->schema_table= schema_table;
}
ptr->select_lex= lex->current_select;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index acb7d8f48f1..60273d21d9f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1164,6 +1164,7 @@ JOIN::exec()
DBUG_VOID_RETURN;
}
}
+ (void) result->prepare2(); // Currently, this cannot fail.
if (!tables_list)
{ // Only test of functions
@@ -4473,16 +4474,9 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
x = used key parts (1 <= x <= c)
*/
double rec_per_key;
-#if 0
- if (!(rec_per_key=(double)
- keyinfo->rec_per_key[keyinfo->key_parts-1]))
- rec_per_key=(double) s->records/rec+1;
-#else
rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1] ?
(double) keyinfo->rec_per_key[keyinfo->key_parts-1] :
(double) s->records/rec+1;
-#endif
-
if (!s->records)
tmp=0;
else if (rec_per_key/(double) s->records >= 0.01)
@@ -13159,7 +13153,8 @@ bool JOIN::change_result(select_result *res)
{
DBUG_ENTER("JOIN::change_result");
result= res;
- if (!procedure && result->prepare(fields_list, select_lex->master_unit()))
+ if (!procedure && (result->prepare(fields_list, select_lex->master_unit()) ||
+ result->prepare2()))
{
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index b909e9cec1b..e9126871045 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1802,7 +1802,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
res= open_and_lock_tables(thd, show_table_list);
if (schema_table->process_table(thd, show_table_list,
table, res, show_table_list->db,
- show_table_list->table_name))
+ show_table_list->alias))
{
DBUG_RETURN(1);
}
@@ -1911,7 +1911,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
show_table_list->lock_type= lock_type;
res= open_and_lock_tables(thd, show_table_list);
if (schema_table->process_table(thd, show_table_list, table,
- res, base_name, file_name))
+ res, base_name,
+ show_table_list->alias))
{
DBUG_RETURN(1);
}
@@ -3183,8 +3184,17 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
}
table->s->tmp_table= TMP_TABLE;
table->grant.privilege= SELECT_ACL;
- table->alias_name_used= 0;
- table_list->schema_table_name= table_list->table_name;
+ /*
+ This test is necessary to make
+ case insensitive file systems +
+ upper case table names(information schema tables) +
+ views
+ working correctly
+ */
+ if (table_list->schema_table_name)
+ table->alias_name_used= my_strcasecmp(table_alias_charset,
+ table_list->schema_table_name,
+ table_list->alias);
table_list->table_name= (char*) table->s->table_name;
table_list->table= table;
table->next= thd->derived_tables;
diff --git a/sql/table.cc b/sql/table.cc
index 82ad32341c0..69a132329c0 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -305,7 +305,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if (!(record= (char *) alloc_root(&outparam->mem_root,
rec_buff_length * records)))
goto err; /* purecov: inspected */
- share->default_values= record;
+ share->default_values= (byte *) record;
if (my_pread(file,(byte*) record, (uint) share->reclength,
(ulong) (uint2korr(head+6)+
((uint2korr(head+14) == 0xffff ?
@@ -320,9 +320,9 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
}
else
{
- outparam->record[0]= record+ rec_buff_length;
+ outparam->record[0]= (byte *) record+ rec_buff_length;
if (records > 2)
- outparam->record[1]= record+ rec_buff_length*2;
+ outparam->record[1]= (byte *) record+ rec_buff_length*2;
else
outparam->record[1]= outparam->record[0]; // Safety
}