diff options
author | unknown <mattiasj@mattiasj-laptop.(none)> | 2007-11-12 21:09:48 +0100 |
---|---|---|
committer | unknown <mattiasj@mattiasj-laptop.(none)> | 2007-11-12 21:09:48 +0100 |
commit | 1b98a962d5fd2f77034ba42b173eeb1d8588becd (patch) | |
tree | e45fd7d0c5fc62764cf02dce0038b6571c4fa001 /sql | |
parent | c4f94b70bdaa26e9b8782771f079a2dc3c1594d6 (diff) | |
parent | e116210a36f784411fe81c662b65836e9f9c2568 (diff) | |
download | mariadb-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-x | sql/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sql/event_scheduler.cc | 1 | ||||
-rw-r--r-- | sql/events.cc | 1 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 1 | ||||
-rw-r--r-- | sql/ha_ndbcluster_binlog.cc | 1 | ||||
-rw-r--r-- | sql/ha_partition.cc | 21 | ||||
-rw-r--r-- | sql/handler.cc | 43 | ||||
-rw-r--r-- | sql/opt_range.cc | 10 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 6 | ||||
-rw-r--r-- | sql/slave.cc | 1 | ||||
-rw-r--r-- | sql/sql_acl.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 3 | ||||
-rw-r--r-- | sql/sql_connect.cc | 1 | ||||
-rw-r--r-- | sql/sql_insert.cc | 7 | ||||
-rw-r--r-- | sql/sql_lex.cc | 3 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_partition.cc | 21 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 1 | ||||
-rw-r--r-- | sql/sql_servers.cc | 5 | ||||
-rw-r--r-- | sql/sql_udf.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 | ||||
-rw-r--r-- | sql/table.cc | 6 | ||||
-rw-r--r-- | sql/tztime.cc | 1 |
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, |