diff options
author | Michael Widenius <monty@mysql.com> | 2008-10-10 18:28:41 +0300 |
---|---|---|
committer | Michael Widenius <monty@mysql.com> | 2008-10-10 18:28:41 +0300 |
commit | f47e003e1bfc56c2bf5d0f144a35517f526b538b (patch) | |
tree | e2bfb9834c6e558381465ed2f57a9d873a9b2c90 /sql/event_data_objects.cc | |
parent | 51a92bbb03cc58ab8688fa9d8226afe32e6156ca (diff) | |
parent | 9daa56fd5ce3ccd33c32b5a505ac1d2b2c437460 (diff) | |
download | mariadb-git-f47e003e1bfc56c2bf5d0f144a35517f526b538b.tar.gz |
Merged 5.1 with maria 5.1
Diffstat (limited to 'sql/event_data_objects.cc')
-rw-r--r-- | sql/event_data_objects.cc | 563 |
1 files changed, 22 insertions, 541 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index f4962fb35ff..b98922e2408 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -25,8 +25,6 @@ @{ */ -#define EVEX_MAX_INTERVAL_VALUE 1000000000L - /*************************************************************************/ /** @@ -188,524 +186,6 @@ Event_queue_element_for_exec::~Event_queue_element_for_exec() /* - Returns a new instance - - SYNOPSIS - Event_parse_data::new_instance() - - RETURN VALUE - Address or NULL in case of error - - NOTE - Created on THD's mem_root -*/ - -Event_parse_data * -Event_parse_data::new_instance(THD *thd) -{ - return new (thd->mem_root) Event_parse_data; -} - - -/* - Constructor - - SYNOPSIS - Event_parse_data::Event_parse_data() -*/ - -Event_parse_data::Event_parse_data() - :on_completion(Event_basic::ON_COMPLETION_DROP), - status(Event_basic::ENABLED), - do_not_create(FALSE), - body_changed(FALSE), - item_starts(NULL), item_ends(NULL), item_execute_at(NULL), - starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE), - item_expression(NULL), expression(0) -{ - DBUG_ENTER("Event_parse_data::Event_parse_data"); - - /* Actually in the parser STARTS is always set */ - starts= ends= execute_at= 0; - - comment.str= NULL; - comment.length= 0; - - DBUG_VOID_RETURN; -} - - -/* - Set a name of the event - - SYNOPSIS - Event_parse_data::init_name() - thd THD - spn the name extracted in the parser -*/ - -void -Event_parse_data::init_name(THD *thd, sp_name *spn) -{ - DBUG_ENTER("Event_parse_data::init_name"); - - /* We have to copy strings to get them into the right memroot */ - dbname.length= spn->m_db.length; - dbname.str= thd->strmake(spn->m_db.str, spn->m_db.length); - name.length= spn->m_name.length; - name.str= thd->strmake(spn->m_name.str, spn->m_name.length); - - if (spn->m_qname.length == 0) - spn->init_qname(thd); - - DBUG_VOID_RETURN; -} - - -/* - This function is called on CREATE EVENT or ALTER EVENT. When either - ENDS or AT is in the past, we are trying to create an event that - will never be executed. If it has ON COMPLETION NOT PRESERVE - (default), then it would normally be dropped already, so on CREATE - EVENT we give a warning, and do not create anyting. On ALTER EVENT - we give a error, and do not change the event. - - If the event has ON COMPLETION PRESERVE, then we see if the event is - created or altered to the ENABLED (default) state. If so, then we - give a warning, and change the state to DISABLED. - - Otherwise it is a valid event in ON COMPLETION PRESERVE DISABLE - state. -*/ - -void -Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc) -{ - if (ltime_utc >= (my_time_t) thd->query_start()) - return; - - if (on_completion == Event_basic::ON_COMPLETION_DROP) - { - switch (thd->lex->sql_command) { - case SQLCOM_CREATE_EVENT: - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_EVENT_CANNOT_CREATE_IN_THE_PAST, - ER(ER_EVENT_CANNOT_CREATE_IN_THE_PAST)); - break; - case SQLCOM_ALTER_EVENT: - my_error(ER_EVENT_CANNOT_ALTER_IN_THE_PAST, MYF(0)); - break; - default: - DBUG_ASSERT(0); - } - - do_not_create= TRUE; - } - else if (status == Event_basic::ENABLED) - { - status= Event_basic::DISABLED; - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_EVENT_EXEC_TIME_IN_THE_PAST, - ER(ER_EVENT_EXEC_TIME_IN_THE_PAST)); - } -} - - -/* - Sets time for execution for one-time event. - - SYNOPSIS - Event_parse_data::init_execute_at() - thd Thread - - RETURN VALUE - 0 OK - ER_WRONG_VALUE Wrong value for execute at (reported) -*/ - -int -Event_parse_data::init_execute_at(THD *thd) -{ - my_bool not_used; - MYSQL_TIME ltime; - my_time_t ltime_utc; - - DBUG_ENTER("Event_parse_data::init_execute_at"); - - if (!item_execute_at) - DBUG_RETURN(0); - - if (item_execute_at->fix_fields(thd, &item_execute_at)) - goto wrong_value; - - /* no starts and/or ends in case of execute_at */ - DBUG_PRINT("info", ("starts_null && ends_null should be 1 is %d", - (starts_null && ends_null))); - DBUG_ASSERT(starts_null && ends_null); - - if ((not_used= item_execute_at->get_date(<ime, TIME_NO_ZERO_DATE))) - goto wrong_value; - - ltime_utc= TIME_to_timestamp(thd,<ime,¬_used); - if (!ltime_utc) - { - DBUG_PRINT("error", ("Execute AT after year 2037")); - goto wrong_value; - } - - check_if_in_the_past(thd, ltime_utc); - - execute_at_null= FALSE; - execute_at= ltime_utc; - DBUG_RETURN(0); - -wrong_value: - report_bad_value("AT", item_execute_at); - DBUG_RETURN(ER_WRONG_VALUE); -} - - -/* - Sets time for execution of multi-time event.s - - SYNOPSIS - Event_parse_data::init_interval() - thd Thread - - RETURN VALUE - 0 OK - EVEX_BAD_PARAMS Interval is not positive or MICROSECOND (reported) - ER_WRONG_VALUE Wrong value for interval (reported) -*/ - -int -Event_parse_data::init_interval(THD *thd) -{ - String value; - INTERVAL interval_tmp; - - DBUG_ENTER("Event_parse_data::init_interval"); - if (!item_expression) - DBUG_RETURN(0); - - switch (interval) { - case INTERVAL_MINUTE_MICROSECOND: - case INTERVAL_HOUR_MICROSECOND: - case INTERVAL_DAY_MICROSECOND: - case INTERVAL_SECOND_MICROSECOND: - case INTERVAL_MICROSECOND: - my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND"); - DBUG_RETURN(EVEX_BAD_PARAMS); - default: - break; - } - - if (item_expression->fix_fields(thd, &item_expression)) - goto wrong_value; - - value.alloc(MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN); - if (get_interval_value(item_expression, interval, &value, &interval_tmp)) - goto wrong_value; - - expression= 0; - - switch (interval) { - case INTERVAL_YEAR: - expression= interval_tmp.year; - break; - case INTERVAL_QUARTER: - case INTERVAL_MONTH: - expression= interval_tmp.month; - break; - case INTERVAL_WEEK: - case INTERVAL_DAY: - expression= interval_tmp.day; - break; - case INTERVAL_HOUR: - expression= interval_tmp.hour; - break; - case INTERVAL_MINUTE: - expression= interval_tmp.minute; - break; - case INTERVAL_SECOND: - expression= interval_tmp.second; - break; - case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM - expression= interval_tmp.year* 12 + interval_tmp.month; - break; - case INTERVAL_DAY_HOUR: - expression= interval_tmp.day* 24 + interval_tmp.hour; - break; - case INTERVAL_DAY_MINUTE: - expression= (interval_tmp.day* 24 + interval_tmp.hour) * 60 + - interval_tmp.minute; - break; - case INTERVAL_HOUR_SECOND: /* day is anyway 0 */ - case INTERVAL_DAY_SECOND: - /* DAY_SECOND having problems because of leap seconds? */ - expression= ((interval_tmp.day* 24 + interval_tmp.hour) * 60 + - interval_tmp.minute)*60 - + interval_tmp.second; - break; - case INTERVAL_HOUR_MINUTE: - expression= interval_tmp.hour * 60 + interval_tmp.minute; - break; - case INTERVAL_MINUTE_SECOND: - expression= interval_tmp.minute * 60 + interval_tmp.second; - break; - case INTERVAL_LAST: - DBUG_ASSERT(0); - default: - ;/* these are the microsec stuff */ - } - if (interval_tmp.neg || expression == 0 || - expression > EVEX_MAX_INTERVAL_VALUE) - { - my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0)); - DBUG_RETURN(EVEX_BAD_PARAMS); - } - - DBUG_RETURN(0); - -wrong_value: - report_bad_value("INTERVAL", item_expression); - DBUG_RETURN(ER_WRONG_VALUE); -} - - -/* - Sets STARTS. - - SYNOPSIS - Event_parse_data::init_starts() - expr how much? - - NOTES - Note that activation time is not execution time. - EVERY 5 MINUTE STARTS "2004-12-12 10:00:00" means that - the event will be executed every 5 minutes but this will - start at the date shown above. Expressions are possible : - DATE_ADD(NOW(), INTERVAL 1 DAY) -- start tommorow at - same time. - - RETURN VALUE - 0 OK - ER_WRONG_VALUE Starts before now -*/ - -int -Event_parse_data::init_starts(THD *thd) -{ - my_bool not_used; - MYSQL_TIME ltime; - my_time_t ltime_utc; - - DBUG_ENTER("Event_parse_data::init_starts"); - if (!item_starts) - DBUG_RETURN(0); - - if (item_starts->fix_fields(thd, &item_starts)) - goto wrong_value; - - if ((not_used= item_starts->get_date(<ime, TIME_NO_ZERO_DATE))) - goto wrong_value; - - ltime_utc= TIME_to_timestamp(thd, <ime, ¬_used); - if (!ltime_utc) - goto wrong_value; - - DBUG_PRINT("info",("now: %ld starts: %ld", - (long) thd->query_start(), (long) ltime_utc)); - - starts_null= FALSE; - starts= ltime_utc; - DBUG_RETURN(0); - -wrong_value: - report_bad_value("STARTS", item_starts); - DBUG_RETURN(ER_WRONG_VALUE); -} - - -/* - Sets ENDS (deactivation time). - - SYNOPSIS - Event_parse_data::init_ends() - thd THD - - NOTES - Note that activation time is not execution time. - EVERY 5 MINUTE ENDS "2004-12-12 10:00:00" means that - the event will be executed every 5 minutes but this will - end at the date shown above. Expressions are possible : - DATE_ADD(NOW(), INTERVAL 1 DAY) -- end tommorow at - same time. - - RETURN VALUE - 0 OK - EVEX_BAD_PARAMS Error (reported) -*/ - -int -Event_parse_data::init_ends(THD *thd) -{ - my_bool not_used; - MYSQL_TIME ltime; - my_time_t ltime_utc; - - DBUG_ENTER("Event_parse_data::init_ends"); - if (!item_ends) - DBUG_RETURN(0); - - if (item_ends->fix_fields(thd, &item_ends)) - goto error_bad_params; - - DBUG_PRINT("info", ("convert to TIME")); - if ((not_used= item_ends->get_date(<ime, TIME_NO_ZERO_DATE))) - goto error_bad_params; - - ltime_utc= TIME_to_timestamp(thd, <ime, ¬_used); - if (!ltime_utc) - goto error_bad_params; - - /* Check whether ends is after starts */ - DBUG_PRINT("info", ("ENDS after STARTS?")); - if (!starts_null && starts >= ltime_utc) - goto error_bad_params; - - check_if_in_the_past(thd, ltime_utc); - - ends_null= FALSE; - ends= ltime_utc; - DBUG_RETURN(0); - -error_bad_params: - my_error(ER_EVENT_ENDS_BEFORE_STARTS, MYF(0)); - DBUG_RETURN(EVEX_BAD_PARAMS); -} - - -/* - Prints an error message about invalid value. Internally used - during input data verification - - SYNOPSIS - Event_parse_data::report_bad_value() - item_name The name of the parameter - bad_item The parameter -*/ - -void -Event_parse_data::report_bad_value(const char *item_name, Item *bad_item) -{ - char buff[120]; - String str(buff,(uint32) sizeof(buff), system_charset_info); - String *str2= bad_item->fixed? bad_item->val_str(&str):NULL; - my_error(ER_WRONG_VALUE, MYF(0), item_name, str2? str2->c_ptr_safe():"NULL"); -} - - -/* - Checks for validity the data gathered during the parsing phase. - - SYNOPSIS - Event_parse_data::check_parse_data() - thd Thread - - RETURN VALUE - FALSE OK - TRUE Error (reported) -*/ - -bool -Event_parse_data::check_parse_data(THD *thd) -{ - bool ret; - DBUG_ENTER("Event_parse_data::check_parse_data"); - DBUG_PRINT("info", ("execute_at: 0x%lx expr=0x%lx starts=0x%lx ends=0x%lx", - (long) item_execute_at, (long) item_expression, - (long) item_starts, (long) item_ends)); - - init_name(thd, identifier); - - init_definer(thd); - - ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) || - init_ends(thd); - check_originator_id(thd); - DBUG_RETURN(ret); -} - - -/* - Inits definer (definer_user and definer_host) during parsing. - - SYNOPSIS - Event_parse_data::init_definer() - thd Thread -*/ - -void -Event_parse_data::init_definer(THD *thd) -{ - DBUG_ENTER("Event_parse_data::init_definer"); - - DBUG_ASSERT(thd->lex->definer); - - const char *definer_user= thd->lex->definer->user.str; - const char *definer_host= thd->lex->definer->host.str; - int definer_user_len= thd->lex->definer->user.length; - int definer_host_len= thd->lex->definer->host.length; - - DBUG_PRINT("info",("init definer_user thd->mem_root: 0x%lx " - "definer_user: 0x%lx", (long) thd->mem_root, - (long) definer_user)); - - /* + 1 for @ */ - DBUG_PRINT("info",("init definer as whole")); - definer.length= definer_user_len + definer_host_len + 1; - definer.str= (char*) thd->alloc(definer.length + 1); - - DBUG_PRINT("info",("copy the user")); - memcpy(definer.str, definer_user, definer_user_len); - definer.str[definer_user_len]= '@'; - - DBUG_PRINT("info",("copy the host")); - memcpy(definer.str + definer_user_len + 1, definer_host, definer_host_len); - definer.str[definer.length]= '\0'; - DBUG_PRINT("info",("definer [%s] initted", definer.str)); - - DBUG_VOID_RETURN; -} - - -/** - Set the originator id of the event to the server_id if executing on - the master or set to the server_id of the master if executing on - the slave. If executing on slave, also set status to SLAVESIDE_DISABLED. - - SYNOPSIS - Event_parse_data::check_originator_id() -*/ -void Event_parse_data::check_originator_id(THD *thd) -{ - /* Disable replicated events on slave. */ - if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL) || - (thd->system_thread == SYSTEM_THREAD_SLAVE_IO)) - { - DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED.")); - if ((status == Event_basic::ENABLED) || - (status == Event_basic::DISABLED)) - status = Event_basic::SLAVESIDE_DISABLED; - originator = thd->server_id; - } - else - originator = server_id; -} - - -/* Constructor SYNOPSIS @@ -799,8 +279,9 @@ Event_basic::load_time_zone(THD *thd, const LEX_STRING tz_name) Event_queue_element::Event_queue_element(): status_changed(FALSE), last_executed_changed(FALSE), - on_completion(ON_COMPLETION_DROP), status(ENABLED), - expression(0), dropped(FALSE), execution_count(0) + on_completion(Event_parse_data::ON_COMPLETION_DROP), + status(Event_parse_data::ENABLED), expression(0), dropped(FALSE), + execution_count(0) { DBUG_ENTER("Event_queue_element::Event_queue_element"); @@ -1057,14 +538,14 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table) switch (ptr[0]) { case 'E' : - status = Event_queue_element::ENABLED; + status = Event_parse_data::ENABLED; break; case 'S' : - status = Event_queue_element::SLAVESIDE_DISABLED; + status = Event_parse_data::SLAVESIDE_DISABLED; break; case 'D' : default: - status = Event_queue_element::DISABLED; + status = Event_parse_data::DISABLED; break; } if ((ptr= get_field(&mem_root, table->field[ET_FIELD_ORIGINATOR])) == NullS) @@ -1076,8 +557,8 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table) table->field[ET_FIELD_ON_COMPLETION])) == NullS) DBUG_RETURN(TRUE); - on_completion= (ptr[0]=='D'? Event_queue_element::ON_COMPLETION_DROP: - Event_queue_element::ON_COMPLETION_PRESERVE); + on_completion= (ptr[0]=='D'? Event_parse_data::ON_COMPLETION_DROP: + Event_parse_data::ON_COMPLETION_PRESERVE); DBUG_RETURN(FALSE); } @@ -1422,7 +903,7 @@ Event_queue_element::compute_next_execution_time() (long) starts, (long) ends, (long) last_executed, (long) this)); - if (status != Event_queue_element::ENABLED) + if (status != Event_parse_data::ENABLED) { DBUG_PRINT("compute_next_execution_time", ("Event %s is DISABLED", name.str)); @@ -1436,10 +917,10 @@ Event_queue_element::compute_next_execution_time() { DBUG_PRINT("info",("One-time event %s.%s of was already executed", dbname.str, name.str)); - dropped= (on_completion == Event_queue_element::ON_COMPLETION_DROP); + dropped= (on_completion == Event_parse_data::ON_COMPLETION_DROP); DBUG_PRINT("info",("One-time event will be dropped: %d.", dropped)); - status= Event_queue_element::DISABLED; + status= Event_parse_data::DISABLED; status_changed= TRUE; } goto ret; @@ -1456,10 +937,10 @@ Event_queue_element::compute_next_execution_time() /* time_now is after ends. don't execute anymore */ execute_at= 0; execute_at_null= TRUE; - if (on_completion == Event_queue_element::ON_COMPLETION_DROP) + if (on_completion == Event_parse_data::ON_COMPLETION_DROP) dropped= TRUE; DBUG_PRINT("info", ("Dropped: %d", dropped)); - status= Event_queue_element::DISABLED; + status= Event_parse_data::DISABLED; status_changed= TRUE; goto ret; @@ -1520,9 +1001,9 @@ Event_queue_element::compute_next_execution_time() /* Next execution after ends. No more executions */ execute_at= 0; execute_at_null= TRUE; - if (on_completion == Event_queue_element::ON_COMPLETION_DROP) + if (on_completion == Event_parse_data::ON_COMPLETION_DROP) dropped= TRUE; - status= Event_queue_element::DISABLED; + status= Event_parse_data::DISABLED; status_changed= TRUE; } else @@ -1612,9 +1093,9 @@ Event_queue_element::compute_next_execution_time() DBUG_PRINT("info", ("Next execution after ENDS. Stop executing.")); execute_at= 0; execute_at_null= TRUE; - status= Event_queue_element::DISABLED; + status= Event_parse_data::DISABLED; status_changed= TRUE; - if (on_completion == Event_queue_element::ON_COMPLETION_DROP) + if (on_completion == Event_parse_data::ON_COMPLETION_DROP) dropped= TRUE; } else @@ -1766,14 +1247,14 @@ Event_timed::get_create_event(THD *thd, String *buf) STRING_WITH_LEN("ON SCHEDULE AT")); } - if (on_completion == Event_timed::ON_COMPLETION_DROP) + if (on_completion == Event_parse_data::ON_COMPLETION_DROP) buf->append(STRING_WITH_LEN(" ON COMPLETION NOT PRESERVE ")); else buf->append(STRING_WITH_LEN(" ON COMPLETION PRESERVE ")); - if (status == Event_timed::ENABLED) + if (status == Event_parse_data::ENABLED) buf->append(STRING_WITH_LEN("ENABLE")); - else if (status == Event_timed::SLAVESIDE_DISABLED) + else if (status == Event_parse_data::SLAVESIDE_DISABLED) buf->append(STRING_WITH_LEN("DISABLE ON SLAVE")); else buf->append(STRING_WITH_LEN("DISABLE")); @@ -1957,10 +1438,10 @@ Event_job_data::execute(THD *thd, bool drop) thd->query_length= sp_sql.length(); { - Lex_input_stream lip(thd, thd->query, thd->query_length); + Parser_state parser_state(thd, thd->query, thd->query_length); lex_start(thd); - if (parse_sql(thd, &lip, creation_ctx)) + if (parse_sql(thd, & parser_state, creation_ctx)) { sql_print_error("Event Scheduler: " "%serror during compilation of %s.%s", |