diff options
author | unknown <monty@mysql.com> | 2004-09-09 07:26:28 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-09-09 07:26:28 +0300 |
commit | e18b7ea95942cb8ab0b31d453929dde50dcf3756 (patch) | |
tree | e2b882265e31ada44f3adec357920530f0c0ac31 /sql/sql_parse.cc | |
parent | c92b5349701ba68fa7ab97abf14933de8d6352fe (diff) | |
parent | 33efc9677d6f6a68d3dba69f4c036856ac4af5fe (diff) | |
download | mariadb-git-e18b7ea95942cb8ab0b31d453929dde50dcf3756.tar.gz |
Merge on pull
BitKeeper/etc/logging_ok:
auto-union
include/my_sys.h:
Auto merged
mysql-test/r/func_in.result:
Auto merged
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 166 |
1 files changed, 118 insertions, 48 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 546183563c9..9a76fa2da84 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1572,7 +1572,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; mysqld_list_fields(thd,&table_list,fields); free_items(thd->free_list); - thd->free_list=0; /* free_list should never point to garbage */ + thd->free_list= 0; /* free_list should never point to garbage */ break; } #endif @@ -1673,8 +1673,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in packet[0]. */ - enum enum_shutdown_level level= - (enum enum_shutdown_level) (uchar) packet[0]; + enum mysql_enum_shutdown_level level= + (enum mysql_enum_shutdown_level) (uchar) packet[0]; DBUG_PRINT("quit",("Got shutdown command for level %u", level)); if (level == SHUTDOWN_DEFAULT) level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable @@ -1958,6 +1958,20 @@ mysql_execute_command(THD *thd) } #endif /* !HAVE_REPLICATION */ + if (lex->time_zone_tables_used) + { + TABLE_LIST *tmp; + if ((tmp= my_tz_get_table_list(thd, &lex->query_tables_last)) == + &fake_time_zone_tables_list) + { + send_error(thd, 0); + DBUG_RETURN(-1); + } + lex->time_zone_tables_used= tmp; + if (!all_tables) + all_tables= tmp; + } + /* When option readonly is set deny operations which change tables. Except for the replication thread and the 'super' users. @@ -2011,8 +2025,6 @@ mysql_execute_command(THD *thd) else thd->send_explain_fields(result); res= mysql_explain_union(thd, &thd->lex->unit, result); - MYSQL_LOCK *save_lock= thd->lock; - thd->lock= (MYSQL_LOCK *)0; if (lex->describe & DESCRIBE_EXTENDED) { char buff[1024]; @@ -2024,20 +2036,19 @@ mysql_execute_command(THD *thd) ER_YES, str.ptr()); } result->send_eof(); - thd->lock= save_lock; + delete result; } else { - if (!result) + if (!result && !(result= new select_send())) { - if (!(result=new select_send())) - { - res= -1; - break; - } + res= -1; + break; } query_cache_store_query(thd, all_tables); - res=handle_select(thd, lex, result); + res= handle_select(thd, lex, result); + if (result != lex->result) + delete result; } } break; @@ -2393,6 +2404,21 @@ mysql_execute_command(THD *thd) net_printf(thd, ER_UPDATE_TABLE_USED, create_table->real_name); goto create_error; } + if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + { + TABLE_LIST *tab; + for (tab= select_tables; tab; tab= tab->next_local) + { + if (find_table_in_local_list((TABLE_LIST*) lex->create_info. + merge_list.first, + select_tables->db, tab->real_name)) + { + net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); + goto create_error; + } + } + } + if (select_tables && check_table_access(thd, SELECT_ACL, select_tables, 0)) goto create_error; // Error message is given @@ -2432,7 +2458,7 @@ mysql_execute_command(THD *thd) res= mysql_create_table(thd, create_table->db, create_table->real_name, &lex->create_info, lex->create_list, - lex->key_list, 0, 0, 0); // do logging + lex->key_list, 0, 0); } if (!res) send_ok(thd); @@ -2758,31 +2784,30 @@ unsent_create_error: // is table which we are changing used somewhere in other parts of query if (find_table_in_global_list(all_tables->next_global, - first_table->db, first_table->real_name)) + first_table->db, first_table->real_name)) { /* Using same table for INSERT and SELECT */ select_lex->options |= OPTION_BUFFER_RESULT; } - if (!(res= open_and_lock_tables(thd, all_tables))) + if (!(res= open_and_lock_tables(thd, all_tables)) && + !(res= mysql_insert_select_prepare(thd)) && + (result= new select_insert(first_table, first_table->table, + &lex->field_list, lex->duplicates))) { - if ((res= mysql_insert_select_prepare(thd))) - break; - if ((result= new select_insert(first_table, first_table->table, - &lex->field_list, lex->duplicates))) - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_table->next_local; - /* - insert/replace from SELECT give its SELECT_LEX for SELECT, - and item_list belong to SELECT - */ - lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; - res= handle_select(thd, lex, result); - /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_table; - lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + /* Skip first table, which is the table we are inserting in */ + lex->select_lex.table_list.first= (byte*) first_table->next_local; + /* + insert/replace from SELECT give its SELECT_LEX for SELECT, + and item_list belong to SELECT + */ + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + res= handle_select(thd, lex, result); + lex->select_lex.table_list.first= (byte*) first_table; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + delete result; if (thd->net.report_error) - res= -1; + res= -1; } else res= -1; @@ -2806,7 +2831,7 @@ unsent_create_error: goto error; } - res= mysql_truncate(thd, first_table); + res= mysql_truncate(thd, first_table, 0); break; case SQLCOM_DELETE: { @@ -3755,7 +3780,7 @@ purposes internal to the MySQL server", MYF(0)); case SP_KEY_NOT_FOUND: if (lex->drop_if_exists) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), SP_COM_STRING(lex), lex->spname->m_name.str); res= 0; @@ -4289,6 +4314,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length, bool lexonly) lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; + lex->time_zone_tables_used= 0; lex->proc_table= lex->query_tables= 0; lex->query_tables_last= &lex->query_tables; lex->variables_used= 0; @@ -4323,8 +4349,8 @@ mysql_init_select(LEX *lex) select_lex->select_limit= HA_POS_ERROR; if (select_lex == &lex->select_lex) { + DBUG_ASSERT(lex->result == 0); lex->exchange= 0; - lex->result= 0; lex->proc_list.first= 0; } } @@ -4493,9 +4519,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) } } thd->proc_info="freeing items"; - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; /* free_list should never point to garbage */ - lex_end(lex); + thd->end_statement(); } DBUG_VOID_RETURN; } @@ -4521,10 +4545,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) if (!yyparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; /* free_list should never point to garbage */ - lex_end(lex); - + thd->end_statement(); DBUG_RETURN(error); } #endif @@ -4691,7 +4712,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->sql_type= FIELD_TYPE_BLOB; sprintf(warn_buff, ER(ER_AUTO_CONVERT), field_name, "CHAR", (cs == &my_charset_bin) ? "BLOB" : "TEXT"); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_AUTO_CONVERT, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, warn_buff); /* fall through */ case FIELD_TYPE_BLOB: @@ -4769,8 +4790,12 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, case FIELD_TYPE_TIMESTAMP: if (!length) new_field->length= 14; // Full date YYYYMMDDHHMMSS - else + else if (new_field->length != 19) { + /* + We support only even TIMESTAMP lengths less or equal than 14 + and 19 as length of 4.1 compatible representation. + */ new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */ new_field->length= min(new_field->length,14); /* purecov: inspected */ } @@ -4831,7 +4856,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->length=0; for (const char **pos=interval->type_names; *pos ; pos++) { - new_field->length+=(uint) strip_sp((char*) *pos)+1; + uint length= (uint) strip_sp((char*) *pos)+1; + CHARSET_INFO *cs= thd->variables.character_set_client; + length= cs->cset->numchars(cs, *pos, *pos+length); + new_field->length+= length; } new_field->length--; set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); @@ -4861,8 +4889,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->length=(uint) strip_sp((char*) interval->type_names[0]); for (const char **pos=interval->type_names+1; *pos ; pos++) { - uint length=(uint) strip_sp((char*) *pos); - set_if_bigger(new_field->length,length); + uint length=(uint) strip_sp((char*) *pos); + CHARSET_INFO *cs= thd->variables.character_set_client; + length= cs->cset->numchars(cs, *pos, *pos+length); + set_if_bigger(new_field->length,length); } set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); if (default_value) @@ -5493,9 +5523,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, tmp_write_to_binlog= 0; if (lock_global_read_lock(thd)) return 1; + result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, + tables); + make_global_read_lock_block_commit(thd); } + else + result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables); my_dbopt_cleanup(); - result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables); } if (options & REFRESH_HOSTS) hostname_cache_refresh(); @@ -6056,3 +6090,39 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables, check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0)) ? 1 : 0); } + + +/* + negate given expression + + SYNOPSIS + negate_expression() + thd therad handler + expr expression for negation + + RETURN + negated expression +*/ + +Item *negate_expression(THD *thd, Item *expr) +{ + Item *negated; + if (expr->type() == Item::FUNC_ITEM && + ((Item_func *) expr)->functype() == Item_func::NOT_FUNC) + { + /* it is NOT(NOT( ... )) */ + Item *arg= ((Item_func *) expr)->arguments()[0]; + enum_parsing_place place= thd->lex->current_select->parsing_place; + if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING) + return arg; + /* + if it is not boolean function then we have to emulate value of + not(not(a)), it will be a != 0 + */ + return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1)); + } + + if ((negated= expr->neg_transformer(thd)) != 0) + return negated; + return new Item_func_not(expr); +} |