diff options
author | holyfoot@mysql.com <> | 2006-05-02 14:36:05 +0500 |
---|---|---|
committer | holyfoot@mysql.com <> | 2006-05-02 14:36:05 +0500 |
commit | 128593f0c292d8768144ae6ecbc87480ab2dc6d5 (patch) | |
tree | 7ce0d37117be0f77177cb5ee12a212fec4049257 /sql | |
parent | 05f32a3db0c745569c268eeef7d4f1ab2343ecdf (diff) | |
parent | b050f975c43fcfa8f85ad9725e6cfe9eff1b025c (diff) | |
download | mariadb-git-128593f0c292d8768144ae6ecbc87480ab2dc6d5.tar.gz |
Merge bk@192.168.21.1:mysql-5.1-new
into mysql.com:/home/hf/work/mysql-5.1.18518
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 26 | ||||
-rw-r--r-- | sql/item.h | 15 | ||||
-rw-r--r-- | sql/item_func.cc | 6 | ||||
-rw-r--r-- | sql/item_subselect.cc | 28 | ||||
-rw-r--r-- | sql/repl_failsafe.cc | 3 | ||||
-rw-r--r-- | sql/set_var.cc | 30 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 15 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 | ||||
-rw-r--r-- | sql/sql_table.cc | 49 |
10 files changed, 108 insertions, 70 deletions
diff --git a/sql/item.cc b/sql/item.cc index 4081aa1e1af..f778f0cb38e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3154,7 +3154,8 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) both clauses contain different fields with the same names, a warning is issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no GROUP BY column is found, then a HAVING name is resolved as a possibly - derived SELECT column. + derived SELECT column. This extension is allowed only if the + MODE_ONLY_FULL_GROUP_BY sql mode isn't enabled. NOTES The resolution procedure is: @@ -3164,7 +3165,9 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) in the GROUP BY clause of Q. - If found different columns with the same name in GROUP BY and SELECT - issue a warning and return the GROUP BY column, - - otherwise return the found SELECT column. + - otherwise + - if the MODE_ONLY_FULL_GROUP_BY mode is enabled return error + - else return the found SELECT column. RETURN @@ -3209,6 +3212,17 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) } } + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && + select_ref != not_found_item && !group_by_ref) + { + /* + Report the error if fields was found only in the SELECT item list and + the strict mode is enabled. + */ + my_error(ER_NON_GROUPING_FIELD_USED, MYF(0), + ref->name, "HAVING"); + return NULL; + } if (select_ref != not_found_item || group_by_ref) { if (select_ref != not_found_item && !ambiguous_fields) @@ -5178,14 +5192,6 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const return FALSE; } -void Item_null_helper::print(String *str) -{ - str->append(STRING_WITH_LEN("<null_helper>(")); - store->print(str); - str->append(')'); -} - - bool Item_default_value::eq(const Item *item, bool binary_cmp) const { return item->type() == DEFAULT_VALUE_ITEM && diff --git a/sql/item.h b/sql/item.h index 49f06ca31fa..f73017563dd 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1893,21 +1893,6 @@ public: } }; -class Item_null_helper :public Item_ref_null_helper -{ - Item *store; -public: - Item_null_helper(Name_resolution_context *context_arg, - Item_in_subselect* master, Item *item, - const char *table_name_arg, const char *field_name_arg) - :Item_ref_null_helper(context_arg, master, (store= 0, &store), - table_name_arg, field_name_arg), - store(item) - { ref= &store; } - void print(String *str); -}; - - /* The following class is used to optimize comparing of date and bigint columns We need to save the original item ('ref') to be able to call diff --git a/sql/item_func.cc b/sql/item_func.cc index 2e4d469d2d2..9281a8a1ddf 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4559,12 +4559,6 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, sys_var *var; LEX_STRING *base_name, *component_name; - if (component.str == 0 && - !my_strcasecmp(system_charset_info, name.str, "VERSION")) - return new Item_string(NULL, server_version, - (uint) strlen(server_version), - system_charset_info, DERIVATION_SYSCONST); - if (component.str) { base_name= &component; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 68f189ccf8c..6c2ff19825f 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -931,14 +931,14 @@ Item_in_subselect::single_value_transformer(JOIN *join, { Item *item= (Item*) select_lex->item_list.head(); - select_lex->item_list.empty(); - select_lex->item_list.push_back(new Item_int("Not_used", - (longlong) 1, 21)); - select_lex->ref_pointer_array[0]= select_lex->item_list.head(); if (select_lex->table_list.elements) { bool tmp; Item *having= item, *orig_item= item; + select_lex->item_list.empty(); + select_lex->item_list.push_back(new Item_int("Not_used", + (longlong) 1, 21)); + select_lex->ref_pointer_array[0]= select_lex->item_list.head(); item= func->create(expr, item); if (!abort_on_null && orig_item->maybe_null) { @@ -993,17 +993,15 @@ Item_in_subselect::single_value_transformer(JOIN *join, comparison functions can't be changed during fix_fields() we can assign select_lex->having here, and pass 0 as last argument (reference) to fix_fields() - */ - item= func->create(expr, - new Item_null_helper(&select_lex->context, - this, item, - (char *)"<no matter>", - (char *)"<result>")); -#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE - if (!abort_on_null && left_expr->maybe_null) - item= new Item_cond_or(new Item_func_isnull(left_expr), item); -#endif - select_lex->having= join->having= item; + */ + select_lex->having= + join->having= + func->create(expr, + new Item_ref_null_helper(&select_lex->context, this, + select_lex->ref_pointer_array, + (char *)"<no matter>", + (char *)"<result>")); + select_lex->having_fix_field= 1; /* we do not check join->having->fixed, because comparison function diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index e207a0bf633..9cabe1a3df0 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -861,7 +861,8 @@ bool load_master_data(THD* thd) if (!rpl_filter->db_ok(db) || !rpl_filter->db_ok_with_wild_table(db) || - !strcmp(db,"mysql")) + !strcmp(db,"mysql") || + is_schema_db(db)) { *cur_table_res = 0; continue; diff --git a/sql/set_var.cc b/sql/set_var.cc index 8ff6b5b98c8..ae380bdf2d5 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -438,6 +438,8 @@ sys_var_thd_storage_engine sys_storage_engine("storage_engine", sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period); #endif sys_var_bool_ptr sys_sync_frm("sync_frm", &opt_sync_frm); +sys_var_const_str sys_system_time_zone("system_time_zone", + system_time_zone); sys_var_long_ptr sys_table_def_size("table_definition_cache", &table_def_size); sys_var_long_ptr sys_table_cache_size("table_open_cache", @@ -455,6 +457,13 @@ sys_var_thd_ulong sys_tmp_table_size("tmp_table_size", &SV::tmp_table_size); sys_var_bool_ptr sys_timed_mutexes("timed_mutexes", &timed_mutexes); +sys_var_const_str sys_version("version", server_version); +sys_var_const_str sys_version_comment("version_comment", + MYSQL_COMPILATION_COMMENT); +sys_var_const_str sys_version_compile_machine("version_compile_machine", + MACHINE_TYPE); +sys_var_const_str sys_version_compile_os("version_compile_os", + SYSTEM_TYPE); sys_var_thd_ulong sys_net_wait_timeout("wait_timeout", &SV::net_wait_timeout); @@ -622,7 +631,6 @@ sys_var_thd_time_zone sys_time_zone("time_zone"); /* Read only variables */ -sys_var_const_str sys_os("version_compile_os", SYSTEM_TYPE); sys_var_have_variable sys_have_archive_db("have_archive", &have_archive_db); sys_var_have_variable sys_have_berkeley_db("have_bdb", &have_berkeley_db); sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine", @@ -630,7 +638,7 @@ sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine", sys_var_have_variable sys_have_compress("have_compress", &have_compress); sys_var_have_variable sys_have_crypt("have_crypt", &have_crypt); sys_var_have_variable sys_have_csv_db("have_csv", &have_csv_db); -sys_var_have_variable sys_have_dlopen("have_dlopen", &have_dlopen); +sys_var_have_variable sys_have_dlopen("have_dynamic_loading", &have_dlopen); sys_var_have_variable sys_have_example_db("have_example_engine", &have_example_db); sys_var_have_variable sys_have_federated_db("have_federated_engine", @@ -902,9 +910,9 @@ SHOW_VAR init_vars[]= { SHOW_SYS}, {"pid_file", (char*) pidfile_name, SHOW_CHAR}, {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR}, - {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS}, {"port", (char*) &mysqld_port, SHOW_INT}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, + {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size, SHOW_SYS}, @@ -949,10 +957,11 @@ SHOW_VAR init_vars[]= { #ifdef HAVE_SYS_UN_H {"socket", (char*) &mysqld_unix_port, SHOW_CHAR_PTR}, #endif - {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS}, + {sys_sort_buffer.name, (char*) &sys_sort_buffer, SHOW_SYS}, + {sys_big_selects.name, (char*) &sys_big_selects, SHOW_SYS}, {sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS}, - {"sql_notes", (char*) &sys_sql_notes, SHOW_BOOL}, - {"sql_warnings", (char*) &sys_sql_warnings, SHOW_BOOL}, + {"sql_notes", (char*) &sys_sql_notes, SHOW_SYS}, + {"sql_warnings", (char*) &sys_sql_warnings, SHOW_SYS}, {sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS}, #ifdef HAVE_REPLICATION {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS}, @@ -981,10 +990,11 @@ SHOW_VAR init_vars[]= { {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS}, {sys_updatable_views_with_limit.name, (char*) &sys_updatable_views_with_limit,SHOW_SYS}, - {"version", server_version, SHOW_CHAR}, - {"version_comment", (char*) MYSQL_COMPILATION_COMMENT, SHOW_CHAR}, - {"version_compile_machine", (char*) MACHINE_TYPE, SHOW_CHAR}, - {sys_os.name, (char*) &sys_os, SHOW_SYS}, + {sys_version.name, (char*) &sys_version, SHOW_SYS}, + {sys_version_comment.name, (char*) &sys_version_comment, SHOW_SYS}, + {sys_version_compile_machine.name, (char*) &sys_version_compile_machine, + SHOW_SYS}, + {sys_version_compile_os.name, (char*) &sys_version_compile_os, SHOW_SYS}, {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS}, {NullS, NullS, SHOW_LONG} }; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 4816f37bd32..01e66b35c0f 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5822,6 +5822,8 @@ ER_MAX_PREPARED_STMT_COUNT_REACHED 42000 eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)" ER_VIEW_RECURSIVE eng "`%-.64s`.`%-.64s` contains view recursion" +ER_NON_GROUPING_FIELD_USED 42000 + eng "non-grouping field '%-.64s' is used in %-.64s clause" ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR eng "Cannot switch out of the row-based binary log format when the session has open temporary tables" ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b4cd4ee9804..2a913cc66aa 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1008,6 +1008,7 @@ static int check_connection(THD *thd) char *user= end; char *passwd= strend(user)+1; + uint user_len= passwd - user - 1; char *db= passwd; char db_buff[NAME_LEN+1]; // buffer to store db in utf8 char user_buff[USERNAME_LENGTH+1]; // buffer to store user in utf8 @@ -1040,11 +1041,19 @@ static int check_connection(THD *thd) db= db_buff; } - user_buff[copy_and_convert(user_buff, sizeof(user_buff)-1, - system_charset_info, user, strlen(user), - thd->charset(), &dummy_errors)]= '\0'; + user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1, + system_charset_info, user, user_len, + thd->charset(), &dummy_errors)]= '\0'; user= user_buff; + /* If username starts and ends in "'", chop them off */ + if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') + { + user[user_len-1]= 0; + user++; + user_len-= 2; + } + if (thd->main_security_ctx.user) x_free(thd->main_security_ctx.user); if (!(thd->main_security_ctx.user= my_strdup(user, MYF(0)))) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index aab126408f0..79b1c3836dc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12690,6 +12690,10 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, if (item->type() != Item::SUM_FUNC_ITEM && !item->marker && !item->const_item()) { + /* + TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed + ER_NON_GROUPING_FIELD_USED + */ my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name()); return 1; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f71234a6087..412682fc3b0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2184,7 +2184,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (need_to_change_arena) thd->restore_active_arena(thd->stmt_arena, &backup_arena); - if (! sql_field->def) + if (sql_field->def == NULL) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -2195,15 +2195,30 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (sql_field->sql_type == FIELD_TYPE_SET) { uint32 field_length; - if (sql_field->def) + if (sql_field->def != NULL) { char *not_used; uint not_used2; bool not_found= 0; String str, *def= sql_field->def->val_str(&str); - def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); - (void) find_set(interval, def->ptr(), def->length(), - cs, ¬_used, ¬_used2, ¬_found); + if (def == NULL) /* SQL "NULL" maps to NULL */ + { + if ((sql_field->flags & NOT_NULL_FLAG) != 0) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + + /* else, NULL is an allowed value */ + (void) find_set(interval, NULL, 0, + cs, ¬_used, ¬_used2, ¬_found); + } + else /* not NULL */ + { + (void) find_set(interval, def->ptr(), def->length(), + cs, ¬_used, ¬_used2, ¬_found); + } + if (not_found) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); @@ -2216,14 +2231,28 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, else /* FIELD_TYPE_ENUM */ { uint32 field_length; - if (sql_field->def) + DBUG_ASSERT(sql_field->sql_type == FIELD_TYPE_ENUM); + if (sql_field->def != NULL) { String str, *def= sql_field->def->val_str(&str); - def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); - if (!find_type2(interval, def->ptr(), def->length(), cs)) + if (def == NULL) /* SQL "NULL" maps to NULL */ { - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + if ((sql_field->flags & NOT_NULL_FLAG) != 0) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + + /* else, the defaults yield the correct length for NULLs. */ + } + else /* not NULL */ + { + def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); + if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */ + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } } } calculate_interval_lengths(cs, interval, &field_length, &dummy); |