summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <mattiasj@mattiasj-laptop.(none)>2007-11-12 21:09:48 +0100
committerunknown <mattiasj@mattiasj-laptop.(none)>2007-11-12 21:09:48 +0100
commit1b98a962d5fd2f77034ba42b173eeb1d8588becd (patch)
treee45fd7d0c5fc62764cf02dce0038b6571c4fa001 /sql
parentc4f94b70bdaa26e9b8782771f079a2dc3c1594d6 (diff)
parente116210a36f784411fe81c662b65836e9f9c2568 (diff)
downloadmariadb-git-1b98a962d5fd2f77034ba42b173eeb1d8588becd.tar.gz
Merge mattiasj-laptop.(none):/home/mattiasj/clones/mysql-5.1-main
into mattiasj-laptop.(none):/home/mattiasj/clones/mysql-5.1-last_with_main libmysqld/lib_sql.cc: Auto merged mysql-test/include/mix1.inc: Auto merged mysql-test/r/innodb_mysql.result: Auto merged sql/event_scheduler.cc: Auto merged sql/events.cc: Auto merged sql/ha_ndbcluster_binlog.cc: Auto merged sql/handler.cc: Auto merged sql/item_func.cc: Auto merged sql/slave.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_connect.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_yacc.yy: Auto merged
Diffstat (limited to 'sql')
-rwxr-xr-xsql/CMakeLists.txt2
-rw-r--r--sql/event_scheduler.cc1
-rw-r--r--sql/events.cc1
-rw-r--r--sql/ha_ndbcluster.cc1
-rw-r--r--sql/ha_ndbcluster_binlog.cc1
-rw-r--r--sql/ha_partition.cc21
-rw-r--r--sql/handler.cc43
-rw-r--r--sql/opt_range.cc10
-rw-r--r--sql/share/errmsg.txt6
-rw-r--r--sql/slave.cc1
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_base.cc3
-rw-r--r--sql/sql_connect.cc1
-rw-r--r--sql/sql_insert.cc7
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_partition.cc21
-rw-r--r--sql/sql_plugin.cc1
-rw-r--r--sql/sql_servers.cc5
-rw-r--r--sql/sql_udf.cc1
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/table.cc6
-rw-r--r--sql/tztime.cc1
23 files changed, 116 insertions, 25 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 299f4ae4285..77abc4e6fa5 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -90,12 +90,14 @@ TARGET_LINK_LIBRARIES(mysqld
SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX})
+IF(cmake_version EQUAL 20406)
# Work around for 2.4.6 bug, OUTPUT_NAME will not set the right .PDB
# file name. Note that COMPILE_FLAGS set some temporary pdb during build,
# LINK_FLAGS sets the real one.
SET_TARGET_PROPERTIES(mysqld PROPERTIES
COMPILE_FLAGS "/Fd${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb"
LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
+ENDIF(cmake_version EQUAL 20406)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index d3a031fd8f8..5655a8acc99 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -127,6 +127,7 @@ post_init_event_thread(THD *thd)
thd->cleanup();
return TRUE;
}
+ lex_start(thd);
pthread_mutex_lock(&LOCK_thread_count);
threads.append(thd);
diff --git a/sql/events.cc b/sql/events.cc
index 1bfbc5d6645..262c62bdbc8 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -884,6 +884,7 @@ Events::init(my_bool opt_noacl)
*/
thd->thread_stack= (char*) &thd;
thd->store_globals();
+ lex_start(thd);
/*
We will need Event_db_repository anyway, even if the scheduler is
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 436710e3dee..bf2b19bfc9c 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -9073,6 +9073,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
thd->thread_stack= (char*)&thd; /* remember where our stack is */
if (thd->store_globals())
goto ndb_util_thread_fail;
+ lex_start(thd);
thd->init_for_queries();
thd->version=refresh_version;
thd->main_security_ctx.host_or_ip= "";
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index fc35a7a930e..55af0c38aed 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -3621,6 +3621,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
pthread_exit(0);
DBUG_RETURN(NULL);
}
+ lex_start(thd);
thd->init_for_queries();
thd->command= COM_DAEMON;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 8afaab71160..b53a5e3da97 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1599,6 +1599,7 @@ error:
void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
{
m_file[0]->update_create_info(create_info);
+ create_info->data_file_name= create_info->index_file_name = NULL;
return;
}
@@ -2678,7 +2679,8 @@ int ha_partition::write_row(uchar * buf)
uint32 part_id;
int error;
longlong func_value;
- bool autoincrement_lock= false;
+ bool autoincrement_lock= FALSE;
+ my_bitmap_map *old_map;
#ifdef NOT_NEEDED
uchar *rec0= m_rec0;
#endif
@@ -2705,8 +2707,17 @@ int ha_partition::write_row(uchar * buf)
use autoincrement_lock variable to avoid unnecessary locks.
Probably not an ideal solution.
*/
- autoincrement_lock= true;
- pthread_mutex_lock(&table_share->mutex);
+ if (table_share->tmp_table == NO_TMP_TABLE)
+ {
+ /*
+ Bug#30878 crash when alter table from non partitioned table
+ to partitioned.
+ Checking if tmp table then there is no need to lock,
+ and the table_share->mutex may not be initialised.
+ */
+ autoincrement_lock= TRUE;
+ pthread_mutex_lock(&table_share->mutex);
+ }
error= update_auto_increment();
/*
@@ -2715,10 +2726,10 @@ int ha_partition::write_row(uchar * buf)
the correct partition. We must check and fail if neccessary.
*/
if (error)
- DBUG_RETURN(error);
+ goto exit;
}
- my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+ old_map= dbug_tmp_use_all_columns(table, table->read_set);
#ifdef NOT_NEEDED
if (likely(buf == rec0))
#endif
diff --git a/sql/handler.cc b/sql/handler.cc
index 1606c160238..8a2355c8a87 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2542,15 +2542,56 @@ int ha_enable_transaction(THD *thd, bool on)
int handler::index_next_same(uchar *buf, const uchar *key, uint keylen)
{
int error;
+ DBUG_ENTER("index_next_same");
if (!(error=index_next(buf)))
{
+ my_ptrdiff_t ptrdiff= buf - table->record[0];
+ uchar *save_record_0;
+ KEY *key_info;
+ KEY_PART_INFO *key_part;
+ KEY_PART_INFO *key_part_end;
+ LINT_INIT(save_record_0);
+ LINT_INIT(key_info);
+ LINT_INIT(key_part);
+ LINT_INIT(key_part_end);
+
+ /*
+ key_cmp_if_same() compares table->record[0] against 'key'.
+ In parts it uses table->record[0] directly, in parts it uses
+ field objects with their local pointers into table->record[0].
+ If 'buf' is distinct from table->record[0], we need to move
+ all record references. This is table->record[0] itself and
+ the field pointers of the fields used in this key.
+ */
+ if (ptrdiff)
+ {
+ save_record_0= table->record[0];
+ table->record[0]= buf;
+ key_info= table->key_info + active_index;
+ key_part= key_info->key_part;
+ key_part_end= key_part + key_info->key_parts;
+ for (; key_part < key_part_end; key_part++)
+ {
+ DBUG_ASSERT(key_part->field);
+ key_part->field->move_field_offset(ptrdiff);
+ }
+ }
+
if (key_cmp_if_same(table, key, active_index, keylen))
{
table->status=STATUS_NOT_FOUND;
error=HA_ERR_END_OF_FILE;
}
+
+ /* Move back if necessary. */
+ if (ptrdiff)
+ {
+ table->record[0]= save_record_0;
+ for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
+ key_part->field->move_field_offset(-ptrdiff);
+ }
}
- return error;
+ DBUG_RETURN(error);
}
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 99c28be36b0..b89e8b3dcbb 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3344,18 +3344,16 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
{
key_part->key= 0;
key_part->part= part;
- key_part->length= (uint16) (*field)->pack_length_in_rec();
- /*
- psergey-todo: check yet again if this is correct for tricky field types,
- e.g. see "Fix a fatal error in decimal key handling" in open_binary_frm()
- */
- key_part->store_length= (uint16) (*field)->pack_length();
+ key_part->store_length= key_part->length= (uint16) (*field)->key_length();
if ((*field)->real_maybe_null())
key_part->store_length+= HA_KEY_NULL_LENGTH;
if ((*field)->type() == MYSQL_TYPE_BLOB ||
(*field)->real_type() == MYSQL_TYPE_VARCHAR)
key_part->store_length+= HA_KEY_BLOB_LENGTH;
+ DBUG_PRINT("info", ("part %u length %u store_length %u", part,
+ key_part->length, key_part->store_length));
+
key_part->field= (*field);
key_part->image_type = Field::itRAW;
/*
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 8fad09eb221..257cea7c27b 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5667,9 +5667,9 @@ ER_ILLEGAL_HA_CREATE_OPTION
eng "Table storage engine '%-.64s' does not support the create option '%.64s'"
ger "Speicher-Engine '%-.64s' der Tabelle unterstützt die Option '%.64s' nicht"
ER_PARTITION_REQUIRES_VALUES_ERROR
- eng "%-.64s PARTITIONING requires definition of VALUES %-.64s for each partition"
- ger "%-.64s-PARTITIONierung erfordert Definition von VALUES %-.64s für jede Partition"
- swe "%-.64s PARTITIONering kräver definition av VALUES %-.64s för varje partition"
+ eng "Syntax error: %-.64s PARTITIONING requires definition of VALUES %-.64s for each partition"
+ ger "Fehler in der SQL-Syntax: %-.64s-PARTITIONierung erfordert Definition von VALUES %-.64s für jede Partition"
+ swe "Syntaxfel: %-.64s PARTITIONering kräver definition av VALUES %-.64s för varje partition"
ER_PARTITION_WRONG_VALUES_ERROR
eng "Only %-.64s PARTITIONING can use VALUES %-.64s in partition definition"
ger "Nur %-.64s-PARTITIONierung kann VALUES %-.64s in der Partitionsdefinition verwenden"
diff --git a/sql/slave.cc b/sql/slave.cc
index 7abcf50fa75..2512954f805 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1510,6 +1510,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
delete thd;
DBUG_RETURN(-1);
}
+ lex_start(thd);
if (thd_type == SLAVE_THD_SQL)
thd->proc_info= "Waiting for the next event in relay log";
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 070a943da9e..311b76c6149 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -277,6 +277,7 @@ my_bool acl_init(bool dont_read_acl_tables)
DBUG_RETURN(1); /* purecov: inspected */
thd->thread_stack= (char*) &thd;
thd->store_globals();
+ lex_start(thd);
/*
It is safe to call acl_reload() since acl_* arrays and hashes which
will be freed there are global static objects and thus are initialized
@@ -3493,6 +3494,7 @@ my_bool grant_init()
DBUG_RETURN(1); /* purecov: deadcode */
thd->thread_stack= (char*) &thd;
thd->store_globals();
+ lex_start(thd);
return_val= grant_reload(thd);
delete thd;
/* Remember that we don't have a THD */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index ddc5f88f577..66d0cda2155 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2289,6 +2289,9 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
HASH_SEARCH_STATE state;
DBUG_ENTER("open_table");
+ /* Parsing of partitioning information from .frm needs thd->lex set up. */
+ DBUG_ASSERT(thd->lex->is_lex_started);
+
/* find a unused table in the open table cache */
if (refresh)
*refresh=0;
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 68872f85cd4..76237576764 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1120,6 +1120,7 @@ pthread_handler_t handle_one_connection(void *arg)
{
NET *net= &thd->net;
+ lex_start(thd);
if (login_connection(thd))
goto end_thread;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index d3010e4309b..11e70a2e5da 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2267,7 +2267,12 @@ pthread_handler_t handle_delayed_insert(void *arg)
goto err;
}
- /* open table */
+ /*
+ Open table requires an initialized lex in case the table is
+ partitioned. The .frm file contains a partial SQL string which is
+ parsed using a lex, that depends on initialized thd->lex.
+ */
+ lex_start(thd);
if (!(di->table=open_ltable(thd, &di->table_list, TL_WRITE_DELAYED, 0)))
{
thd->fatal_error(); // Abort waiting inserts
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 4ee66cb1e8d..7d6f21cad05 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -363,6 +363,7 @@ void lex_start(THD *thd)
lex->server_options.owner= 0;
lex->server_options.port= -1;
+ lex->is_lex_started= TRUE;
DBUG_VOID_RETURN;
}
@@ -2139,7 +2140,7 @@ void Query_tables_list::destroy_query_tables_list()
st_lex::st_lex()
:result(0), yacc_yyss(0), yacc_yyvs(0),
- sql_command(SQLCOM_END), option_type(OPT_DEFAULT)
+ sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
{
my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 507d64daf89..da0ff94ec96 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1712,6 +1712,7 @@ typedef struct st_lex : public Query_tables_list
st_alter_tablespace *alter_tablespace_info;
bool escape_used;
+ bool is_lex_started; /* If lex_start() did run. For debugging. */
st_lex();
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 0cc2cac2a1a..ad9eec1906a 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1856,6 +1856,20 @@ static int add_uint(File fptr, ulonglong number)
return add_string(fptr, buff);
}
+/*
+ Must escape strings in partitioned tables frm-files,
+ parsing it later with mysql_unpack_partition will fail otherwise.
+*/
+static int add_quoted_string(File fptr, const char *quotestr)
+{
+ String orgstr(quotestr, system_charset_info);
+ String escapedstr;
+ int err= add_string(fptr, "'");
+ err+= append_escaped(&escapedstr, &orgstr);
+ err+= add_string(fptr, escapedstr.c_ptr_safe());
+ return err + add_string(fptr, "'");
+}
+
static int add_keyword_string(File fptr, const char *keyword,
bool should_use_quotes,
const char *keystr)
@@ -1866,10 +1880,9 @@ static int add_keyword_string(File fptr, const char *keyword,
err+= add_equal(fptr);
err+= add_space(fptr);
if (should_use_quotes)
- err+= add_string(fptr, "'");
- err+= add_string(fptr, keystr);
- if (should_use_quotes)
- err+= add_string(fptr, "'");
+ err+= add_quoted_string(fptr, keystr);
+ else
+ err+= add_string(fptr, keystr);
return err + add_space(fptr);
}
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 2af528f6699..c8d9116f196 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1329,6 +1329,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
}
new_thd->thread_stack= (char*) &tables;
new_thd->store_globals();
+ lex_start(new_thd);
new_thd->db= my_strdup("mysql", MYF(0));
new_thd->db_length= 5;
bzero((uchar*)&tables, sizeof(tables));
diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc
index a780c561ffe..602c289a605 100644
--- a/sql/sql_servers.cc
+++ b/sql/sql_servers.cc
@@ -140,6 +140,7 @@ bool servers_init(bool dont_read_servers_table)
DBUG_RETURN(TRUE);
thd->thread_stack= (char*) &thd;
thd->store_globals();
+ lex_start(thd);
/*
It is safe to call servers_reload() since servers_* arrays and hashes which
will be freed there are global static objects and thus are initialized
@@ -289,7 +290,7 @@ get_server_from_table_to_cache(TABLE *table)
{
/* alloc a server struct */
char *ptr;
- char *blank= (char*)"";
+ char * const blank= (char*)"";
FOREIGN_SERVER *server= (FOREIGN_SERVER *)alloc_root(&mem,
sizeof(FOREIGN_SERVER));
DBUG_ENTER("get_server_from_table_to_cache");
@@ -312,7 +313,7 @@ get_server_from_table_to_cache(TABLE *table)
server->port= server->sport ? atoi(server->sport) : 0;
ptr= get_field(&mem, table->field[6]);
- server->socket= ptr && strlen(ptr) ? ptr : NULL;
+ server->socket= ptr && strlen(ptr) ? ptr : blank;
ptr= get_field(&mem, table->field[7]);
server->scheme= ptr ? ptr : blank;
ptr= get_field(&mem, table->field[8]);
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 1076772d598..18511063117 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -135,6 +135,7 @@ void udf_init()
initialized = 1;
new_thd->thread_stack= (char*) &new_thd;
new_thd->store_globals();
+ lex_start(new_thd);
new_thd->set_db(db, sizeof(db)-1);
bzero((uchar*) &tables,sizeof(tables));
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b337f82dec3..04af253fec9 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6492,7 +6492,7 @@ bool_pri:
{ $$= (*$2)(0)->create($1,$3); }
| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
{ $$= all_any_subquery_creator($1, $2, $3, $5); }
- | predicate ;
+ | predicate
;
predicate:
diff --git a/sql/table.cc b/sql/table.cc
index a113975c5c5..c3ddb809b9e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1610,6 +1610,9 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
share->table_name.str, (long) outparam));
+ /* Parsing of partitioning information from .frm needs thd->lex set up. */
+ DBUG_ASSERT(thd->lex->is_lex_started);
+
error= 1;
bzero((char*) outparam, sizeof(*outparam));
outparam->in_use= thd;
@@ -1784,7 +1787,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam, is_create_table,
share->default_part_db_type,
&work_part_info_used);
- outparam->part_info->is_auto_partitioned= share->auto_partitioned;
+ if (!tmp)
+ outparam->part_info->is_auto_partitioned= share->auto_partitioned;
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
/* we should perform the fix_partition_func in either local or
caller's arena depending on work_part_info_used value
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 9eb38e97827..920f8e87d13 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1575,6 +1575,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap)
DBUG_RETURN(1);
thd->thread_stack= (char*) &thd;
thd->store_globals();
+ lex_start(thd);
/* Init all memory structures that require explicit destruction */
if (hash_init(&tz_names, &my_charset_latin1, 20,