diff options
author | Igor Babaev <igor@askmonty.org> | 2018-06-03 10:34:41 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2018-06-03 10:34:41 -0700 |
commit | cab1d6382623f0611335caf2cd056aa7ee04d7cd (patch) | |
tree | c33b8118a77a78d87d8fb01e908dbfa6a67ca9a2 /sql | |
parent | ffe83e8e7bef32eb2a80aad2d382f0b023dd3a44 (diff) | |
parent | ee5124d714ea01f4e1bd6decf6da38b05c1009ad (diff) | |
download | mariadb-git-cab1d6382623f0611335caf2cd056aa7ee04d7cd.tar.gz |
Merge branch '10.3' into 10.4
Diffstat (limited to 'sql')
177 files changed, 12706 insertions, 9925 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index ca5c7c87bf5..7253f7ba447 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -469,12 +469,13 @@ IF(WIN32) ADD_CUSTOM_COMMAND(OUTPUT ${my_bootstrap_sql} COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_SOURCE_DIR}/scripts - cmd /c copy mysql_system_tables.sql+mysql_system_tables_data.sql+fill_help_tables.sql+mysql_performance_tables.sql ${native_outfile} + cmd /c copy mysql_system_tables.sql+mysql_system_tables_data.sql+fill_help_tables.sql+mysql_performance_tables.sql+mysql_test_db.sql ${native_outfile} DEPENDS ${CMAKE_SOURCE_DIR}/scripts/mysql_system_tables.sql ${CMAKE_SOURCE_DIR}/scripts/mysql_system_tables_data.sql ${CMAKE_SOURCE_DIR}/scripts/fill_help_tables.sql ${CMAKE_SOURCE_DIR}/scripts/mysql_performance_tables.sql + ${CMAKE_SOURCE_DIR}/scripts/mysql_test_db.sql ) ADD_CUSTOM_COMMAND( diff --git a/sql/create_options.h b/sql/create_options.h index c82cb875743..16be5affde0 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -63,7 +63,7 @@ class engine_option_value: public Sql_alloc name(name_arg), next(NULL), parsed(false), quoted_value(false) { char *str; - if ((value.str= str= (char *)alloc_root(root, 22))) + if (likely((value.str= str= (char *)alloc_root(root, 22)))) { value.length= longlong10_to_str(value_arg, str, 10) - str; link(start, end); diff --git a/sql/datadict.cc b/sql/datadict.cc index 4e18fe06cb6..410dbff8778 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -89,10 +89,10 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name, ((char*) (engine_name->str))[0]= 0; } - if ((error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP)))) + if (unlikely((error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP))))) goto err; - if (!strncmp((char*) header, "TYPE=VIEW\n", 10)) + if (unlikely((!strncmp((char*) header, "TYPE=VIEW\n", 10)))) { type= TABLE_TYPE_VIEW; goto err; diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 58a01a77849..d25c1a75e96 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -790,7 +790,7 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action) and shall not be reported as a result of SET DEBUG_SYNC. Hence, we check for the first condition above. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(TRUE); } @@ -1448,7 +1448,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) DBUG_PRINT("debug_sync", ("awoke from %s global: %s error: %d", sig_wait, sig_glob, error));}); - if (error == ETIMEDOUT || error == ETIME) + if (unlikely(error == ETIMEDOUT || error == ETIME)) { // We should not make the statement fail, even if in strict mode. const bool save_abort_on_warning= thd->abort_on_warning; diff --git a/sql/derror.cc b/sql/derror.cc index 8011f8c4020..011f8e1669c 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -232,7 +232,8 @@ static File open_error_msg_file(const char *file_name, const char *language, ret->errors= uint2korr(head+12); ret->sections= uint2korr(head+14); - if (ret->max_error < error_messages || ret->sections != MAX_ERROR_RANGES) + if (unlikely(ret->max_error < error_messages || + ret->sections != MAX_ERROR_RANGES)) { sql_print_error("\ Error message file '%s' had only %d error messages, but it should contain at least %d error messages.\nCheck that the above file is the right version for this program!", @@ -276,8 +277,8 @@ bool read_texts(const char *file_name, const char *language, struct st_msg_file msg_file; DBUG_ENTER("read_texts"); - if ((file= open_error_msg_file(file_name, language, error_messages, - &msg_file)) == FERR) + if (unlikely((file= open_error_msg_file(file_name, language, error_messages, + &msg_file)) == FERR)) DBUG_RETURN(1); if (!(*data= (const char***) diff --git a/sql/discover.cc b/sql/discover.cc index 7184cde5e03..afebce77bf9 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -127,7 +127,7 @@ int writefrm(const char *path, const char *db, const char *table, File file= mysql_file_create(key_file_frm, file_name, CREATE_MODE, create_flags, MYF(0)); - if ((error= file < 0)) + if (unlikely((error= file < 0))) { if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR, MYF(0), db); diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 59aa6bcabc6..28820f05aa3 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1444,7 +1444,7 @@ Event_job_data::execute(THD *thd, bool drop) } end: - if (drop && !thd->is_fatal_error) + if (drop && likely(!thd->is_fatal_error)) { /* We must do it here since here we're under the right authentication diff --git a/sql/events.cc b/sql/events.cc index 2fbb16861f6..6a8695843a3 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -320,7 +320,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data) enum_binlog_format save_binlog_format; DBUG_ENTER("Events::create_event"); - if (check_if_system_tables_error()) + if (unlikely(check_if_system_tables_error())) DBUG_RETURN(TRUE); /* @@ -455,7 +455,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, DBUG_ENTER("Events::update_event"); - if (check_if_system_tables_error()) + if (unlikely(check_if_system_tables_error())) DBUG_RETURN(TRUE); if (parse_data->check_parse_data(thd) || parse_data->do_not_create) @@ -589,7 +589,7 @@ Events::drop_event(THD *thd, const LEX_CSTRING *dbname, enum_binlog_format save_binlog_format; DBUG_ENTER("Events::drop_event"); - if (check_if_system_tables_error()) + if (unlikely(check_if_system_tables_error())) DBUG_RETURN(TRUE); if (check_access(thd, EVENT_ACL, dbname->str, NULL, NULL, 0, 0)) @@ -761,7 +761,7 @@ Events::show_create_event(THD *thd, const LEX_CSTRING *dbname, DBUG_ENTER("Events::show_create_event"); DBUG_PRINT("enter", ("name: %s@%s", dbname->str, name->str)); - if (check_if_system_tables_error()) + if (unlikely(check_if_system_tables_error())) DBUG_RETURN(TRUE); if (check_access(thd, EVENT_ACL, dbname->str, NULL, NULL, 0, 0)) @@ -817,7 +817,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) if (opt_noacl) DBUG_RETURN(0); - if (check_if_system_tables_error()) + if (unlikely(check_if_system_tables_error())) DBUG_RETURN(1); /* diff --git a/sql/field.cc b/sql/field.cc index 4f04fef1a26..a5b8e4a9e51 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1348,7 +1348,7 @@ bool Field::sp_prepare_and_store_item(THD *thd, Item **value) expr_item->save_in_field(this, 0); - if (!thd->is_error()) + if (likely(!thd->is_error())) DBUG_RETURN(false); error: @@ -1388,7 +1388,7 @@ void Field_num::prepend_zeros(String *value) const if ((diff= (int) (field_length - value->length())) > 0) { const bool error= value->realloc(field_length); - if (!error) + if (likely(!error)) { bmove_upp((uchar*) value->ptr()+field_length, (uchar*) value->ptr()+value->length(), @@ -1630,7 +1630,7 @@ double Field_real::get_double(const char *str, size_t length, CHARSET_INFO *cs, { char *end; double nr= my_strntod(cs,(char*) str, length, &end, error); - if (*error) + if (unlikely(*error)) { set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); *error= 1; @@ -2908,7 +2908,7 @@ int Field_decimal::store(double nr) return 1; } - if (!isfinite(nr)) // Handle infinity as special case + if (!std::isfinite(nr)) // Handle infinity as special case { overflow(nr < 0.0); return 1; @@ -3190,7 +3190,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value, *native_error= my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, decimal_value, ptr, precision, dec); - if (*native_error == E_DEC_OVERFLOW) + if (unlikely(*native_error == E_DEC_OVERFLOW)) { my_decimal buff; DBUG_PRINT("info", ("overflow")); @@ -3209,7 +3209,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) { int native_error; bool rc= store_value(decimal_value, &native_error); - if (!rc && native_error == E_DEC_TRUNCATED) + if (unlikely(!rc && native_error == E_DEC_TRUNCATED)) set_note(WARN_DATA_TRUNCATED, 1); return rc; } @@ -4189,7 +4189,7 @@ int Field_long::store(double nr) else res=(int32) (longlong) nr; } - if (error) + if (unlikely(error)) set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); int4store(ptr,res); @@ -4235,7 +4235,7 @@ int Field_long::store(longlong nr, bool unsigned_val) else res=(int32) nr; } - if (error) + if (unlikely(error)) set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); int4store(ptr,res); @@ -4319,7 +4319,7 @@ int Field_longlong::store(const char *from,size_t len,CHARSET_INFO *cs) ulonglong tmp; tmp= cs->cset->strntoull10rnd(cs,from,len,unsigned_flag,&end,&error); - if (error == MY_ERRNO_ERANGE) + if (unlikely(error == MY_ERRNO_ERANGE)) { set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; @@ -4339,7 +4339,7 @@ int Field_longlong::store(double nr) ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; Converter_double_to_longlong conv(nr, unsigned_flag); - if (conv.error()) + if (unlikely(conv.error())) set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); int8store(ptr, conv.result()); @@ -4352,7 +4352,7 @@ int Field_longlong::store(longlong nr, bool unsigned_val) ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; - if (nr < 0) // Only possible error + if (unlikely(nr < 0)) // Only possible error { /* if field is unsigned and value is signed (< 0) or @@ -4501,7 +4501,7 @@ int Field_float::store(double nr) int error= truncate_double(&nr, field_length, not_fixed ? NOT_FIXED_DEC : dec, unsigned_flag, FLT_MAX); - if (error) + if (unlikely(error)) { set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); if (error < 0) // Wrong double value @@ -4680,7 +4680,7 @@ int Field_double::store(double nr) int error= truncate_double(&nr, field_length, not_fixed ? NOT_FIXED_DEC : dec, unsigned_flag, DBL_MAX); - if (error) + if (unlikely(error)) { set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); if (error < 0) // Wrong double value @@ -4718,7 +4718,7 @@ int truncate_double(double *nr, uint field_length, uint dec, int error= 0; double res= *nr; - if (isnan(res)) + if (std::isnan(res)) { *nr= 0; return -1; @@ -4740,7 +4740,7 @@ int truncate_double(double *nr, uint field_length, uint dec, max_value-= 1.0 / log_10[dec]; /* Check for infinity so we don't get NaN in calculations */ - if (!my_isinf(res)) + if (!std::isinf(res)) { double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec]; res= floor(res) + tmp; @@ -4847,7 +4847,7 @@ double Field_double::val_real(void) longlong Field_double::val_int_from_real(bool want_unsigned_result) { Converter_double_to_longlong conv(val_real(), want_unsigned_result); - if (!want_unsigned_result && conv.error()) + if (unlikely(!want_unsigned_result && conv.error())) conv.push_warning(get_thd(), Field_double::val_real(), false); return conv.result(); } @@ -5084,7 +5084,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time, timestamp= TIME_to_timestamp(thd, l_time, &conversion_error); if (timestamp == 0 && l_time->second_part == 0) conversion_error= ER_WARN_DATA_OUT_OF_RANGE; - if (conversion_error) + if (unlikely(conversion_error)) { set_datetime_warning(conversion_error, str, MYSQL_TIMESTAMP_DATETIME, !error); @@ -6276,7 +6276,7 @@ int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs) if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION && (error= check_int(cs, from, len, end, error))) { - if (error == 1) /* empty or incorrect string */ + if (unlikely(error == 1) /* empty or incorrect string */) { *ptr= 0; return 1; @@ -6943,7 +6943,7 @@ Field_longstr::check_string_copy_error(const String_copier *copier, const char *pos; char tmp[32]; - if (!(pos= copier->most_important_error_pos())) + if (likely(!(pos= copier->most_important_error_pos()))) return FALSE; convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6); @@ -7003,15 +7003,15 @@ int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length; - String_copier copier; + int rc; /* See the comment for Field_long::store(long long) */ DBUG_ASSERT(!table || table->in_use == current_thd); - copy_length= copier.well_formed_copy(field_charset, - (char*) ptr, field_length, - cs, from, length, - field_length / field_charset->mbmaxlen); + rc= well_formed_copy_with_check((char*) ptr, field_length, + cs, from, length, + field_length / field_charset->mbmaxlen, + false, ©_length); /* Append spaces if the string was shorter than the field. */ if (copy_length < field_length) @@ -7019,7 +7019,7 @@ int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs) field_length-copy_length, field_charset->pad_char); - return check_conversion_status(&copier, from + length, cs, false); + return rc; } @@ -7055,10 +7055,10 @@ int Field_str::store(double nr) my_bool error= (local_char_length == 0); // my_gcvt() requires width > 0, and we may have a CHAR(0) column. - if (!error) + if (likely(!error)) length= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, local_char_length, buff, &error); - if (error) + if (unlikely(error)) { if (get_thd()->abort_on_warning) set_warning(ER_DATA_TOO_LONG, 1); @@ -7553,19 +7553,16 @@ int Field_varstring::store(const char *from,size_t length,CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length; - String_copier copier; + int rc; - copy_length= copier.well_formed_copy(field_charset, - (char*) ptr + length_bytes, - field_length, - cs, from, length, - field_length / field_charset->mbmaxlen); - if (length_bytes == 1) - *ptr= (uchar) copy_length; - else - int2store(ptr, copy_length); + rc= well_formed_copy_with_check((char*) get_data(), field_length, + cs, from, length, + field_length / field_charset->mbmaxlen, + true, ©_length); + + store_length(copy_length); - return check_conversion_status(&copier, from + length, cs, true); + return rc; } @@ -7959,10 +7956,13 @@ void Field_varstring::hash(ulong *nr, ulong *nr2) Compress field @param[out] to destination buffer for compressed data - @param[in,out] to_length in: size of to, out: compressed data length + @param[in] to_length size of to @param[in] from data to compress @param[in] length from length + @param[in] max_length truncate `from' to this length + @param[out] out_length compessed data length @param[in] cs from character set + @param[in] nchars copy no more than "nchars" characters In worst case (no compression performed) storage requirement is increased by 1 byte to store header. If it exceeds field length, normal data truncation is @@ -7986,52 +7986,57 @@ void Field_varstring::hash(ulong *nr, ulong *nr2) followed by compressed data. */ -int Field_longstr::compress(char *to, uint *to_length, +int Field_longstr::compress(char *to, uint to_length, const char *from, uint length, - CHARSET_INFO *cs) + uint max_length, + uint *out_length, + CHARSET_INFO *cs, size_t nchars) { THD *thd= get_thd(); - char *buf= 0; + char *buf; + uint buf_length; int rc= 0; - if (length == 0) - { - *to_length= 0; - return 0; - } - if (String::needs_conversion_on_storage(length, cs, field_charset) || - *to_length <= length) + max_length < length) { - String_copier copier; - const char *end= from + length; - - if (!(buf= (char*) my_malloc(*to_length - 1, MYF(MY_WME)))) + set_if_smaller(max_length, static_cast<ulonglong>(field_charset->mbmaxlen) * length + 1); + if (!(buf= (char*) my_malloc(max_length, MYF(MY_WME)))) { - *to_length= 0; + *out_length= 0; return -1; } - length= copier.well_formed_copy(field_charset, buf, *to_length - 1, - cs, from, length, - (*to_length - 1) / field_charset->mbmaxlen); - rc= check_conversion_status(&copier, end, cs, true); - from= buf; - DBUG_ASSERT(length > 0); + rc= well_formed_copy_with_check(buf, max_length, cs, from, length, + nchars, true, &buf_length); + } + else + { + buf= const_cast<char*>(from); + buf_length= length; } - if (length >= thd->variables.column_compression_threshold && - (*to_length= compression_method()->compress(thd, to, from, length))) + if (buf_length == 0) + *out_length= 0; + else if (buf_length >= thd->variables.column_compression_threshold && + (*out_length= compression_method()->compress(thd, to, buf, buf_length))) status_var_increment(thd->status_var.column_compressions); else { /* Store uncompressed */ to[0]= 0; - memcpy(to + 1, from, length); - *to_length= length + 1; + if (buf_length < to_length) + memcpy(to + 1, buf, buf_length); + else + { + /* Storing string at blob capacity, e.g. 255 bytes string to TINYBLOB. */ + rc= well_formed_copy_with_check(to + 1, to_length - 1, cs, from, length, + nchars, true, &buf_length); + } + *out_length= buf_length + 1; } - if (buf) + if (buf != from) my_free(buf); return rc; } @@ -8085,9 +8090,12 @@ int Field_varstring_compressed::store(const char *from, size_t length, CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; - uint to_length= (uint)MY_MIN(field_length, field_charset->mbmaxlen * length + 1); - int rc= compress((char*) get_data(), &to_length, from, (uint)length, cs); - store_length(to_length); + uint compressed_length; + int rc= compress((char*) get_data(), field_length, from, (uint) length, + Field_varstring_compressed::max_display_length(), + &compressed_length, cs, + Field_varstring_compressed::char_length()); + store_length(compressed_length); return rc; } @@ -8215,10 +8223,11 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; size_t copy_length, new_length; - String_copier copier; + uint copy_len; char *tmp; char buff[STRING_BUFFER_USUAL_SIZE]; String tmpstr(buff,sizeof(buff), &my_charset_bin); + int rc; if (!length) { @@ -8285,13 +8294,13 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs) bmove(ptr + packlength, (uchar*) &tmp, sizeof(char*)); return 0; } - copy_length= copier.well_formed_copy(field_charset, - (char*) value.ptr(), (uint)new_length, - cs, from, length); - Field_blob::store_length(copy_length); + rc= well_formed_copy_with_check((char*) value.ptr(), (uint) new_length, + cs, from, length, + length, true, ©_len); + Field_blob::store_length(copy_len); bmove(ptr+packlength,(uchar*) &tmp,sizeof(char*)); - return check_conversion_status(&copier, from + length, cs, true); + return rc; oom_error: /* Fatal OOM error */ @@ -8695,7 +8704,10 @@ int Field_blob_compressed::store(const char *from, size_t length, CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; - uint to_length= (uint)MY_MIN(max_data_length(), field_charset->mbmaxlen * length + 1); + uint compressed_length; + uint max_length= max_data_length(); + uint to_length= (uint) MY_MIN(max_length, + field_charset->mbmaxlen * length + 1); String tmp(from, length, cs); int rc; @@ -8705,8 +8717,9 @@ int Field_blob_compressed::store(const char *from, size_t length, if (value.alloc(to_length)) goto oom; - rc= compress((char*) value.ptr(), &to_length, tmp.ptr(), (uint) length, cs); - set_ptr(to_length, (uchar*) value.ptr()); + rc= compress((char*) value.ptr(), to_length, tmp.ptr(), (uint) length, + max_length, &compressed_length, cs, (uint) length); + set_ptr(compressed_length, (uchar*) value.ptr()); return rc; oom: @@ -10319,7 +10332,7 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name, if (type == VCOL_GENERATED_VIRTUAL) filter|= VCOL_NOT_VIRTUAL; - if (ret || (res.errors & filter)) + if (unlikely(ret || (res.errors & filter))) { my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, vcol_type_name(type), name->str); @@ -10805,6 +10818,12 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field, uint32 Field_blob::char_length() const { + return Field_blob::octet_length(); +} + + +uint32 Field_blob::octet_length() const +{ switch (packlength) { case 1: @@ -10879,7 +10898,7 @@ bool Column_definition::set_compressed(const char *method) length */ -uint32 Field_blob::max_display_length() +uint32 Field_blob::max_display_length() const { switch (packlength) { @@ -11061,8 +11080,8 @@ bool Field::save_in_field_default_value(bool view_error_processing) { THD *thd= table->in_use; - if (flags & NO_DEFAULT_VALUE_FLAG && - real_type() != MYSQL_TYPE_ENUM) + if (unlikely(flags & NO_DEFAULT_VALUE_FLAG && + real_type() != MYSQL_TYPE_ENUM)) { if (reset()) { diff --git a/sql/field.h b/sql/field.h index eb4be46d3a0..b6f28808e2e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -745,13 +745,15 @@ public: { return DTCollation(charset(), derivation(), repertoire()); } - Type_std_attributes type_std_attributes() const + virtual Type_std_attributes type_std_attributes() const { return Type_std_attributes(field_length, decimals(), MY_TEST(flags & UNSIGNED_FLAG), dtcollation()); } + bool is_unsigned() const { return flags & UNSIGNED_FLAG; } + /** Convenience definition of a copy function returned by Field::get_copy_func() @@ -1090,6 +1092,16 @@ public: memcpy(ptr, val, len); } virtual uint decimals() const { return 0; } + virtual Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + return Information_schema_numeric_attributes(); + } + virtual Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(); + } /* Caller beware: sql_type can change str.Ptr, so check ptr() to see if it changed if you are using your own buffer @@ -1382,8 +1394,7 @@ public: new_table->s->db_create_options|= HA_OPTION_PACK_RECORD; } /* maximum possible display length */ - virtual uint32 max_display_length()= 0; - + virtual uint32 max_display_length() const= 0; /** Whether a field being created is compatible with a existing one. @@ -1444,11 +1455,6 @@ public: return flags & VERS_UPDATE_UNVERSIONED_FLAG; } - virtual bool vers_trx_id() const - { - return false; - } - /* Validate a non-null field value stored in the given record according to the current thread settings, e.g. sql_mode. @@ -1544,7 +1550,7 @@ public: } virtual bool sp_prepare_and_store_item(THD *thd, Item **value); - friend int cre_myisam(char * name, register TABLE *form, uint options, + friend int cre_myisam(char * name, TABLE *form, uint options, ulonglong auto_increment_value); friend class Copy_field; friend class Item_avg_field; @@ -1718,7 +1724,14 @@ public: CHARSET_INFO *charset(void) const { return field_charset; } enum Derivation derivation(void) const { return field_derivation; } bool binary() const { return field_charset == &my_charset_bin; } - uint32 max_display_length() { return field_length; } + uint32 max_display_length() const { return field_length; } + uint32 char_length() const { return field_length / field_charset->mbmaxlen; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(max_display_length(), + char_length()); + } friend class Create_field; my_decimal *val_decimal(my_decimal *); bool val_bool() { return val_real() != 0e0; } @@ -1751,13 +1764,29 @@ protected: return report_if_important_data(copier->source_end_pos(), end, count_spaces); } + int well_formed_copy_with_check(char *to, size_t to_length, + CHARSET_INFO *from_cs, + const char *from, size_t from_length, + size_t nchars, bool count_spaces, + uint *copy_length) + { + String_copier copier; + + *copy_length= copier.well_formed_copy(field_charset, to, to_length, + from_cs, from, from_length, + nchars); + + return check_conversion_status(&copier, from + from_length, from_cs, count_spaces); + } bool cmp_to_string_with_same_collation(const Item_bool_func *cond, const Item *item) const; bool cmp_to_string_with_stricter_collation(const Item_bool_func *cond, const Item *item) const; - int compress(char *to, uint *to_length, + int compress(char *to, uint to_length, const char *from, uint length, - CHARSET_INFO *cs); + uint max_length, + uint *out_length, + CHARSET_INFO *cs, size_t nchars); String *uncompress(String *val_buffer, String *val_ptr, const uchar *from, uint from_length); public: @@ -1809,6 +1838,13 @@ public: { return do_field_real; } + Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + return dec == NOT_FIXED_DEC ? + Information_schema_numeric_attributes(field_length) : + Information_schema_numeric_attributes(field_length, dec); + } int save_in_field(Field *to) { return to->store(val_real()); } bool memcpy_field_possible(const Field *from) const { @@ -1825,7 +1861,7 @@ public: bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); my_decimal *val_decimal(my_decimal *); bool val_bool() { return val_real() != 0e0; } - uint32 max_display_length() { return field_length; } + uint32 max_display_length() const { return field_length; } uint size_of() const { return sizeof(*this); } Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item); }; @@ -1844,6 +1880,12 @@ public: const Type_handler *type_handler() const { return &type_handler_olddecimal; } enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } + Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + uint tmp= dec ? 2 : 1; // The sign and the decimal point + return Information_schema_numeric_attributes(field_length - tmp, dec); + } Copy_func *get_copy_func(const Field *from) const { return eq_def(from) ? get_identical_copy_func() : do_field_string; @@ -1928,7 +1970,12 @@ public: void sort_string(uchar *buff, uint length); bool zero_pack() const { return 0; } void sql_type(String &str) const; - uint32 max_display_length() { return field_length; } + uint32 max_display_length() const { return field_length; } + Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + return Information_schema_numeric_attributes(precision, dec); + } uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } uint pack_length_from_metadata(uint field_metadata); @@ -1958,6 +2005,35 @@ public: bool val_bool() { return val_int() != 0; } int store_time_dec(const MYSQL_TIME *ltime, uint dec); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); + virtual const Type_limits_int *type_limits_int() const= 0; + uint32 max_display_length() const + { + return type_limits_int()->char_length(); + } + Type_std_attributes type_std_attributes() const + { + /* + For integer data types, the user-specified length does not constrain the + supported range, so e.g. a column of the INT(1) data type supports the + full integer range anyway. + Choose the maximum from the user-specified length and the maximum + possible length determined by the data type capacity: + INT(1) -> 11 + INT(10) -> 11 + INT(40) -> 40 + */ + uint32 length1= max_display_length(); + uint32 length2= field_length; + return Type_std_attributes(MY_MAX(length1, length2), decimals(), + MY_TEST(flags & UNSIGNED_FLAG), + dtcollation()); + } + Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + uint32 prec= type_limits_int()->precision(); + return Information_schema_numeric_attributes(prec, 0); + } }; @@ -1986,7 +2062,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 1; } void sql_type(String &str) const; - uint32 max_display_length() { return 4; } + const Type_limits_int *type_limits_int() const + { + return type_handler_tiny.type_limits_int_by_unsigned_flag(is_unsigned()); + } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { @@ -2036,8 +2115,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 2; } void sql_type(String &str) const; - uint32 max_display_length() { return 6; } - + const Type_limits_int *type_limits_int() const + { + return type_handler_short.type_limits_int_by_unsigned_flag(is_unsigned()); + } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return pack_int16(to, from); } @@ -2071,8 +2152,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; - uint32 max_display_length() { return 8; } - + const Type_limits_int *type_limits_int() const + { + return type_handler_int24.type_limits_int_by_unsigned_flag(is_unsigned()); + } virtual uchar *pack(uchar* to, const uchar *from, uint max_length) { return Field::pack(to, from, max_length); @@ -2111,7 +2194,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; - uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; } + const Type_limits_int *type_limits_int() const + { + return type_handler_long.type_limits_int_by_unsigned_flag(is_unsigned()); + } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused))) { @@ -2161,7 +2247,10 @@ public: void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; - uint32 max_display_length() { return 20; } + const Type_limits_int *type_limits_int() const + { + return type_handler_longlong.type_limits_int_by_unsigned_flag(is_unsigned()); + } virtual uchar *pack(uchar* to, const uchar *from, uint max_length __attribute__((unused))) { @@ -2191,8 +2280,7 @@ public: unsigned_arg), cached(0) {} - enum_field_types real_type() const { return MYSQL_TYPE_LONGLONG; } - enum_field_types type() const { return MYSQL_TYPE_LONGLONG;} + const Type_handler *type_handler() const { return &type_handler_vers_trx_id; } uint size_of() const { return sizeof(*this); } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate, ulonglong trx_id); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) @@ -2219,10 +2307,6 @@ public: } /* cmp_type() cannot be TIME_RESULT, because we want to compare this field against integers. But in all other cases we treat it as TIME_RESULT! */ - bool vers_trx_id() const - { - return true; - } }; @@ -2337,6 +2421,11 @@ public: unireg_check_arg, field_name_arg, collation) {} const Type_handler *type_handler() const { return &type_handler_null; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(); + } Copy_func *get_copy_func(const Field *from) const { return do_field_string; @@ -2358,7 +2447,7 @@ public: uint32 pack_length() const { return 0; } void sql_type(String &str) const; uint size_of() const { return sizeof(*this); } - uint32 max_display_length() { return 4; } + uint32 max_display_length() const { return 4; } void move_field_offset(my_ptrdiff_t ptr_diff) {} bool can_optimize_keypart_ref(const Item_bool_func *cond, const Item *item) const @@ -2397,7 +2486,7 @@ public: return to->store_time_dec(<ime, decimals()); } bool memcpy_field_possible(const Field *from) const; - uint32 max_display_length() { return field_length; } + uint32 max_display_length() const { return field_length; } bool str_needs_quotes() { return TRUE; } enum Derivation derivation(void) const { return DERIVATION_NUMERIC; } uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; } @@ -2697,7 +2786,12 @@ public: String *val_str(String*,String *); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); bool send_binary(Protocol *protocol); - uint32 max_display_length() { return field_length; } + Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + return Information_schema_numeric_attributes(); + } + uint32 max_display_length() const { return field_length; } void sql_type(String &str) const; }; @@ -3352,7 +3446,11 @@ private: Field_varstring::sql_type(str); str.append(STRING_WITH_LEN(" /*!100301 COMPRESSED*/")); } - uint32 max_display_length() { return field_length - 1; } + uint32 max_display_length() const { return field_length - 1; } + uint32 char_length() const + { + return (field_length - 1) / field_charset->mbmaxlen; + } int cmp_max(const uchar *a_ptr, const uchar *b_ptr, uint max_len); /* @@ -3472,6 +3570,19 @@ public: } enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } + Type_std_attributes type_std_attributes() const + { + return Type_std_attributes(Field_blob::max_display_length(), decimals(), + MY_TEST(flags & UNSIGNED_FLAG), + dtcollation()); + } + Information_schema_character_attributes + information_schema_character_attributes() const + { + uint32 octets= Field_blob::octet_length(); + uint32 chars= octets / field_charset->mbminlen; + return Information_schema_character_attributes(octets, chars); + } Copy_func *get_copy_func(const Field *from) const { /* @@ -3548,7 +3659,7 @@ public: DBUG_ASSERT(number < UINT_MAX32); store_length(ptr, packlength, (uint32)number); } - inline uint32 get_length(uint row_offset= 0) const + inline uint32 get_length(my_ptrdiff_t row_offset= 0) const { return get_length(ptr+row_offset, this->packlength); } uint32 get_length(const uchar *ptr, uint packlength) const; uint32 get_length(const uchar *ptr_arg) const @@ -3632,8 +3743,9 @@ public: uint size_of() const { return sizeof(*this); } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } - uint32 max_display_length(); + uint32 max_display_length() const; uint32 char_length() const; + uint32 octet_length() const; uint is_equal(Create_field *new_field); private: int save_field_metadata(uchar *first_byte); @@ -3716,6 +3828,11 @@ public: { return MYSQL_TYPE_GEOMETRY; } + Information_schema_character_attributes + information_schema_character_attributes() const + { + return Information_schema_character_attributes(); + } bool can_optimize_range(const Item_bool_func *cond, const Item *item, bool is_eq_func) const; @@ -3912,7 +4029,12 @@ public: enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; } uint32 key_length() const { return (uint32) (field_length + 7) / 8; } uint32 max_data_length() const { return (field_length + 7) / 8; } - uint32 max_display_length() { return field_length; } + uint32 max_display_length() const { return field_length; } + Information_schema_numeric_attributes + information_schema_numeric_attributes() const + { + return Information_schema_numeric_attributes(field_length); + } uint size_of() const { return sizeof(*this); } int reset(void) { bzero(ptr, bytes_in_rec); diff --git a/sql/field_comp.cc b/sql/field_comp.cc index 9a7b3a7c7e0..eb4ae42aa4d 100644 --- a/sql/field_comp.cc +++ b/sql/field_comp.cc @@ -21,11 +21,30 @@ #include <zlib.h> +/** + Compresses string using zlib + + @param[out] to destination buffer for compressed data + @param[in] from data to compress + @param[in] length from length + + Requirement is such that string stored at `to' must not exceed `from' length. + Otherwise 0 is returned and caller stores string uncompressed. + + `to' must be large enough to hold `length' bytes. + + length == 1 is an edge case that may break stream.avail_out calculation: at + least 2 bytes required to store metadata. +*/ + static uint compress_zlib(THD *thd, char *to, const char *from, uint length) { uint level= thd->variables.column_compression_zlib_level; - if (level > 0) + /* Caller takes care of empty strings. */ + DBUG_ASSERT(length); + + if (level > 0 && length > 1) { z_stream stream; int wbits= thd->variables.column_compression_zlib_wrap ? MAX_WBITS : @@ -40,6 +59,7 @@ static uint compress_zlib(THD *thd, char *to, const char *from, uint length) stream.avail_in= length; stream.next_in= (Bytef*) from; + DBUG_ASSERT(length >= static_cast<uint>(original_pack_length) + 1); stream.avail_out= length - original_pack_length - 1; stream.next_out= (Bytef*) to + original_pack_length + 1; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index d648c90e114..64d0bc6c452 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -487,10 +487,11 @@ static void do_cut_string_complex(Copy_field *copy) memcpy(copy->to_ptr, copy->from_ptr, copy_length); /* Check if we lost any important characters */ - if (prefix.well_formed_error_pos() || - cs->cset->scan(cs, (char*) copy->from_ptr + copy_length, - (char*) from_end, - MY_SEQ_SPACES) < (copy->from_length - copy_length)) + if (unlikely(prefix.well_formed_error_pos() || + cs->cset->scan(cs, (char*) copy->from_ptr + copy_length, + (char*) from_end, + MY_SEQ_SPACES) < + (copy->from_length - copy_length))) { copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); diff --git a/sql/filesort.cc b/sql/filesort.cc index 00dfa08bba8..b2c88cda7b3 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -376,7 +376,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, } } tracker->report_merge_passes_at_end(thd->query_plan_fsort_passes); - if (error) + if (unlikely(error)) { int kill_errno= thd->killed_errno(); DBUG_ASSERT(thd->is_error() || kill_errno || thd->killed == ABORT_QUERY); @@ -414,7 +414,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, (longlong) sort->found_rows)); MYSQL_FILESORT_DONE(error, num_rows); - if (error) + if (unlikely(error)) { delete sort; sort= 0; @@ -705,10 +705,9 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, Bounded_queue<uchar, uchar> *pq, ha_rows *found_rows) { - int error,flag,quick_select; - uint idx,indexpos,ref_length; - uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH]; - my_off_t record; + int error, quick_select; + uint idx, indexpos; + uchar *ref_pos, *next_pos, ref_buff[MAX_REFLENGTH]; TABLE *sort_form; handler *file; MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set; @@ -723,14 +722,10 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, error=quick_select=0; sort_form=param->sort_form; file=sort_form->file; - ref_length=param->ref_length; ref_pos= ref_buff; quick_select=select && select->quick; - record=0; *found_rows= 0; - flag= ((file->ha_table_flags() & HA_REC_NOT_IN_SEQ) || quick_select); - if (flag) - ref_pos= &file->ref[0]; + ref_pos= &file->ref[0]; next_pos=ref_pos; DBUG_EXECUTE_IF("show_explain_in_find_all_keys", @@ -742,7 +737,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, next_pos=(uchar*) 0; /* Find records in sequence */ DBUG_EXECUTE_IF("bug14365043_1", DBUG_SET("+d,ha_rnd_init_fail");); - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) DBUG_RETURN(HA_POS_ERROR); file->extra_opt(HA_EXTRA_CACHE, thd->variables.read_buff_size); } @@ -778,29 +773,15 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, for (;;) { if (quick_select) - { - if ((error= select->quick->get_next())) - break; - file->position(sort_form->record[0]); - DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE);); - } + error= select->quick->get_next(); else /* Not quick-select */ - { - { - error= file->ha_rnd_next(sort_form->record[0]); - if (!flag) - { - my_store_ptr(ref_pos,ref_length,record); // Position to row - record+= sort_form->s->db_record_offset; - } - else if (!error) - file->position(sort_form->record[0]); - } - if (error && error != HA_ERR_RECORD_DELETED) - break; - } + error= file->ha_rnd_next(sort_form->record[0]); + if (unlikely(error)) + break; + file->position(sort_form->record[0]); + DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE);); - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { DBUG_PRINT("info",("Sort killed by user")); if (!quick_select) @@ -812,7 +793,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, } bool write_record= false; - if (error == 0) + if (likely(error == 0)) { param->examined_rows++; if (select && select->cond) @@ -865,7 +846,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, } /* It does not make sense to read more keys in case of a fatal error */ - if (thd->is_error()) + if (unlikely(thd->is_error())) break; /* @@ -885,11 +866,11 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, /* Signal we should use orignal column read and write maps */ sort_form->column_bitmaps_set(save_read_set, save_write_set, save_vcol_set); - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(HA_POS_ERROR); DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos)); - if (error != HA_ERR_END_OF_FILE) + if (unlikely(error != HA_ERR_END_OF_FILE)) { file->print_error(error,MYF(ME_ERROR | ME_WAITTANG)); // purecov: inspected DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */ @@ -1166,12 +1147,11 @@ Type_handler_real_result::make_sort_key(uchar *to, Item *item, /** Make a sort-key from record. */ -static void make_sortkey(register Sort_param *param, - register uchar *to, uchar *ref_pos) +static void make_sortkey(Sort_param *param, uchar *to, uchar *ref_pos) { - reg3 Field *field; - reg1 SORT_FIELD *sort_field; - reg5 uint length; + Field *field; + SORT_FIELD *sort_field; + uint length; for (sort_field=param->local_sortorder ; sort_field != param->end ; @@ -1261,7 +1241,7 @@ static void make_sortkey(register Sort_param *param, static void register_used_fields(Sort_param *param) { - reg1 SORT_FIELD *sort_field; + SORT_FIELD *sort_field; TABLE *table=param->sort_form; for (sort_field= param->local_sortorder ; @@ -1460,7 +1440,7 @@ static bool check_if_pq_applicable(Sort_param *param, int merge_many_buff(Sort_param *param, uchar *sort_buffer, BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file) { - register uint i; + uint i; IO_CACHE t_file2,*from_file,*to_file,*temp; BUFFPEK *lastbuff; DBUG_ENTER("merge_many_buff"); @@ -1508,27 +1488,28 @@ cleanup: /** Read data to buffer. - @retval - (uint)-1 if something goes wrong + @retval Number of bytes read + (ulong)-1 if something goes wrong */ -uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, - uint rec_length) +ulong read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, + uint rec_length) { - register uint count; - uint length; + ulong count; + ulong length= 0; - if ((count=(uint) MY_MIN((ha_rows) buffpek->max_keys,buffpek->count))) + if ((count= (ulong) MY_MIN((ha_rows) buffpek->max_keys,buffpek->count))) { - if (my_b_pread(fromfile, (uchar*) buffpek->base, - (length= rec_length*count), buffpek->file_pos)) - return ((uint) -1); + length= rec_length*count; + if (unlikely(my_b_pread(fromfile, (uchar*) buffpek->base, length, + buffpek->file_pos))) + return ((ulong) -1); buffpek->key=buffpek->base; buffpek->file_pos+= length; /* New filepos */ buffpek->count-= count; buffpek->mem_count= count; } - return (count*rec_length); + return (length); } /* read_to_buffer */ @@ -1582,18 +1563,18 @@ void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length) @retval 0 OK @retval - other error + 1 ERROR */ -int merge_buffers(Sort_param *param, IO_CACHE *from_file, - IO_CACHE *to_file, uchar *sort_buffer, - BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb, - int flag) +bool merge_buffers(Sort_param *param, IO_CACHE *from_file, + IO_CACHE *to_file, uchar *sort_buffer, + BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb, + int flag) { - int error; + bool error= 0; uint rec_length,res_length,offset; size_t sort_length; - ulong maxcount; + ulong maxcount, bytes_read; ha_rows max_rows,org_max_rows; my_off_t to_start_filepos; uchar *strpos; @@ -1611,7 +1592,6 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, thd->inc_status_sort_merge_passes(); thd->query_plan_fsort_passes++; - error=0; rec_length= param->rec_length; res_length= param->res_length; sort_length= param->sort_length; @@ -1639,18 +1619,18 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, cmp= get_ptr_compare(sort_length); first_cmp_arg= (void*) &sort_length; } - if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0, - (queue_compare) cmp, first_cmp_arg, 0, 0)) + if (unlikely(init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0, + (queue_compare) cmp, first_cmp_arg, 0, 0))) DBUG_RETURN(1); /* purecov: inspected */ for (buffpek= Fb ; buffpek <= Tb ; buffpek++) { buffpek->base= strpos; buffpek->max_keys= maxcount; - strpos+= - (uint) (error= (int) read_to_buffer(from_file, buffpek, rec_length)); - - if (error == -1) + bytes_read= read_to_buffer(from_file, buffpek, rec_length); + if (unlikely(bytes_read == (ulong) -1)) goto err; /* purecov: inspected */ + + strpos+= bytes_read; buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected queue_insert(&queue, (uchar*) buffpek); } @@ -1670,13 +1650,13 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, buffpek->key+= rec_length; if (! --buffpek->mem_count) { - if (!(error= (int) read_to_buffer(from_file, buffpek, - rec_length))) + if (unlikely(!(bytes_read= read_to_buffer(from_file, buffpek, + rec_length)))) { (void) queue_remove_top(&queue); reuse_freed_buff(&queue, buffpek, rec_length); } - else if (error == -1) + else if (unlikely(bytes_read == (ulong) -1)) goto err; /* purecov: inspected */ } queue_replace_top(&queue); // Top element has been used @@ -1686,10 +1666,9 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, while (queue.elements > 1) { - if (killable && thd->check_killed()) - { - error= 1; goto err; /* purecov: inspected */ - } + if (killable && unlikely(thd->check_killed())) + goto err; /* purecov: inspected */ + for (;;) { buffpek= (BUFFPEK*) queue_top(&queue); @@ -1726,9 +1705,7 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, if (!check_dupl_count || dupl_count >= min_dupl_count) { if (my_b_write(to_file, src+wr_offset, wr_len)) - { - error=1; goto err; /* purecov: inspected */ - } + goto err; /* purecov: inspected */ } if (cmp) { @@ -1739,7 +1716,7 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, } if (!--max_rows) { - error= 0; /* purecov: inspected */ + /* Nothing more to do */ goto end; /* purecov: inspected */ } @@ -1747,14 +1724,14 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, buffpek->key+= rec_length; if (! --buffpek->mem_count) { - if (!(error= (int) read_to_buffer(from_file, buffpek, - rec_length))) + if (unlikely(!(bytes_read= read_to_buffer(from_file, buffpek, + rec_length)))) { (void) queue_remove_top(&queue); reuse_freed_buff(&queue, buffpek, rec_length); break; /* One buffer have been removed */ } - else if (error == -1) + else if (unlikely(bytes_read == (ulong) -1)) goto err; /* purecov: inspected */ } queue_replace_top(&queue); /* Top element has been replaced */ @@ -1790,14 +1767,9 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, { src= unique_buff; if (my_b_write(to_file, src+wr_offset, wr_len)) - { - error=1; goto err; /* purecov: inspected */ - } + goto err; /* purecov: inspected */ if (!--max_rows) - { - error= 0; goto end; - } } } @@ -1813,13 +1785,11 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, { if (my_b_write(to_file, (uchar*) buffpek->key, (size_t)(rec_length*buffpek->mem_count))) - { - error= 1; goto err; /* purecov: inspected */ - } + goto err; /* purecov: inspected */ } else { - register uchar *end; + uchar *end; src= buffpek->key+offset; for (end= src+buffpek->mem_count*rec_length ; src != end ; @@ -1832,21 +1802,26 @@ int merge_buffers(Sort_param *param, IO_CACHE *from_file, continue; } if (my_b_write(to_file, src, wr_len)) - { - error=1; goto err; - } + goto err; } } } - while ((error=(int) read_to_buffer(from_file, buffpek, rec_length)) - != -1 && error != 0); + while (likely(!(error= + (bytes_read= read_to_buffer(from_file, buffpek, + rec_length)) == (ulong) -1)) && + bytes_read != 0); end: lastbuff->count= MY_MIN(org_max_rows-max_rows, param->max_rows); lastbuff->file_pos= to_start_filepos; -err: +cleanup: delete_queue(&queue); DBUG_RETURN(error); + +err: + error= 1; + goto cleanup; + } /* merge_buffers */ diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index b2bc1aee091..9241dd79113 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -78,6 +78,7 @@ So, we can read full search-structure as 32-bit word */ #define NO_YACC_SYMBOLS +#undef CHECK_UNLIKELY #include "mariadb.h" #include "mysql_version.h" #include "lex.h" @@ -140,7 +141,8 @@ void insert_into_hash(hash_lex_struct *root, const char *name, if (root->first_char>(*name)) { size_t new_size= root->last_char-(*name)+1; - if (new_size<real_size) printf("error!!!!\n"); + if (unlikely(new_size<real_size)) + printf("error!!!!\n"); tails= root->char_tails; tails= (hash_lex_struct*)realloc((char*)tails, sizeof(hash_lex_struct)*new_size); @@ -155,7 +157,8 @@ void insert_into_hash(hash_lex_struct *root, const char *name, if (root->last_char<(*name)) { size_t new_size= (*name)-root->first_char+1; - if (new_size<real_size) printf("error!!!!\n"); + if (unlikely(new_size<real_size)) + printf("error!!!!\n"); tails= root->char_tails; tails= (hash_lex_struct*)realloc((char*)tails, sizeof(hash_lex_struct)*new_size); @@ -401,8 +404,8 @@ int main(int argc,char **argv) static SYMBOL *get_hash_symbol(const char *s,\n\ unsigned int len,bool function)\n\ {\n\ - register uchar *hash_map;\n\ - register const char *cur_str= s;\n\ + uchar *hash_map;\n\ + const char *cur_str= s;\n\ \n\ if (len == 0) {\n\ DBUG_PRINT(\"warning\", (\"get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake.\"));\ @@ -414,25 +417,25 @@ static SYMBOL *get_hash_symbol(const char *s,\n\ if (function){\n\ if (len>sql_functions_max_len) return 0;\n\ hash_map= sql_functions_map;\n\ - register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\ + uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\ \n\ for (;;){\n\ - register uchar first_char= (uchar)cur_struct;\n\ + uchar first_char= (uchar)cur_struct;\n\ \n\ if (first_char == 0)\n\ {\n\ - register int16 ires= (int16)(cur_struct>>16);\n\ + int16 ires= (int16)(cur_struct>>16);\n\ if (ires==array_elements(symbols)) return 0;\n\ - register SYMBOL *res;\n\ + SYMBOL *res;\n\ if (ires>=0) \n\ res= symbols+ires;\n\ else\n\ res= sql_functions-ires-1;\n\ - register uint count= (uint) (cur_str - s);\n\ + uint count= (uint) (cur_str - s);\n\ return lex_casecmp(cur_str,res->name+count,len-count) ? 0 : res;\n\ }\n\ \n\ - register uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];\n\ + uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];\n\ if (cur_char<first_char) return 0;\n\ cur_struct>>=8;\n\ if (cur_char>(uchar)cur_struct) return 0;\n\ @@ -448,20 +451,20 @@ static SYMBOL *get_hash_symbol(const char *s,\n\ }else{\n\ if (len>symbols_max_len) return 0;\n\ hash_map= symbols_map;\n\ - register uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\ + uint32 cur_struct= uint4korr(hash_map+((len-1)*4));\n\ \n\ for (;;){\n\ - register uchar first_char= (uchar)cur_struct;\n\ + uchar first_char= (uchar)cur_struct;\n\ \n\ - if (first_char==0){\n\ - register int16 ires= (int16)(cur_struct>>16);\n\ + if (first_char==0) {\n\ + int16 ires= (int16)(cur_struct>>16);\n\ if (ires==array_elements(symbols)) return 0;\n\ - register SYMBOL *res= symbols+ires;\n\ - register uint count= (uint) (cur_str - s);\n\ + SYMBOL *res= symbols+ires;\n\ + uint count= (uint) (cur_str - s);\n\ return lex_casecmp(cur_str,res->name+count,len-count)!=0 ? 0 : res;\n\ }\n\ \n\ - register uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];\n\ + uchar cur_char= (uchar)to_upper_lex[(uchar)*cur_str];\n\ if (cur_char<first_char) return 0;\n\ cur_struct>>=8;\n\ if (cur_char>(uchar)cur_struct) return 0;\n\ diff --git a/sql/group_by_handler.cc b/sql/group_by_handler.cc index e75800d8986..f18758a2d94 100644 --- a/sql/group_by_handler.cc +++ b/sql/group_by_handler.cc @@ -63,9 +63,8 @@ int Pushdown_query::execute(JOIN *join) while (!(err= handler->next_row())) { - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); handler->end_scan(); DBUG_RETURN(-1); } @@ -78,7 +77,7 @@ int Pushdown_query::execute(JOIN *join) if ((err= table->file->ha_write_tmp_row(table->record[0]))) { bool is_duplicate; - if (!table->file->is_fatal_error(err, HA_CHECK_DUP)) + if (likely(!table->file->is_fatal_error(err, HA_CHECK_DUP))) continue; // Distinct elimination if (create_internal_tmp_table_from_heap(thd, table, @@ -98,7 +97,7 @@ int Pushdown_query::execute(JOIN *join) { int error; /* result < 0 if row was not accepted and should not be counted */ - if ((error= join->result->send_data(*join->fields))) + if (unlikely((error= join->result->send_data(*join->fields)))) { handler->end_scan(); DBUG_RETURN(error < 0 ? 0 : -1); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 30d4b338147..0775d67a592 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -738,12 +738,16 @@ int ha_partition::create(const char *name, TABLE *table_arg, for (j= 0; j < m_part_info->num_subparts; j++) { part_elem= sub_it++; - if ((error= create_partition_name(name_buff, sizeof(name_buff), path, - name_buffer_ptr, NORMAL_PART_NAME, FALSE))) + if (unlikely((error= create_partition_name(name_buff, + sizeof(name_buff), path, + name_buffer_ptr, + NORMAL_PART_NAME, FALSE)))) goto create_error; - if ((error= set_up_table_before_create(table_arg, name_buff, - create_info, part_elem)) || - ((error= (*file)->ha_create(name_buff, table_arg, create_info)))) + if (unlikely((error= set_up_table_before_create(table_arg, name_buff, + create_info, + part_elem)) || + ((error= (*file)->ha_create(name_buff, table_arg, + create_info))))) goto create_error; name_buffer_ptr= strend(name_buffer_ptr) + 1; @@ -752,12 +756,15 @@ int ha_partition::create(const char *name, TABLE *table_arg, } else { - if ((error= create_partition_name(name_buff, sizeof(name_buff), path, - name_buffer_ptr, NORMAL_PART_NAME, FALSE))) + if (unlikely((error= create_partition_name(name_buff, sizeof(name_buff), + path, name_buffer_ptr, + NORMAL_PART_NAME, FALSE)))) goto create_error; - if ((error= set_up_table_before_create(table_arg, name_buff, - create_info, part_elem)) || - ((error= (*file)->ha_create(name_buff, table_arg, create_info)))) + if (unlikely((error= set_up_table_before_create(table_arg, name_buff, + create_info, + part_elem)) || + ((error= (*file)->ha_create(name_buff, table_arg, + create_info))))) goto create_error; name_buffer_ptr= strend(name_buffer_ptr) + 1; @@ -832,16 +839,19 @@ int ha_partition::drop_partitions(const char *path) { partition_element *sub_elem= sub_it++; part= i * num_subparts + j; - if ((ret_error= create_subpartition_name(part_name_buff, - sizeof(part_name_buff), path, - part_elem->partition_name, - sub_elem->partition_name, name_variant))) + if (unlikely((ret_error= + create_subpartition_name(part_name_buff, + sizeof(part_name_buff), path, + part_elem->partition_name, + sub_elem->partition_name, + name_variant)))) error= ret_error; file= m_file[part]; DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); - if ((ret_error= file->ha_delete_table(part_name_buff))) + if (unlikely((ret_error= file->ha_delete_table(part_name_buff)))) error= ret_error; - if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) + if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> + entry_pos))) error= 1; } while (++j < num_subparts); } @@ -855,9 +865,10 @@ int ha_partition::drop_partitions(const char *path) { file= m_file[i]; DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); - if ((ret_error= file->ha_delete_table(part_name_buff))) + if (unlikely((ret_error= file->ha_delete_table(part_name_buff)))) error= ret_error; - if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) + if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> + entry_pos))) error= 1; } } @@ -938,15 +949,18 @@ int ha_partition::rename_partitions(const char *path) { sub_elem= sub_it++; file= m_reorged_file[part_count++]; - if ((ret_error= create_subpartition_name(norm_name_buff, - sizeof(norm_name_buff), path, - part_elem->partition_name, - sub_elem->partition_name, NORMAL_PART_NAME))) + if (unlikely((ret_error= + create_subpartition_name(norm_name_buff, + sizeof(norm_name_buff), path, + part_elem->partition_name, + sub_elem->partition_name, + NORMAL_PART_NAME)))) error= ret_error; DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if ((ret_error= file->ha_delete_table(norm_name_buff))) + if (unlikely((ret_error= file->ha_delete_table(norm_name_buff)))) error= ret_error; - else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) + else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> + entry_pos))) error= 1; else sub_elem->log_entry= NULL; /* Indicate success */ @@ -955,16 +969,19 @@ int ha_partition::rename_partitions(const char *path) else { file= m_reorged_file[part_count++]; - if ((ret_error= create_partition_name(norm_name_buff, - sizeof(norm_name_buff), path, - part_elem->partition_name, NORMAL_PART_NAME, TRUE))) + if (unlikely((ret_error= + create_partition_name(norm_name_buff, + sizeof(norm_name_buff), path, + part_elem->partition_name, + NORMAL_PART_NAME, TRUE)))) error= ret_error; else { DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); - if ((ret_error= file->ha_delete_table(norm_name_buff))) + if (unlikely((ret_error= file->ha_delete_table(norm_name_buff)))) error= ret_error; - else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) + else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> + entry_pos))) error= 1; else part_elem->log_entry= NULL; /* Indicate success */ @@ -1011,33 +1028,39 @@ int ha_partition::rename_partitions(const char *path) { sub_elem= sub_it++; part= i * num_subparts + j; - if ((ret_error= create_subpartition_name(norm_name_buff, - sizeof(norm_name_buff), path, - part_elem->partition_name, - sub_elem->partition_name, NORMAL_PART_NAME))) + if (unlikely((ret_error= + create_subpartition_name(norm_name_buff, + sizeof(norm_name_buff), path, + part_elem->partition_name, + sub_elem->partition_name, + NORMAL_PART_NAME)))) error= ret_error; if (part_elem->part_state == PART_IS_CHANGED) { file= m_reorged_file[part_count++]; DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); - if ((ret_error= file->ha_delete_table(norm_name_buff))) + if (unlikely((ret_error= file->ha_delete_table(norm_name_buff)))) error= ret_error; - else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) + else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> + entry_pos))) error= 1; (void) sync_ddl_log(); } file= m_new_file[part]; - if ((ret_error= create_subpartition_name(part_name_buff, - sizeof(part_name_buff), path, - part_elem->partition_name, - sub_elem->partition_name, TEMP_PART_NAME))) + if (unlikely((ret_error= + create_subpartition_name(part_name_buff, + sizeof(part_name_buff), path, + part_elem->partition_name, + sub_elem->partition_name, + TEMP_PART_NAME)))) error= ret_error; DBUG_PRINT("info", ("Rename subpartition from %s to %s", part_name_buff, norm_name_buff)); - if ((ret_error= file->ha_rename_table(part_name_buff, - norm_name_buff))) + if (unlikely((ret_error= file->ha_rename_table(part_name_buff, + norm_name_buff)))) error= ret_error; - else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) + else if (unlikely(deactivate_ddl_log_entry(sub_elem->log_entry-> + entry_pos))) error= 1; else sub_elem->log_entry= NULL; @@ -1045,12 +1068,17 @@ int ha_partition::rename_partitions(const char *path) } else { - if ((ret_error= create_partition_name(norm_name_buff, - sizeof(norm_name_buff), path, - part_elem->partition_name, NORMAL_PART_NAME, TRUE)) || - (ret_error= create_partition_name(part_name_buff, - sizeof(part_name_buff), path, - part_elem->partition_name, TEMP_PART_NAME, TRUE))) + if (unlikely((ret_error= + create_partition_name(norm_name_buff, + sizeof(norm_name_buff), path, + part_elem->partition_name, + NORMAL_PART_NAME, TRUE)) || + (ret_error= create_partition_name(part_name_buff, + sizeof(part_name_buff), + path, + part_elem-> + partition_name, + TEMP_PART_NAME, TRUE)))) error= ret_error; else { @@ -1058,19 +1086,21 @@ int ha_partition::rename_partitions(const char *path) { file= m_reorged_file[part_count++]; DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); - if ((ret_error= file->ha_delete_table(norm_name_buff))) + if (unlikely((ret_error= file->ha_delete_table(norm_name_buff)))) error= ret_error; - else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) + else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> + entry_pos))) error= 1; (void) sync_ddl_log(); } file= m_new_file[i]; DBUG_PRINT("info", ("Rename partition from %s to %s", part_name_buff, norm_name_buff)); - if ((ret_error= file->ha_rename_table(part_name_buff, - norm_name_buff))) + if (unlikely((ret_error= file->ha_rename_table(part_name_buff, + norm_name_buff)))) error= ret_error; - else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) + else if (unlikely(deactivate_ddl_log_entry(part_elem->log_entry-> + entry_pos))) error= 1; else part_elem->log_entry= NULL; @@ -1394,7 +1424,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, part= i * num_subparts + j; DBUG_PRINT("info", ("Optimize subpartition %u (%s)", part, sub_elem->partition_name)); - if ((error= handle_opt_part(thd, check_opt, part, flag))) + if (unlikely((error= handle_opt_part(thd, check_opt, part, flag)))) { /* print a line which partition the error belongs to */ if (error != HA_ADMIN_NOT_IMPLEMENTED && @@ -1421,7 +1451,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, { DBUG_PRINT("info", ("Optimize partition %u (%s)", i, part_elem->partition_name)); - if ((error= handle_opt_part(thd, check_opt, i, flag))) + if (unlikely((error= handle_opt_part(thd, check_opt, i, flag)))) { /* print a line which partition the error belongs to */ if (error != HA_ADMIN_NOT_IMPLEMENTED && @@ -1554,7 +1584,8 @@ int ha_partition::prepare_new_partition(TABLE *tbl, truncate_partition_filename((char*) p_elem->data_file_name); truncate_partition_filename((char*) p_elem->index_file_name); - if ((error= set_up_table_before_create(tbl, part_name, create_info, p_elem))) + if (unlikely((error= set_up_table_before_create(tbl, part_name, create_info, + p_elem)))) goto error_create; if (!(file->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION)) @@ -1573,8 +1604,8 @@ int ha_partition::prepare_new_partition(TABLE *tbl, goto error_create; } DBUG_PRINT("info", ("partition %s created", part_name)); - if ((error= file->ha_open(tbl, part_name, m_mode, - m_open_test_lock | HA_OPEN_NO_PSI_CALL))) + if (unlikely((error= file->ha_open(tbl, part_name, m_mode, + m_open_test_lock | HA_OPEN_NO_PSI_CALL)))) goto error_open; DBUG_PRINT("info", ("partition %s opened", part_name)); @@ -1584,7 +1615,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl, assumes that external_lock() is last call that may fail here. Otherwise see description for cleanup_new_partition(). */ - if ((error= file->ha_external_lock(ha_thd(), F_WRLCK))) + if (unlikely((error= file->ha_external_lock(ha_thd(), F_WRLCK)))) goto error_external_lock; DBUG_PRINT("info", ("partition %s external locked", part_name)); @@ -1738,7 +1769,6 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, !(m_reorged_file= (handler**) thd->calloc(sizeof(handler*)* (m_reorged_parts + 1)))) { - mem_alloc_error(sizeof(handler*)*(m_reorged_parts+1)); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } @@ -1771,7 +1801,6 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, thd->calloc(sizeof(handler*)* (2*(num_remain_partitions + 1)))))) { - mem_alloc_error(sizeof(handler*)*2*(num_remain_partitions+1)); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } m_added_file= &new_file_array[num_remain_partitions + 1]; @@ -1863,7 +1892,6 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, thd->mem_root, part_elem->engine_type))) { - mem_alloc_error(sizeof(handler)); DBUG_RETURN(HA_ERR_OUT_OF_MEM); } if ((*new_file)->set_ha_share_ref(&p_share_refs->ha_shares[j])) @@ -1920,21 +1948,24 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, do { partition_element *sub_elem= sub_it++; - if ((error= create_subpartition_name(part_name_buff, - sizeof(part_name_buff), path, - part_elem->partition_name, sub_elem->partition_name, - name_variant))) + if (unlikely((error= + create_subpartition_name(part_name_buff, + sizeof(part_name_buff), path, + part_elem->partition_name, + sub_elem->partition_name, + name_variant)))) { cleanup_new_partition(part_count); DBUG_RETURN(error); } part= i * num_subparts + j; DBUG_PRINT("info", ("Add subpartition %s", part_name_buff)); - if ((error= prepare_new_partition(table, create_info, - new_file_array[part], - (const char *)part_name_buff, - sub_elem, - disable_non_uniq_indexes))) + if (unlikely((error= + prepare_new_partition(table, create_info, + new_file_array[part], + (const char *)part_name_buff, + sub_elem, + disable_non_uniq_indexes)))) { cleanup_new_partition(part_count); DBUG_RETURN(error); @@ -1945,20 +1976,23 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, } else { - if ((error= create_partition_name(part_name_buff, - sizeof(part_name_buff), path, part_elem->partition_name, - name_variant, TRUE))) + if (unlikely((error= + create_partition_name(part_name_buff, + sizeof(part_name_buff), path, + part_elem->partition_name, + name_variant, TRUE)))) { cleanup_new_partition(part_count); DBUG_RETURN(error); } DBUG_PRINT("info", ("Add partition %s", part_name_buff)); - if ((error= prepare_new_partition(table, create_info, - new_file_array[i], - (const char *)part_name_buff, - part_elem, - disable_non_uniq_indexes))) + if (unlikely((error= + prepare_new_partition(table, create_info, + new_file_array[i], + (const char *)part_name_buff, + part_elem, + disable_non_uniq_indexes)))) { cleanup_new_partition(part_count); DBUG_RETURN(error); @@ -1992,7 +2026,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, part_elem->part_state= PART_TO_BE_DROPPED; } m_new_file= new_file_array; - if ((error= copy_partitions(copied, deleted))) + if (unlikely((error= copy_partitions(copied, deleted)))) { /* Close and unlock the new temporary partitions. @@ -2049,14 +2083,12 @@ int ha_partition::copy_partitions(ulonglong * const copied, uint32 new_part; late_extra_cache(reorg_part); - if ((result= file->ha_rnd_init_with_error(1))) + if (unlikely((result= file->ha_rnd_init_with_error(1)))) goto init_error; while (TRUE) { if ((result= file->ha_rnd_next(m_rec0))) { - if (result == HA_ERR_RECORD_DELETED) - continue; //Probably MyISAM if (result != HA_ERR_END_OF_FILE) goto error; /* @@ -2331,7 +2363,7 @@ uint ha_partition::del_ren_table(const char *from, const char *to) Delete table, start by delete the .par file. If error, break, otherwise delete as much as possible. */ - if ((error= handler::delete_table(from))) + if (unlikely((error= handler::delete_table(from)))) DBUG_RETURN(error); } /* @@ -2347,17 +2379,19 @@ uint ha_partition::del_ren_table(const char *from, const char *to) i= 0; do { - if ((error= create_partition_name(from_buff, sizeof(from_buff), from_path, - name_buffer_ptr, NORMAL_PART_NAME, FALSE))) + if (unlikely((error= create_partition_name(from_buff, sizeof(from_buff), + from_path, name_buffer_ptr, + NORMAL_PART_NAME, FALSE)))) goto rename_error; if (to != NULL) { // Rename branch - if ((error= create_partition_name(to_buff, sizeof(to_buff), to_path, - name_buffer_ptr, NORMAL_PART_NAME, FALSE))) + if (unlikely((error= create_partition_name(to_buff, sizeof(to_buff), + to_path, name_buffer_ptr, + NORMAL_PART_NAME, FALSE)))) goto rename_error; error= (*file)->ha_rename_table(from_buff, to_buff); - if (error) + if (unlikely(error)) goto rename_error; } else // delete branch @@ -2365,13 +2399,13 @@ uint ha_partition::del_ren_table(const char *from, const char *to) error= (*file)->ha_delete_table(from_buff); } name_buffer_ptr= strend(name_buffer_ptr) + 1; - if (error) + if (unlikely(error)) save_error= error; i++; } while (*(++file)); if (to != NULL) { - if ((error= handler::rename_table(from, to))) + if (unlikely((error= handler::rename_table(from, to)))) { /* Try to revert everything, ignore errors */ (void) handler::rename_table(to, from); @@ -2883,10 +2917,8 @@ bool ha_partition::new_handlers_from_part_info(MEM_ROOT *mem_root) DBUG_ENTER("ha_partition::new_handlers_from_part_info"); if (!(m_file= (handler **) alloc_root(mem_root, alloc_len))) - { - mem_alloc_error(alloc_len); - goto error_end; - } + goto error; + m_file_tot_parts= m_tot_parts; bzero((char*) m_file, alloc_len); DBUG_ASSERT(m_part_info->num_parts > 0); @@ -2927,8 +2959,6 @@ bool ha_partition::new_handlers_from_part_info(MEM_ROOT *mem_root) } DBUG_RETURN(FALSE); error: - mem_alloc_error(sizeof(handler)); -error_end: DBUG_RETURN(TRUE); } @@ -3486,7 +3516,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) if (init_partition_bitmaps()) goto err_alloc; - if ((error= m_part_info->set_partition_bitmaps(m_partitions_to_open))) + if (unlikely((error= + m_part_info->set_partition_bitmaps(m_partitions_to_open)))) goto err_alloc; /* Allocate memory used with MMR */ @@ -3535,8 +3566,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) if (!bitmap_is_set(&m_is_clone_of->m_opened_partitions, i)) continue; - if ((error= create_partition_name(name_buff, sizeof(name_buff), name, - name_buffer_ptr, NORMAL_PART_NAME, FALSE))) + if (unlikely((error= create_partition_name(name_buff, sizeof(name_buff), + name, name_buffer_ptr, + NORMAL_PART_NAME, FALSE)))) goto err_handler; /* ::clone() will also set ha_share from the original. */ if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root))) @@ -3553,7 +3585,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) } else { - if ((error= open_read_partitions(name_buff, sizeof(name_buff)))) + if (unlikely((error= open_read_partitions(name_buff, sizeof(name_buff))))) goto err_handler; m_num_locks= m_file_sample->lock_count(); } @@ -3886,7 +3918,7 @@ int ha_partition::external_lock(THD *thd, int lock_type) i= bitmap_get_next_set(used_partitions, i)) { DBUG_PRINT("info", ("external_lock(thd, %d) part %u", lock_type, i)); - if ((error= m_file[i]->ha_external_lock(thd, lock_type))) + if (unlikely((error= m_file[i]->ha_external_lock(thd, lock_type)))) { if (lock_type != F_UNLCK) goto err_handler; @@ -4050,7 +4082,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type) i < m_tot_parts; i= bitmap_get_next_set(&m_part_info->lock_partitions, i)) { - if ((error= m_file[i]->start_stmt(thd, lock_type))) + if (unlikely((error= m_file[i]->start_stmt(thd, lock_type)))) break; /* Add partition to be called in reset(). */ bitmap_set_bit(&m_partitions_to_reset, i); @@ -4235,7 +4267,7 @@ int ha_partition::write_row(uchar * buf) it is highly likely that we will not be able to insert it into the correct partition. We must check and fail if neccessary. */ - if (error) + if (unlikely(error)) goto exit; /* @@ -4346,9 +4378,10 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id)); #endif - if ((error= get_part_for_buf(new_data, m_rec0, m_part_info, &new_part_id))) + if (unlikely((error= get_part_for_buf(new_data, m_rec0, m_part_info, + &new_part_id)))) goto exit; - if (!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id)) + if (unlikely(!bitmap_is_set(&(m_part_info->lock_partitions), new_part_id))) { error= HA_ERR_NOT_IN_LOCK_PARTITIONS; goto exit; @@ -4385,13 +4418,13 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) error= m_file[new_part_id]->ha_write_row((uchar*) new_data); reenable_binlog(thd); table->next_number_field= saved_next_number_field; - if (error) + if (unlikely(error)) goto exit; tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */ error= m_file[old_part_id]->ha_delete_row(old_data); reenable_binlog(thd); - if (error) + if (unlikely(error)) goto exit; } @@ -4481,7 +4514,7 @@ int ha_partition::delete_row(const uchar *buf) or last historical partition, but DELETE HISTORY can delete from any historical partition. So, skip the check in this case. */ - if (!thd->lex->vers_conditions) // if not DELETE HISTORY + if (!thd->lex->vers_conditions.is_set()) // if not DELETE HISTORY { uint32 part_id; error= get_part_for_buf(buf, m_rec0, m_part_info, &part_id); @@ -4535,7 +4568,7 @@ int ha_partition::delete_all_rows() i= bitmap_get_next_set(&m_part_info->read_partitions, i)) { /* Can be pruned, like DELETE FROM t PARTITION (pX) */ - if ((error= m_file[i]->ha_delete_all_rows())) + if (unlikely((error= m_file[i]->ha_delete_all_rows()))) DBUG_RETURN(error); } DBUG_RETURN(0); @@ -4567,7 +4600,7 @@ int ha_partition::truncate() file= m_file; do { - if ((error= (*file)->ha_truncate())) + if (unlikely((error= (*file)->ha_truncate()))) DBUG_RETURN(error); } while (*(++file)); DBUG_RETURN(0); @@ -4625,7 +4658,7 @@ int ha_partition::truncate_partition(Alter_info *alter_info, bool *binlog_stmt) part= i * num_subparts + j; DBUG_PRINT("info", ("truncate subpartition %u (%s)", part, sub_elem->partition_name)); - if ((error= m_file[part]->ha_truncate())) + if (unlikely((error= m_file[part]->ha_truncate()))) break; sub_elem->part_state= PART_NORMAL; } while (++j < num_subparts); @@ -4901,7 +4934,7 @@ int ha_partition::rnd_init(bool scan) i < m_tot_parts; i= bitmap_get_next_set(&m_part_info->read_partitions, i)) { - if ((error= m_file[i]->ha_rnd_init(scan))) + if (unlikely((error= m_file[i]->ha_rnd_init(scan)))) goto err; } @@ -5035,9 +5068,6 @@ int ha_partition::rnd_next(uchar *buf) /* if we get here, then the current partition ha_rnd_next returned failure */ - if (result == HA_ERR_RECORD_DELETED) - continue; // Probably MyISAM - if (result != HA_ERR_END_OF_FILE) goto end_dont_reset_start_part; // Return error @@ -5365,7 +5395,7 @@ int ha_partition::index_init(uint inx, bool sorted) i < m_tot_parts; i= bitmap_get_next_set(&m_part_info->read_partitions, i)) { - if ((error= m_file[i]->ha_index_init(inx, sorted))) + if (unlikely((error= m_file[i]->ha_index_init(inx, sorted)))) goto err; DBUG_EXECUTE_IF("ha_partition_fail_index_init", { @@ -5375,7 +5405,7 @@ int ha_partition::index_init(uint inx, bool sorted) }); } err: - if (error) + if (unlikely(error)) { /* End the previously initialized indexes. */ uint j; @@ -5570,7 +5600,7 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key) m_start_key.keypart_map, m_start_key.flag, key_len)); DBUG_ASSERT(key_len); } - if ((error= partition_scan_set_up(buf, have_start_key))) + if (unlikely((error= partition_scan_set_up(buf, have_start_key)))) { DBUG_RETURN(error); } @@ -5596,7 +5626,7 @@ int ha_partition::common_index_read(uchar *buf, bool have_start_key) */ DBUG_PRINT("info", ("doing unordered scan")); error= handle_pre_scan(FALSE, FALSE); - if (!error) + if (likely(!error)) error= handle_unordered_scan_next_partition(buf); } else @@ -5686,12 +5716,12 @@ int ha_partition::common_first_last(uchar *buf) { int error; - if ((error= partition_scan_set_up(buf, FALSE))) + if (unlikely((error= partition_scan_set_up(buf, FALSE)))) return error; if (!m_ordered_scan_ongoing && m_index_scan_type != partition_index_last) { - if ((error= handle_pre_scan(FALSE, check_parallel_search()))) + if (unlikely((error= handle_pre_scan(FALSE, check_parallel_search())))) return error; return handle_unordered_scan_next_partition(buf); } @@ -5739,8 +5769,8 @@ int ha_partition::index_read_idx_map(uchar *buf, uint index, { error= m_file[part]->ha_index_read_idx_map(buf, index, key, keypart_map, find_flag); - if (error != HA_ERR_KEY_NOT_FOUND && - error != HA_ERR_END_OF_FILE) + if (likely(error != HA_ERR_KEY_NOT_FOUND && + error != HA_ERR_END_OF_FILE)) break; } if (part <= m_part_spec.end_part) @@ -6236,9 +6266,9 @@ ha_rows ha_partition::multi_range_read_info_const(uint keyno, save_part_spec= m_part_spec; seq_it= seq->init(seq_init_param, n_ranges, *mrr_mode); - if ((error= multi_range_key_create_key(seq, seq_it))) + if (unlikely((error= multi_range_key_create_key(seq, seq_it)))) { - if (error == HA_ERR_END_OF_FILE) // No keys in range + if (likely(error == HA_ERR_END_OF_FILE)) // No keys in range { rows= 0; goto calc_cost; @@ -6355,7 +6385,7 @@ int ha_partition::multi_range_read_init(RANGE_SEQ_IF *seq, m_seq_if= seq; m_seq= seq->init(seq_init_param, n_ranges, mrr_mode); - if ((error= multi_range_key_create_key(seq, m_seq))) + if (unlikely((error= multi_range_key_create_key(seq, m_seq)))) DBUG_RETURN(0); m_part_seq_if.get_key_info= (seq->get_key_info ? @@ -6406,12 +6436,12 @@ int ha_partition::multi_range_read_init(RANGE_SEQ_IF *seq, else m_mrr_buffer[i]= *buf; - if ((error= (*file)-> - multi_range_read_init(&m_part_seq_if, - &m_partition_part_key_multi_range_hld[i], - m_part_mrr_range_length[i], - mrr_mode, - &m_mrr_buffer[i]))) + if (unlikely((error= (*file)-> + multi_range_read_init(&m_part_seq_if, + &m_partition_part_key_multi_range_hld[i], + m_part_mrr_range_length[i], + mrr_mode, + &m_mrr_buffer[i])))) goto error; m_stock_range_seq[i]= 0; } @@ -6440,25 +6470,28 @@ int ha_partition::multi_range_read_next(range_id_t *range_info) { if (m_multi_range_read_first) { - if ((error= handle_ordered_index_scan(table->record[0], FALSE))) + if (unlikely((error= handle_ordered_index_scan(table->record[0], + FALSE)))) DBUG_RETURN(error); if (!m_pre_calling) m_multi_range_read_first= FALSE; } - else if ((error= handle_ordered_next(table->record[0], eq_range))) + else if (unlikely((error= handle_ordered_next(table->record[0], + eq_range)))) DBUG_RETURN(error); *range_info= m_mrr_range_current->ptr; } else { - if (m_multi_range_read_first) + if (unlikely(m_multi_range_read_first)) { - if ((error= handle_unordered_scan_next_partition(table->record[0]))) + if (unlikely((error= + handle_unordered_scan_next_partition(table->record[0])))) DBUG_RETURN(error); if (!m_pre_calling) m_multi_range_read_first= FALSE; } - else if ((error= handle_unordered_next(table->record[0], FALSE))) + else if (unlikely((error= handle_unordered_next(table->record[0], FALSE)))) DBUG_RETURN(error); *range_info= @@ -6631,7 +6664,7 @@ int ha_partition::ft_init() */ if (m_pre_calling) { - if ((error= pre_ft_end())) + if (unlikely((error= pre_ft_end()))) goto err1; } else @@ -6642,7 +6675,7 @@ int ha_partition::ft_init() if (bitmap_is_set(&(m_part_info->read_partitions), i)) { error= m_pre_calling ? m_file[i]->pre_ft_init() : m_file[i]->ft_init(); - if (error) + if (unlikely(error)) goto err2; } } @@ -6889,9 +6922,6 @@ int ha_partition::ft_read(uchar *buf) /* if we get here, then the current partition ft_next returned failure */ - if (result == HA_ERR_RECORD_DELETED) - continue; // Probably MyISAM - if (result != HA_ERR_END_OF_FILE) goto end_dont_reset_start_part; // Return error @@ -7195,7 +7225,7 @@ int ha_partition::handle_pre_scan(bool reverse_order, bool use_parallel) } if (error == HA_ERR_END_OF_FILE) error= 0; - if (error) + if (unlikely(error)) DBUG_RETURN(error); } table->status= 0; @@ -7250,8 +7280,8 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) if (m_index_scan_type == partition_read_multi_range) { - if (!(error= file-> - multi_range_read_next(&m_range_info[m_part_spec.start_part]))) + if (likely(!(error= file-> + multi_range_read_next(&m_range_info[m_part_spec.start_part])))) { m_last_part= m_part_spec.start_part; DBUG_RETURN(0); @@ -7259,7 +7289,7 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) } else if (m_index_scan_type == partition_read_range) { - if (!(error= file->read_range_next())) + if (likely(!(error= file->read_range_next()))) { m_last_part= m_part_spec.start_part; DBUG_RETURN(0); @@ -7267,8 +7297,8 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) } else if (is_next_same) { - if (!(error= file->ha_index_next_same(buf, m_start_key.key, - m_start_key.length))) + if (likely(!(error= file->ha_index_next_same(buf, m_start_key.key, + m_start_key.length)))) { m_last_part= m_part_spec.start_part; DBUG_RETURN(0); @@ -7276,14 +7306,14 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) } else { - if (!(error= file->ha_index_next(buf))) + if (likely(!(error= file->ha_index_next(buf)))) { m_last_part= m_part_spec.start_part; DBUG_RETURN(0); // Row was in range } } - if (error == HA_ERR_END_OF_FILE) + if (unlikely(error == HA_ERR_END_OF_FILE)) { m_part_spec.start_part++; // Start using next part error= handle_unordered_scan_next_partition(buf); @@ -7355,12 +7385,13 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf) DBUG_ASSERT(FALSE); DBUG_RETURN(1); } - if (!error) + if (likely(!error)) { m_last_part= i; DBUG_RETURN(0); } - if ((error != HA_ERR_END_OF_FILE) && (error != HA_ERR_KEY_NOT_FOUND)) + if (likely((error != HA_ERR_END_OF_FILE) && + (error != HA_ERR_KEY_NOT_FOUND))) DBUG_RETURN(error); /* @@ -7420,7 +7451,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) error= handle_pre_scan(reverse_order, m_pre_call_use_parallel); else error= handle_pre_scan(reverse_order, check_parallel_search()); - if (error) + if (unlikely(error)) DBUG_RETURN(error); if (m_key_not_found) @@ -7484,7 +7515,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) */ error= file->read_range_first(m_start_key.key? &m_start_key: NULL, end_range, eq_range, TRUE); - if (!error) + if (likely(!error)) memcpy(rec_buf_ptr, table->record[0], m_rec_length); reverse_order= FALSE; break; @@ -7501,7 +7532,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) bitmap_clear_bit(&m_mrr_used_partitions, i); continue; } - if (!error) + if (likely(!error)) { memcpy(rec_buf_ptr, table->record[0], m_rec_length); reverse_order= FALSE; @@ -7525,7 +7556,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) DBUG_ASSERT(FALSE); DBUG_RETURN(HA_ERR_END_OF_FILE); } - if (!error) + if (likely(!error)) { found= TRUE; if (!m_using_extended_keys) @@ -7687,7 +7718,7 @@ int ha_partition::handle_ordered_index_scan_key_not_found() error= m_file[i]->ha_index_next(curr_rec_buf); /* HA_ERR_KEY_NOT_FOUND is not allowed from index_next! */ DBUG_ASSERT(error != HA_ERR_KEY_NOT_FOUND); - if (!error) + if (likely(!error)) { DBUG_PRINT("info", ("partition queue_insert(1)")); queue_insert(&m_queue, part_buf); @@ -7749,7 +7780,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) { /* There are partitions not included in the index record queue. */ uint old_elements= m_queue.elements; - if ((error= handle_ordered_index_scan_key_not_found())) + if (unlikely((error= handle_ordered_index_scan_key_not_found()))) DBUG_RETURN(error); /* If the queue top changed, i.e. one of the partitions that gave @@ -7785,9 +7816,9 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) bool get_next= FALSE; error= file->multi_range_read_next(&m_range_info[part_id]); DBUG_PRINT("info", ("error: %d", error)); - if (error == HA_ERR_KEY_NOT_FOUND) + if (unlikely(error == HA_ERR_KEY_NOT_FOUND)) error= HA_ERR_END_OF_FILE; - if (error == HA_ERR_END_OF_FILE) + if (unlikely(error == HA_ERR_END_OF_FILE)) { bitmap_clear_bit(&m_mrr_used_partitions, part_id); DBUG_PRINT("info", ("partition m_queue.elements: %u", m_queue.elements)); @@ -7805,7 +7836,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) } get_next= TRUE; } - else if (!error) + else if (likely(!error)) { DBUG_PRINT("info", ("m_range_info[%u])->id: %u", part_id, ((PARTITION_KEY_MULTI_RANGE *) @@ -7900,7 +7931,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) error= file->ha_index_next_same(rec_buf, m_start_key.key, m_start_key.length); - if (error) + if (unlikely(error)) { if (error == HA_ERR_END_OF_FILE && m_queue.elements) { @@ -7957,7 +7988,7 @@ int ha_partition::handle_ordered_prev(uchar *buf) uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; handler *file= m_file[part_id]; - if ((error= file->ha_index_prev(rec_buf))) + if (unlikely((error= file->ha_index_prev(rec_buf)))) { if (error == HA_ERR_END_OF_FILE && m_queue.elements) { @@ -8351,7 +8382,7 @@ int ha_partition::open_read_partitions(char *name_buff, size_t name_buff_size) { handler **file; char *name_buffer_ptr; - int error; + int error= 0; name_buffer_ptr= m_name_buffer_ptr; file= m_file; @@ -8362,18 +8393,27 @@ int ha_partition::open_read_partitions(char *name_buff, size_t name_buff_size) int is_open= bitmap_is_set(&m_opened_partitions, n_file); int should_be_open= bitmap_is_set(&m_part_info->read_partitions, n_file); - if (is_open && !should_be_open) - { - if ((error= (*file)->ha_close())) - goto err_handler; - bitmap_clear_bit(&m_opened_partitions, n_file); - } - else if (!is_open && should_be_open) + /* + TODO: we can close some opened partitions if they're not + used in the query. It probably should be syncronized with the + table_open_cache value. + + if (is_open && !should_be_open) + { + if (unlikely((error= (*file)->ha_close()))) + goto err_handler; + bitmap_clear_bit(&m_opened_partitions, n_file); + } + else + */ + if (!is_open && should_be_open) { LEX_CSTRING save_connect_string= table->s->connect_string; - if ((error= create_partition_name(name_buff, name_buff_size, - table->s->normalized_path.str, - name_buffer_ptr, NORMAL_PART_NAME, FALSE))) + if (unlikely((error= + create_partition_name(name_buff, name_buff_size, + table->s->normalized_path.str, + name_buffer_ptr, NORMAL_PART_NAME, + FALSE)))) goto err_handler; if (!((*file)->ht->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION)) table->s->connect_string= m_connect_string[(uint)(file-m_file)]; @@ -8404,7 +8444,7 @@ int ha_partition::change_partitions_to_open(List<String> *partition_names) return 0; m_partitions_to_open= partition_names; - if ((error= m_part_info->set_partition_bitmaps(partition_names))) + if (unlikely((error= m_part_info->set_partition_bitmaps(partition_names)))) goto err_handler; if (m_lock_type != F_UNLCK) @@ -8419,8 +8459,8 @@ int ha_partition::change_partitions_to_open(List<String> *partition_names) if (bitmap_cmp(&m_opened_partitions, &m_part_info->read_partitions) != 0) return 0; - if ((error= read_par_file(table->s->normalized_path.str)) || - (error= open_read_partitions(name_buff, sizeof(name_buff)))) + if (unlikely((error= read_par_file(table->s->normalized_path.str)) || + (error= open_read_partitions(name_buff, sizeof(name_buff))))) goto err_handler; clear_handler_file(); @@ -8647,6 +8687,16 @@ err_handler: HA_EXTRA_NO_READCHECK=5 No readcheck on update HA_EXTRA_READCHECK=6 Use readcheck (def) + HA_EXTRA_REMEMBER_POS: + HA_EXTRA_RESTORE_POS: + System versioning needs this for MyISAM and Aria tables. + On DELETE using PRIMARY KEY: + 1) handler::ha_index_read_map() saves rowid used for row delete/update + 2) handler::ha_update_row() can rewrite saved rowid + 3) handler::ha_delete_row()/handler::ha_update_row() expects saved but got + different rowid and operation fails + Using those flags prevents harmful side effect of 2) + 4) Operations only used by temporary tables for query processing ---------------------------------------------------------------- HA_EXTRA_RESET_STATE: @@ -8706,8 +8756,6 @@ err_handler: Only used MyISAM, only used internally in MyISAM handler, never called from server level. HA_EXTRA_KEYREAD_CHANGE_POS: - HA_EXTRA_REMEMBER_POS: - HA_EXTRA_RESTORE_POS: HA_EXTRA_PRELOAD_BUFFER_SIZE: HA_EXTRA_CHANGE_KEY_TO_DUP: HA_EXTRA_CHANGE_KEY_TO_UNIQUE: @@ -8790,6 +8838,8 @@ int ha_partition::extra(enum ha_extra_function operation) case HA_EXTRA_PREPARE_FOR_DROP: case HA_EXTRA_FLUSH_CACHE: case HA_EXTRA_PREPARE_FOR_ALTER_TABLE: + case HA_EXTRA_REMEMBER_POS: + case HA_EXTRA_RESTORE_POS: { DBUG_RETURN(loop_extra(operation)); } @@ -9387,8 +9437,8 @@ ha_rows ha_partition::records() i= bitmap_get_next_set(&m_part_info->read_partitions, i)) { ha_rows rows; - if ((error= m_file[i]->pre_records()) || - (rows= m_file[i]->records()) == HA_POS_ERROR) + if (unlikely((error= m_file[i]->pre_records()) || + (rows= m_file[i]->records()) == HA_POS_ERROR)) DBUG_RETURN(HA_POS_ERROR); tot_rows+= rows; } @@ -10036,7 +10086,7 @@ bool ha_partition::commit_inplace_alter_table(TABLE *altered_table, ha_alter_info->handler_ctx= part_inplace_ctx->handler_ctx_array[0]; error= m_file[0]->ha_commit_inplace_alter_table(altered_table, ha_alter_info, commit); - if (error) + if (unlikely(error)) goto end; if (ha_alter_info->group_commit_ctx) { @@ -10347,7 +10397,7 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment, /* Only nb_desired_values = 1 makes sense */ (*file)->get_auto_increment(offset, increment, 1, &first_value_part, &nb_reserved_values_part); - if (first_value_part == ULONGLONG_MAX) // error in one partition + if (unlikely(first_value_part == ULONGLONG_MAX)) // error in one partition { *first_value= first_value_part; /* log that the error was between table/partition handler */ @@ -10508,7 +10558,7 @@ int ha_partition::disable_indexes(uint mode) DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions))); for (file= m_file; *file; file++) { - if ((error= (*file)->ha_disable_indexes(mode))) + if (unlikely((error= (*file)->ha_disable_indexes(mode)))) break; } return error; @@ -10533,7 +10583,7 @@ int ha_partition::enable_indexes(uint mode) DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions))); for (file= m_file; *file; file++) { - if ((error= (*file)->ha_enable_indexes(mode))) + if (unlikely((error= (*file)->ha_enable_indexes(mode)))) break; } return error; @@ -10558,7 +10608,7 @@ int ha_partition::indexes_are_disabled(void) DBUG_ASSERT(bitmap_is_set_all(&(m_part_info->lock_partitions))); for (file= m_file; *file; file++) { - if ((error= (*file)->indexes_are_disabled())) + if (unlikely((error= (*file)->indexes_are_disabled()))) break; } return error; @@ -10597,6 +10647,8 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair) { /* Only need to read the partitioning fields. */ bitmap_union(table->read_set, &m_part_info->full_part_field_set); + if (table->vcol_set) + bitmap_union(table->vcol_set, &m_part_info->full_part_field_set); } if ((result= m_file[read_part_id]->ha_rnd_init(1))) @@ -10606,8 +10658,6 @@ int ha_partition::check_misplaced_rows(uint read_part_id, bool do_repair) { if ((result= m_file[read_part_id]->ha_rnd_next(m_rec0))) { - if (result == HA_ERR_RECORD_DELETED) - continue; if (result != HA_ERR_END_OF_FILE) break; @@ -10958,7 +11008,7 @@ int ha_partition::exec_bulk_update(ha_rows *dup_key_found) do { - if ((error= (*file)->exec_bulk_update(dup_key_found))) + if (unlikely((error= (*file)->exec_bulk_update(dup_key_found)))) DBUG_RETURN(error); } while (*(++file)); DBUG_RETURN(0); @@ -11123,9 +11173,9 @@ int ha_partition::direct_update_rows_init() bitmap_is_set(&(m_part_info->lock_partitions), i)) { file= m_file[i]; - if ((error= (m_pre_calling ? - file->pre_direct_update_rows_init() : - file->direct_update_rows_init()))) + if (unlikely((error= (m_pre_calling ? + file->pre_direct_update_rows_init() : + file->direct_update_rows_init())))) { DBUG_PRINT("info", ("partition FALSE by storage engine")); DBUG_RETURN(error); @@ -11221,14 +11271,14 @@ int ha_partition::direct_update_rows(ha_rows *update_rows_result) { if (rnd_seq && (m_pre_calling ? file->pre_inited : file->inited) == NONE) { - if ((error= (m_pre_calling ? - file->ha_pre_rnd_init(TRUE) : - file->ha_rnd_init(TRUE)))) + if (unlikely((error= (m_pre_calling ? + file->ha_pre_rnd_init(TRUE) : + file->ha_rnd_init(TRUE))))) DBUG_RETURN(error); } - if ((error= (m_pre_calling ? - (file)->pre_direct_update_rows() : - (file)->ha_direct_update_rows(&update_rows)))) + if (unlikely((error= (m_pre_calling ? + (file)->pre_direct_update_rows() : + (file)->ha_direct_update_rows(&update_rows))))) { if (rnd_seq) { @@ -11243,9 +11293,9 @@ int ha_partition::direct_update_rows(ha_rows *update_rows_result) } if (rnd_seq) { - if ((error= (m_pre_calling ? - file->ha_pre_index_or_rnd_end() : - file->ha_index_or_rnd_end()))) + if (unlikely((error= (m_pre_calling ? + file->ha_pre_index_or_rnd_end() : + file->ha_index_or_rnd_end())))) DBUG_RETURN(error); } } @@ -11309,9 +11359,9 @@ int ha_partition::direct_delete_rows_init() bitmap_is_set(&(m_part_info->lock_partitions), i)) { handler *file= m_file[i]; - if ((error= (m_pre_calling ? - file->pre_direct_delete_rows_init() : - file->direct_delete_rows_init()))) + if (unlikely((error= (m_pre_calling ? + file->pre_direct_delete_rows_init() : + file->direct_delete_rows_init())))) { DBUG_PRINT("exit", ("error in direct_delete_rows_init")); DBUG_RETURN(error); @@ -11408,9 +11458,9 @@ int ha_partition::direct_delete_rows(ha_rows *delete_rows_result) { if (rnd_seq && (m_pre_calling ? file->pre_inited : file->inited) == NONE) { - if ((error= (m_pre_calling ? - file->ha_pre_rnd_init(TRUE) : - file->ha_rnd_init(TRUE)))) + if (unlikely((error= (m_pre_calling ? + file->ha_pre_rnd_init(TRUE) : + file->ha_rnd_init(TRUE))))) DBUG_RETURN(error); } if ((error= (m_pre_calling ? @@ -11427,9 +11477,9 @@ int ha_partition::direct_delete_rows(ha_rows *delete_rows_result) } if (rnd_seq) { - if ((error= (m_pre_calling ? - file->ha_pre_index_or_rnd_end() : - file->ha_index_or_rnd_end()))) + if (unlikely((error= (m_pre_calling ? + file->ha_pre_index_or_rnd_end() : + file->ha_index_or_rnd_end())))) DBUG_RETURN(error); } } diff --git a/sql/ha_sequence.cc b/sql/ha_sequence.cc index b500ce3c1f6..d5064af16c3 100644 --- a/sql/ha_sequence.cc +++ b/sql/ha_sequence.cc @@ -81,17 +81,21 @@ int ha_sequence::open(const char *name, int mode, uint flags) DBUG_ASSERT(table->s == table_share && file); file->table= table; - if (!(error= file->open(name, mode, flags))) + if (likely(!(error= file->open(name, mode, flags)))) { /* - Copy values set by handler::open() in the underlying handler - Reuse original storage engine data for duplicate key reference - It would be easier to do this if we would have another handler - call: fixup_after_open()... - */ - ref= file->ref; + Allocate ref in table's mem_root. We can't use table's ref + as it's allocated by ha_ caller that allocates this. + */ ref_length= file->ref_length; - dup_ref= file->dup_ref; + if (!(ref= (uchar*) alloc_root(&table->mem_root,ALIGN_SIZE(ref_length)*2))) + { + file->ha_close(); + error=HA_ERR_OUT_OF_MEM; + DBUG_RETURN(error); + } + file->ref= ref; + file->dup_ref= dup_ref= ref+ALIGN_SIZE(file->ref_length); /* ha_open() sets the following for us. We have to set this for the @@ -107,7 +111,7 @@ int ha_sequence::open(const char *name, int mode, uint flags) /* Don't try to read the inital row the call is part of create code */ if (!(flags & (HA_OPEN_FOR_CREATE | HA_OPEN_FOR_REPAIR))) { - if ((error= table->s->sequence->read_initial_values(table))) + if (unlikely((error= table->s->sequence->read_initial_values(table)))) file->ha_close(); } else @@ -212,7 +216,7 @@ int ha_sequence::write_row(uchar *buf) if (tmp_seq.check_and_adjust(0)) DBUG_RETURN(HA_ERR_SEQUENCE_INVALID_DATA); sequence->copy(&tmp_seq); - if (!(error= file->write_row(buf))) + if (likely(!(error= file->write_row(buf)))) sequence->initialized= SEQUENCE::SEQ_READY_TO_USE; DBUG_RETURN(error); } @@ -229,14 +233,10 @@ int ha_sequence::write_row(uchar *buf) - Get an exclusive lock for the table. This is needed to ensure that we excute all full inserts (same as ALTER SEQUENCE) in same order on master and slaves - - Check that we are only using one table. - This is to avoid deadlock problems when upgrading lock to exlusive. - Check that the new row is an accurate SEQUENCE object */ THD *thd= table->in_use; - if (thd->lock->table_count != 1) - DBUG_RETURN(ER_WRONG_INSERT_INTO_SEQUENCE); if (table->s->tmp_table == NO_TMP_TABLE && thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE, @@ -255,7 +255,7 @@ int ha_sequence::write_row(uchar *buf) sequence->write_lock(table); } - if (!(error= file->update_first_row(buf))) + if (likely(!(error= file->update_first_row(buf)))) { Log_func *log_func= Write_rows_log_event::binlog_row_logging_function; if (!sequence_locked) @@ -322,7 +322,8 @@ int ha_sequence::external_lock(THD *thd, int lock_type) Copy lock flag to satisfy DBUG_ASSERT checks in ha_* functions in handler.cc when we later call it with file->ha_..() */ - file->m_lock_type= lock_type; + if (!error) + file->m_lock_type= lock_type; return error; } diff --git a/sql/handler.cc b/sql/handler.cc index 2c93ffeaa73..07459d4cd8c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -698,7 +698,7 @@ int ha_end() So if flag is equal to HA_PANIC_CLOSE, the deallocate the errors. */ - if (ha_finish_errors()) + if (unlikely(ha_finish_errors())) error= 1; DBUG_RETURN(error); @@ -1197,7 +1197,7 @@ int ha_prepare(THD *thd) handlerton *ht= ha_info->ht(); if (ht->prepare) { - if (prepare_or_error(ht, thd, all)) + if (unlikely(prepare_or_error(ht, thd, all))) { ha_rollback_trans(thd, all); error=1; @@ -1475,7 +1475,7 @@ int ha_commit_trans(THD *thd, bool all) Sic: we know that prepare() is not NULL since otherwise trans->no_2pc would have been set. */ - if (prepare_or_error(ht, thd, all)) + if (unlikely(prepare_or_error(ht, thd, all))) goto err; need_prepare_ordered|= (ht->prepare_ordered != NULL); @@ -2525,7 +2525,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path, dummy_table.s= &dummy_share; path= get_canonical_filename(file, path, tmp_path); - if ((error= file->ha_delete_table(path))) + if (unlikely((error= file->ha_delete_table(path)))) { /* it's not an error if the table doesn't exist in the engine. @@ -2681,7 +2681,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, set_partitions_to_open(partitions_to_open); - if ((error=open(name,mode,test_if_locked))) + if (unlikely((error=open(name,mode,test_if_locked)))) { if ((error == EACCES || error == EROFS) && mode == O_RDWR && (table->db_stat & HA_TRY_READ_ONLY)) @@ -2690,7 +2690,7 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, error=open(name,O_RDONLY,test_if_locked); } } - if (error) + if (unlikely(error)) { my_errno= error; /* Safeguard */ DBUG_PRINT("error",("error: %d errno: %d",error,errno)); @@ -2759,19 +2759,27 @@ int handler::ha_rnd_next(uchar *buf) m_lock_type != F_UNLCK); DBUG_ASSERT(inited == RND); - TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0, - { result= rnd_next(buf); }) - if (!result) + do { - update_rows_read(); - if (table->vfield && buf == table->record[0]) - table->update_virtual_fields(this, VCOL_UPDATE_FOR_READ); - increment_statistics(&SSV::ha_read_rnd_next_count); - } - else if (result == HA_ERR_RECORD_DELETED) - increment_statistics(&SSV::ha_read_rnd_deleted_count); + TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0, + { result= rnd_next(buf); }) + if (result != HA_ERR_RECORD_DELETED) + break; + status_var_increment(table->in_use->status_var.ha_read_rnd_deleted_count); + } while (!table->in_use->check_killed(1)); + + if (result == HA_ERR_RECORD_DELETED) + result= HA_ERR_ABORTED_BY_USER; else + { + if (!result) + { + update_rows_read(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(this, VCOL_UPDATE_FOR_READ); + } increment_statistics(&SSV::ha_read_rnd_next_count); + } table->status=result ? STATUS_NOT_FOUND: 0; DBUG_RETURN(result); @@ -2789,7 +2797,9 @@ int handler::ha_rnd_pos(uchar *buf, uchar *pos) TABLE_IO_WAIT(tracker, m_psi, PSI_TABLE_FETCH_ROW, MAX_KEY, 0, { result= rnd_pos(buf, pos); }) increment_statistics(&SSV::ha_read_rnd_count); - if (!result) + if (result == HA_ERR_RECORD_DELETED) + result= HA_ERR_KEY_NOT_FOUND; + else if (!result) { update_rows_read(); if (table->vfield && buf == table->record[0]) @@ -2967,7 +2977,7 @@ bool handler::ha_was_semi_consistent_read() int handler::ha_rnd_init_with_error(bool scan) { int error; - if (!(error= ha_rnd_init(scan))) + if (likely(!(error= ha_rnd_init(scan)))) return 0; table->file->print_error(error, MYF(0)); return error; @@ -2983,7 +2993,7 @@ int handler::ha_rnd_init_with_error(bool scan) */ int handler::read_first_row(uchar * buf, uint primary_key) { - register int error; + int error; DBUG_ENTER("handler::read_first_row"); /* @@ -2994,23 +3004,22 @@ int handler::read_first_row(uchar * buf, uint primary_key) if (stats.deleted < 10 || primary_key >= MAX_KEY || !(index_flags(primary_key, 0, 0) & HA_READ_ORDER)) { - if (!(error= ha_rnd_init(1))) + if (likely(!(error= ha_rnd_init(1)))) { - while ((error= ha_rnd_next(buf)) == HA_ERR_RECORD_DELETED) - /* skip deleted row */; + error= ha_rnd_next(buf); const int end_error= ha_rnd_end(); - if (!error) + if (likely(!error)) error= end_error; } } else { /* Find the first row through the primary key */ - if (!(error= ha_index_init(primary_key, 0))) + if (likely(!(error= ha_index_init(primary_key, 0)))) { error= ha_index_first(buf); const int end_error= ha_index_end(); - if (!error) + if (likely(!error)) error= end_error; } } @@ -3430,7 +3439,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, *nb_reserved_values= 1; } - if (error) + if (unlikely(error)) { if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND) /* No entry found, that's fine */; @@ -3818,7 +3827,7 @@ void handler::print_error(int error, myf errflag) } } DBUG_ASSERT(textno > 0); - if (fatal_error) + if (unlikely(fatal_error)) { /* Ensure this becomes a true error */ errflag&= ~(ME_JUST_WARNING | ME_JUST_INFO); @@ -3945,7 +3954,7 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) if (table->s->frm_version < FRM_VER_TRUE_VARCHAR) return HA_ADMIN_NEEDS_ALTER; - if ((error= check_collation_compatibility())) + if (unlikely((error= check_collation_compatibility()))) return error; return check_for_upgrade(check_opt); @@ -4023,7 +4032,8 @@ uint handler::get_dup_key(int error) m_lock_type != F_UNLCK); DBUG_ENTER("handler::get_dup_key"); table->file->errkey = (uint) -1; - if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY || + if (error == HA_ERR_FOUND_DUPP_KEY || + error == HA_ERR_FOREIGN_DUPLICATE_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE || error == HA_ERR_NULL_IN_SPATIAL || error == HA_ERR_DROP_INDEX_FK) table->file->info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK); @@ -4087,14 +4097,14 @@ int handler::rename_table(const char * from, const char * to) start_ext= bas_ext(); for (ext= start_ext; *ext ; ext++) { - if (rename_file_ext(from, to, *ext)) + if (unlikely(rename_file_ext(from, to, *ext))) { if ((error=my_errno) != ENOENT) break; error= 0; } } - if (error) + if (unlikely(error)) { /* Try to revert the rename. Ignore errors. */ for (; ext >= start_ext; ext--) @@ -4138,15 +4148,15 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) if (table->s->mysql_version < MYSQL_VERSION_ID) { - if ((error= check_old_types())) + if (unlikely((error= check_old_types()))) return error; error= ha_check_for_upgrade(check_opt); - if (error && (error != HA_ADMIN_NEEDS_CHECK)) + if (unlikely(error && (error != HA_ADMIN_NEEDS_CHECK))) return error; - if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE)) + if (unlikely(!error && (check_opt->sql_flags & TT_FOR_UPGRADE))) return 0; } - if ((error= check(thd, check_opt))) + if (unlikely((error= check(thd, check_opt)))) return error; /* Skip updating frm version if not main handler. */ if (table->file != this) @@ -4469,20 +4479,8 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - -/* - Default implementation to support in-place alter table - and old online add/drop index API -*/ - -void handler::notify_table_changed() -{ - ha_create_partitioning_metadata(table->s->path.str, NULL, CHF_INDEX_FLAG); -} - - void Alter_inplace_info::report_unsupported_error(const char *not_supported, - const char *try_instead) + const char *try_instead) const { if (unsupported_reason == NULL) my_error(ER_ALTER_OPERATION_NOT_SUPPORTED, MYF(0), @@ -4579,7 +4577,6 @@ handler::ha_create_partitioning_metadata(const char *name, */ DBUG_ASSERT(m_lock_type == F_UNLCK || (!old_name && strcmp(name, table_share->path.str))); - mark_trx_read_write(); return create_partitioning_metadata(name, old_name, action_flag); } @@ -4669,7 +4666,7 @@ int ha_enable_transaction(THD *thd, bool on) is an optimization hint that storage engine is free to ignore. So, let's commit an open transaction (if any) now. */ - if (!(error= ha_commit_trans(thd, 0))) + if (likely(!(error= ha_commit_trans(thd, 0)))) error= trans_commit_implicit(thd); } DBUG_RETURN(error); @@ -4770,7 +4767,8 @@ void handler::update_global_table_stats() if (rows_read + rows_changed == 0) return; // Nothing to update. - DBUG_ASSERT(table->s && table->s->table_cache_key.str); + DBUG_ASSERT(table->s); + DBUG_ASSERT(table->s->table_cache_key.str); mysql_mutex_lock(&LOCK_global_table_stats); /* Gets the global table stats, creating one if necessary. */ @@ -4927,7 +4925,7 @@ int ha_create_table(THD *thd, const char *path, error= table.file->ha_create(name, &table, create_info); - if (error) + if (unlikely(error)) { if (!thd->is_error()) my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table_name, error); @@ -5082,7 +5080,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, int error= hton->discover_table(hton, thd, share); if (error != HA_ERR_NO_SUCH_TABLE) { - if (error) + if (unlikely(error)) { if (!share->error) { @@ -5719,12 +5717,12 @@ int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key, int error, UNINIT_VAR(error1); error= ha_index_init(index, 0); - if (!error) + if (likely(!error)) { error= index_read_map(buf, key, keypart_map, find_flag); error1= ha_index_end(); } - return error ? error : error1; + return error ? error : error1; } @@ -5861,7 +5859,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) We also check thd->is_error() as Innodb may return 0 even if there was an error. */ - if (!result && !thd->is_error()) + if (likely(!result && !thd->is_error())) my_eof(thd); else if (!thd->is_error()) my_error(ER_GET_ERRNO, MYF(0), errno, hton_name(db_type)->str); @@ -6124,7 +6122,7 @@ int handler::ha_external_lock(THD *thd, int lock_type) DBUG_EXECUTE_IF("external_lock_failure", error= HA_ERR_GENERIC;); - if (error == 0 || lock_type == F_UNLCK) + if (likely(error == 0 || lock_type == F_UNLCK)) { m_lock_type= lock_type; cached_table_flags= table_flags(); @@ -6245,10 +6243,10 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data) int handler::update_first_row(uchar *new_data) { int error; - if (!(error= ha_rnd_init(1))) + if (likely(!(error= ha_rnd_init(1)))) { int end_error; - if (!(error= ha_rnd_next(table->record[1]))) + if (likely(!(error= ha_rnd_next(table->record[1])))) { /* We have to do the memcmp as otherwise we may get error 169 from InnoDB @@ -6257,7 +6255,7 @@ int handler::update_first_row(uchar *new_data) error= update_row(table->record[1], new_data); } end_error= ha_rnd_end(); - if (!error) + if (likely(!error)) error= end_error; /* Logging would be wrong if update_row works but ha_rnd_end fails */ DBUG_ASSERT(!end_error || error != 0); @@ -6374,7 +6372,8 @@ void handler::use_hidden_primary_key() Handler_share *handler::get_ha_share_ptr() { DBUG_ENTER("handler::get_ha_share_ptr"); - DBUG_ASSERT(ha_share && table_share); + DBUG_ASSERT(ha_share); + DBUG_ASSERT(table_share); #ifndef DBUG_OFF if (table_share->tmp_table == NO_TMP_TABLE) @@ -6854,7 +6853,8 @@ static Create_field *vers_init_sys_field(THD *thd, const char *field_name, int f f->flags= flags | NOT_NULL_FLAG; if (integer) { - f->set_handler(&type_handler_longlong); + DBUG_ASSERT(0); // Not implemented yet + f->set_handler(&type_handler_vers_trx_id); f->length= MY_INT64_NUM_DECIMAL_DIGITS - 1; f->flags|= UNSIGNED_FLAG; } @@ -6884,8 +6884,8 @@ static bool vers_create_sys_field(THD *thd, const char *field_name, return false; } -const LString_i Vers_parse_info::default_start= "row_start"; -const LString_i Vers_parse_info::default_end= "row_end"; +const Lex_ident Vers_parse_info::default_start= "row_start"; +const Lex_ident Vers_parse_info::default_end= "row_end"; bool Vers_parse_info::fix_implicit(THD *thd, Alter_info *alter_info) { @@ -7055,7 +7055,7 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, { if (f->change.length && f->flags & VERS_SYSTEM_FIELD) { - my_error(ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN, MYF(0)); + my_error(ER_VERS_ALTER_SYSTEM_FIELD, MYF(0), f->field_name.str); return true; } } @@ -7079,10 +7079,12 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, // copy info from existing table create_info->options|= HA_VERSIONED_TABLE; - DBUG_ASSERT(share->vers_start_field() && share->vers_end_field()); - LString_i start(share->vers_start_field()->field_name); - LString_i end(share->vers_end_field()->field_name); - DBUG_ASSERT(start.ptr() && end.ptr()); + DBUG_ASSERT(share->vers_start_field()); + DBUG_ASSERT(share->vers_end_field()); + Lex_ident start(share->vers_start_field()->field_name); + Lex_ident end(share->vers_end_field()->field_name); + DBUG_ASSERT(start.str); + DBUG_ASSERT(end.str); as_row= start_end_t(start, end); system_time= as_row; @@ -7186,8 +7188,8 @@ bool Vers_parse_info::need_check(const Alter_info *alter_info) const alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING || *this; } -bool Vers_parse_info::check_conditions(const LString &table_name, - const LString &db) const +bool Vers_parse_info::check_conditions(const Lex_table_name &table_name, + const Lex_table_name &db) const { if (!as_row.start || !as_row.end) { @@ -7217,7 +7219,8 @@ bool Vers_parse_info::check_conditions(const LString &table_name, return false; } -bool Vers_parse_info::check_sys_fields(const LString &table_name, const LString &db, +bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name, + const Lex_table_name &db, Alter_info *alter_info, bool native) { if (check_conditions(table_name, db)) diff --git a/sql/handler.h b/sql/handler.h index c5d92cbbaab..3d1b764bd14 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -73,11 +73,14 @@ class sequence_definition; */ enum enum_alter_inplace_result { HA_ALTER_ERROR, + HA_ALTER_INPLACE_COPY_NO_LOCK, + HA_ALTER_INPLACE_COPY_LOCK, + HA_ALTER_INPLACE_NOCOPY_LOCK, + HA_ALTER_INPLACE_NOCOPY_NO_LOCK, + HA_ALTER_INPLACE_INSTANT, HA_ALTER_INPLACE_NOT_SUPPORTED, HA_ALTER_INPLACE_EXCLUSIVE_LOCK, - HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE, HA_ALTER_INPLACE_SHARED_LOCK, - HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE, HA_ALTER_INPLACE_NO_LOCK }; @@ -628,43 +631,41 @@ typedef ulonglong alter_table_operations; ALTER_DROP_STORED_COLUMN) #define ALTER_COLUMN_DEFAULT ALTER_CHANGE_COLUMN_DEFAULT -#define ALTER_DROP_HISTORICAL (1ULL << 35) - // Add non-unique, non-primary index -#define ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 36) +#define ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 35) // Drop non-unique, non-primary index -#define ALTER_DROP_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 37) +#define ALTER_DROP_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 36) // Add unique, non-primary index -#define ALTER_ADD_UNIQUE_INDEX (1ULL << 38) +#define ALTER_ADD_UNIQUE_INDEX (1ULL << 37) // Drop unique, non-primary index -#define ALTER_DROP_UNIQUE_INDEX (1ULL << 39) +#define ALTER_DROP_UNIQUE_INDEX (1ULL << 38) // Add primary index -#define ALTER_ADD_PK_INDEX (1ULL << 40) +#define ALTER_ADD_PK_INDEX (1ULL << 39) // Drop primary index -#define ALTER_DROP_PK_INDEX (1ULL << 41) +#define ALTER_DROP_PK_INDEX (1ULL << 40) // Virtual generated column -#define ALTER_ADD_VIRTUAL_COLUMN (1ULL << 42) +#define ALTER_ADD_VIRTUAL_COLUMN (1ULL << 41) // Stored base (non-generated) column -#define ALTER_ADD_STORED_BASE_COLUMN (1ULL << 43) +#define ALTER_ADD_STORED_BASE_COLUMN (1ULL << 42) // Stored generated column -#define ALTER_ADD_STORED_GENERATED_COLUMN (1ULL << 44) +#define ALTER_ADD_STORED_GENERATED_COLUMN (1ULL << 43) // Drop column -#define ALTER_DROP_VIRTUAL_COLUMN (1ULL << 45) -#define ALTER_DROP_STORED_COLUMN (1ULL << 46) +#define ALTER_DROP_VIRTUAL_COLUMN (1ULL << 44) +#define ALTER_DROP_STORED_COLUMN (1ULL << 45) // Rename column (verified; ALTER_RENAME_COLUMN may use original name) -#define ALTER_COLUMN_NAME (1ULL << 47) +#define ALTER_COLUMN_NAME (1ULL << 46) // Change column datatype -#define ALTER_VIRTUAL_COLUMN_TYPE (1ULL << 48) -#define ALTER_STORED_COLUMN_TYPE (1ULL << 49) +#define ALTER_VIRTUAL_COLUMN_TYPE (1ULL << 47) +#define ALTER_STORED_COLUMN_TYPE (1ULL << 48) /** Change column datatype in such way that new type has compatible @@ -672,45 +673,45 @@ typedef ulonglong alter_table_operations; possible to perform change by only updating data dictionary without changing table rows. */ -#define ALTER_COLUMN_EQUAL_PACK_LENGTH (1ULL << 50) +#define ALTER_COLUMN_EQUAL_PACK_LENGTH (1ULL << 49) // Reorder column -#define ALTER_STORED_COLUMN_ORDER (1ULL << 51) +#define ALTER_STORED_COLUMN_ORDER (1ULL << 50) // Reorder column -#define ALTER_VIRTUAL_COLUMN_ORDER (1ULL << 52) +#define ALTER_VIRTUAL_COLUMN_ORDER (1ULL << 51) // Change column from NOT NULL to NULL -#define ALTER_COLUMN_NULLABLE (1ULL << 53) +#define ALTER_COLUMN_NULLABLE (1ULL << 52) // Change column from NULL to NOT NULL -#define ALTER_COLUMN_NOT_NULLABLE (1ULL << 54) +#define ALTER_COLUMN_NOT_NULLABLE (1ULL << 53) // Change column generation expression -#define ALTER_VIRTUAL_GCOL_EXPR (1ULL << 55) -#define ALTER_STORED_GCOL_EXPR (1ULL << 56) +#define ALTER_VIRTUAL_GCOL_EXPR (1ULL << 54) +#define ALTER_STORED_GCOL_EXPR (1ULL << 55) // column's engine options changed, something in field->option_struct -#define ALTER_COLUMN_OPTION (1ULL << 57) +#define ALTER_COLUMN_OPTION (1ULL << 56) // MySQL alias for the same thing: -#define ALTER_COLUMN_STORAGE_TYPE (1ULL << 58) +#define ALTER_COLUMN_STORAGE_TYPE ALTER_COLUMN_OPTION // Change the column format of column -#define ALTER_COLUMN_COLUMN_FORMAT (1ULL << 59) +#define ALTER_COLUMN_COLUMN_FORMAT (1ULL << 57) /** Changes in generated columns that affect storage, for example, when a vcol type or expression changes and this vcol is indexed or used in a partitioning expression */ -#define ALTER_COLUMN_VCOL (1ULL << 60) +#define ALTER_COLUMN_VCOL (1ULL << 58) /** ALTER TABLE for a partitioned table. The engine needs to commit online alter of all partitions atomically (using group_commit_ctx) */ -#define ALTER_PARTITIONED (1ULL << 61) +#define ALTER_PARTITIONED (1ULL << 59) /* Flags set in partition_flags when altering partitions @@ -1919,15 +1920,15 @@ struct Vers_parse_info start_end_t(LEX_CSTRING _start, LEX_CSTRING _end) : start(_start), end(_end) {} - LString_i start; - LString_i end; + Lex_ident start; + Lex_ident end; }; start_end_t system_time; start_end_t as_row; vers_sys_type_t check_unit; - void set_system_time(LString start, LString end) + void set_system_time(Lex_ident start, Lex_ident end) { system_time.start= start; system_time.end= end; @@ -1955,16 +1956,18 @@ protected: return as_row.start || as_row.end || system_time.start || system_time.end; } bool need_check(const Alter_info *alter_info) const; - bool check_conditions(const LString &table_name, const LString &db) const; + bool check_conditions(const Lex_table_name &table_name, + const Lex_table_name &db) const; public: - static const LString_i default_start; - static const LString_i default_end; + static const Lex_ident default_start; + static const Lex_ident default_end; bool fix_alter_info(THD *thd, Alter_info *alter_info, HA_CREATE_INFO *create_info, TABLE *table); bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info, TABLE_LIST &src_table, TABLE_LIST &table); - bool check_sys_fields(const LString &table_name, const LString &db, + bool check_sys_fields(const Lex_table_name &table_name, + const Lex_table_name &db, Alter_info *alter_info, bool native); /** @@ -2304,8 +2307,7 @@ public: /** Can be set by handler to describe why a given operation cannot be done in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done - online (HA_ALTER_INPLACE_NO_LOCK or - HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE) + online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_COPY_NO_LOCK) If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if results from handler::check_if_supported_inplace_alter() doesn't match requirements set by user. If not set, the more generic @@ -2353,7 +2355,7 @@ public: replace not_supported with. */ void report_unsupported_error(const char *not_supported, - const char *try_instead); + const char *try_instead) const; }; @@ -4060,8 +4062,8 @@ public: *) As the first step, we acquire a lock corresponding to the concurrency level which was returned by handler::check_if_supported_inplace_alter() and requested by the user. This lock is held for most of the - duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE - or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an + duration of in-place ALTER (if HA_ALTER_INPLACE_COPY_LOCK + or HA_ALTER_INPLACE_COPY_NO_LOCK were returned we acquire an exclusive lock for duration of the next step only). *) After that we call handler::ha_prepare_inplace_alter_table() to give the storage engine a chance to update its internal structures with a higher @@ -4105,12 +4107,12 @@ public: @retval HA_ALTER_ERROR Unexpected error. @retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported, must use copy. @retval HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock. - @retval HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE + @retval HA_ALTER_INPLACE_COPY_LOCK Supported, but requires SNW lock during main phase. Prepare phase requires X lock. @retval HA_ALTER_INPLACE_SHARED_LOCK Supported, but requires SNW lock. - @retval HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE + @retval HA_ALTER_INPLACE_COPY_NO_LOCK Supported, concurrent reads/writes allowed. However, prepare phase requires X lock. @@ -4170,10 +4172,9 @@ protected: /** Allows the storage engine to update internal structures with concurrent writes blocked. If check_if_supported_inplace_alter() returns - HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE or - HA_ALTER_INPLACE_SHARED_AFTER_PREPARE, this function is called with - exclusive lock otherwise the same level of locking as for - inplace_alter_table() will be used. + HA_ALTER_INPLACE_COPY_NO_LOCK or HA_ALTER_INPLACE_COPY_LOCK, + this function is called with exclusive lock otherwise the same level + of locking as for inplace_alter_table() will be used. @note Storage engines are responsible for reporting any errors by calling my_error()/print_error() @@ -4271,7 +4272,7 @@ protected: @note No errors are allowed during notify_table_changed(). */ - virtual void notify_table_changed(); + virtual void notify_table_changed() { } public: /* End of On-line/in-place ALTER TABLE interface. */ diff --git a/sql/hostname.cc b/sql/hostname.cc index 2d39a8bb03d..00c780d9f35 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -460,7 +460,7 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage, entry->m_last_seen= now; *connect_errors= entry->m_errors.m_connect; - if (entry->m_errors.m_connect >= max_connect_errors) + if (unlikely(entry->m_errors.m_connect >= max_connect_errors)) { entry->m_errors.m_host_blocked++; entry->set_error_timestamps(now); diff --git a/sql/item.cc b/sql/item.cc index c19ad32f6ce..b07d959375b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -295,7 +295,7 @@ longlong Item::val_int_signed_typecast_from_str() { int error; longlong value= val_int_from_str(&error); - if (!null_value && value < 0 && error == 0) + if (unlikely(!null_value && value < 0 && error == 0)) push_note_converted_to_negative_complement(current_thd); return value; } @@ -305,7 +305,7 @@ longlong Item::val_int_unsigned_typecast_from_str() { int error; longlong value= val_int_from_str(&error); - if (!null_value && error < 0) + if (unlikely(!null_value && error < 0)) push_note_converted_to_positive_complement(current_thd); return value; } @@ -508,6 +508,8 @@ Item::Item(THD *thd): marker= 0; maybe_null=null_value=with_sum_func=with_window_func=with_field=0; in_rollup= 0; + with_param= 0; + /* Initially this item is not attached to any JOIN_TAB. */ join_tab_idx= MAX_TABLES; @@ -549,6 +551,7 @@ Item::Item(THD *thd, Item *item): in_rollup(item->in_rollup), null_value(item->null_value), with_sum_func(item->with_sum_func), + with_param(item->with_param), with_window_func(item->with_window_func), with_field(item->with_field), fixed(item->fixed), @@ -703,12 +706,11 @@ Item* Item::set_expr_cache(THD *thd) { DBUG_ENTER("Item::set_expr_cache"); Item_cache_wrapper *wrapper; - if ((wrapper= new (thd->mem_root) Item_cache_wrapper(thd, this)) && - !wrapper->fix_fields(thd, (Item**)&wrapper)) + if (likely((wrapper= new (thd->mem_root) Item_cache_wrapper(thd, this))) && + likely(!wrapper->fix_fields(thd, (Item**)&wrapper))) { - if (wrapper->set_cache(thd)) - DBUG_RETURN(NULL); - DBUG_RETURN(wrapper); + if (likely(!wrapper->set_cache(thd))) + DBUG_RETURN(wrapper); } DBUG_RETURN(NULL); } @@ -1307,7 +1309,7 @@ Item *Item_cache::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) return this; Item_cache *cache; if (!conv || conv->fix_fields(thd, (Item **) NULL) || - !(cache= new (thd->mem_root) Item_cache_str(thd, conv))) + unlikely(!(cache= new (thd->mem_root) Item_cache_str(thd, conv)))) return NULL; // Safe conversion is not possible, or OEM cache->setup(thd, conv); cache->fixed= false; // Make Item::fix_fields() happy @@ -1389,7 +1391,7 @@ Item *Item::const_charset_converter(THD *thd, CHARSET_INFO *tocs, collation.derivation, collation.repertoire)); - if (!conv || (conv_errors && lossless)) + if (unlikely(!conv || (conv_errors && lossless))) { /* Safe conversion is not possible (or EOM). @@ -1688,6 +1690,9 @@ bool Item_sp_variable::fix_fields_from_item(THD *thd, Item **, const Item *it) max_length= it->max_length; decimals= it->decimals; unsigned_flag= it->unsigned_flag; + with_param= 1; + if (thd->lex->current_select && thd->lex->current_select->master_unit()->item) + thd->lex->current_select->master_unit()->item->with_param= 1; fixed= 1; collation.set(it->collation.collation, it->collation.derivation); @@ -2760,13 +2765,13 @@ bool Type_std_attributes::agg_item_set_converter(const DTCollation &coll, Item* Item_func_or_sum::build_clone(THD *thd) { Item_func_or_sum *copy= (Item_func_or_sum *) get_copy(thd); - if (!copy) + if (unlikely(!copy)) return 0; if (arg_count > 2) { copy->args= (Item**) alloc_root(thd->mem_root, sizeof(Item*) * arg_count); - if (!copy->args) + if (unlikely(!copy->args)) return 0; } else if (arg_count > 0) @@ -2797,6 +2802,17 @@ Item_sp::Item_sp(THD *thd, Name_resolution_context *context_arg, memset(&sp_mem_root, 0, sizeof(sp_mem_root)); } +Item_sp::Item_sp(THD *thd, Item_sp *item): + context(item->context), m_name(item->m_name), + m_sp(item->m_sp), func_ctx(NULL), sp_result_field(NULL) +{ + dummy_table= (TABLE*) thd->calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE) + + sizeof(Query_arena)); + dummy_table->s= (TABLE_SHARE*) (dummy_table+1); + sp_query_arena= (Query_arena *) (dummy_table->s + 1); + memset(&sp_mem_root, 0, sizeof(sp_mem_root)); +} + const char * Item_sp::func_name(THD *thd) const { @@ -2863,7 +2879,7 @@ Item_sp::sp_check_access(THD *thd) */ bool Item_sp::execute(THD *thd, bool *null_value, Item **args, uint arg_count) { - if (execute_impl(thd, args, arg_count)) + if (unlikely(execute_impl(thd, args, arg_count))) { *null_value= 1; context->process_error(thd); @@ -2905,7 +2921,7 @@ Item_sp::execute_impl(THD *thd, Item **args, uint arg_count) thd->security_ctx= context->security_ctx; } - if (sp_check_access(thd)) + if (unlikely(sp_check_access(thd))) { thd->security_ctx= save_security_ctx; DBUG_RETURN(TRUE); @@ -2916,10 +2932,10 @@ Item_sp::execute_impl(THD *thd, Item **args, uint arg_count) statement-based replication (SBR) is active. */ - if (!m_sp->detistic() && !trust_function_creators && - (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) && - (mysql_bin_log.is_open() && - thd->variables.binlog_format == BINLOG_FORMAT_STMT)) + if (unlikely(!m_sp->detistic() && !trust_function_creators && + (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) && + (mysql_bin_log.is_open() && + thd->variables.binlog_format == BINLOG_FORMAT_STMT))) { my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0)); thd->security_ctx= save_security_ctx; @@ -3049,9 +3065,10 @@ Item_sp::init_result_field(THD *thd, uint max_length, uint maybe_null, Item* Item_ref::build_clone(THD *thd) { Item_ref *copy= (Item_ref *) get_copy(thd); - if (!copy || - !(copy->ref= (Item**) alloc_root(thd->mem_root, sizeof(Item*))) || - !(*copy->ref= (* ref)->build_clone(thd))) + if (unlikely(!copy) || + unlikely(!(copy->ref= (Item**) alloc_root(thd->mem_root, + sizeof(Item*)))) || + unlikely(!(*copy->ref= (* ref)->build_clone(thd)))) return 0; return copy; } @@ -3165,72 +3182,16 @@ Item_field::Item_field(THD *thd, Item_field *item) } -/** - Calculate the max column length not taking into account the - limitations over integer types. - - When storing data into fields the server currently just ignores the - limits specified on integer types, e.g. 1234 can safely be stored in - an int(2) and will not cause an error. - Thus when creating temporary tables and doing transformations - we must adjust the maximum field length to reflect this fact. - We take the un-restricted maximum length and adjust it similarly to - how the declared length is adjusted wrt unsignedness etc. - TODO: this all needs to go when we disable storing 1234 in int(2). - - @param field_par Original field the use to calculate the lengths - @param max_length Item's calculated explicit max length - @return The adjusted max length -*/ - -inline static uint32 -adjust_max_effective_column_length(Field *field_par, uint32 max_length) -{ - uint32 new_max_length= field_par->max_display_length(); - uint32 sign_length= (field_par->flags & UNSIGNED_FLAG) ? 0 : 1; - - switch (field_par->type()) - { - case MYSQL_TYPE_INT24: - /* - Compensate for MAX_MEDIUMINT_WIDTH being 1 too long (8) - compared to the actual number of digits that can fit into - the column. - */ - new_max_length+= 1; - /* fall through */ - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - - /* Take out the sign and add a conditional sign */ - new_max_length= new_max_length - 1 + sign_length; - break; - - /* BINGINT is always 20 no matter the sign */ - case MYSQL_TYPE_LONGLONG: - /* make gcc happy */ - default: - break; - } - - /* Adjust only if the actual precision based one is bigger than specified */ - return new_max_length > max_length ? new_max_length : max_length; -} - - void Item_field::set_field(Field *field_par) { field=result_field=field_par; // for easy coding with fields maybe_null=field->maybe_null(); - Type_std_attributes::set(field_par); + Type_std_attributes::set(field_par->type_std_attributes()); table_name= *field_par->table_name; field_name= field_par->field_name; db_name= field_par->table->s->db.str; alias_name_used= field_par->table->alias_name_used; - max_length= adjust_max_effective_column_length(field_par, max_length); - fixed= 1; if (field->table->s->tmp_table == SYSTEM_TMP_TABLE) any_privileges= 0; @@ -4269,7 +4230,7 @@ bool Item_param::set_str(const char *str, ulong length, been written to the binary log. */ uint dummy_errors; - if (value.m_string.copy(str, length, fromcs, tocs, &dummy_errors)) + if (unlikely(value.m_string.copy(str, length, fromcs, tocs, &dummy_errors))) DBUG_RETURN(TRUE); /* Set str_value_ptr to make sure it's in sync with str_value. @@ -6208,7 +6169,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) Field *new_field= (*((Item_field**)res))->field; - if (new_field == NULL) + if (unlikely(new_field == NULL)) { /* The column to which we link isn't valid. */ my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name.str, @@ -6253,7 +6214,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) } } - if (!select) + if (unlikely(!select)) { my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where); goto error; @@ -6407,19 +6368,15 @@ error: return TRUE; } - -/* - @brief - Mark virtual columns as used in a partitioning expression -*/ - -bool Item_field::vcol_in_partition_func_processor(void *int_arg) +bool Item_field::post_fix_fields_part_expr_processor(void *int_arg) { DBUG_ASSERT(fixed); if (field->vcol_info) - { field->vcol_info->mark_as_in_partitioning_expr(); - } + /* + Update table_name to be real table name, not the alias. Because alias is + reallocated for every statement, and this item has a long life time */ + table_name= field->table->s->table_name.str; return FALSE; } @@ -6661,7 +6618,7 @@ String *Item::check_well_formed_result(String *str, bool send_error) CHARSET_INFO *cs= str->charset(); uint wlen= str->well_formed_length(); null_value= false; - if (wlen < str->length()) + if (unlikely(wlen < str->length())) { THD *thd= current_thd; char hexbuf[7]; @@ -6700,9 +6657,10 @@ String_copier_for_item::copy_with_warn(CHARSET_INFO *dstcs, String *dst, CHARSET_INFO *srccs, const char *src, uint32 src_length, uint32 nchars) { - if ((dst->copy(dstcs, srccs, src, src_length, nchars, this))) + if (unlikely((dst->copy(dstcs, srccs, src, src_length, nchars, this)))) return true; // EOM - if (const char *pos= well_formed_error_pos()) + const char *pos; + if (unlikely(pos= well_formed_error_pos())) { ErrConvString err(pos, src_length - (pos - src), &my_charset_bin); push_warning_printf(m_thd, Sql_condition::WARN_LEVEL_WARN, @@ -6713,7 +6671,7 @@ String_copier_for_item::copy_with_warn(CHARSET_INFO *dstcs, String *dst, err.ptr()); return false; } - if (const char *pos= cannot_convert_error_pos()) + if (unlikely(pos= cannot_convert_error_pos())) { char buf[16]; int mblen= my_charlen(srccs, pos, src + src_length); @@ -6846,6 +6804,11 @@ fast_field_copier Item_field::setup_fast_field_copier(Field *to) return to->get_fast_field_copier(field); } +void Item_field::save_in_result_field(bool no_conversions) +{ + bool unused; + save_field_in_field(field, &unused, result_field, no_conversions); +} /** Set a field's value from a item. @@ -7236,7 +7199,7 @@ Item_float::Item_float(THD *thd, const char *str_arg, size_t length): char *end_not_used; value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used, &error); - if (error) + if (unlikely(error)) { char tmp[NAME_LEN + 1]; my_snprintf(tmp, sizeof(tmp), "%.*s", (int)length, str_arg); @@ -8209,7 +8172,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) Field *from_field; ref= 0; - if (!outer_context) + if (unlikely(!outer_context)) { /* The current reference cannot be resolved in this query. */ my_error(ER_BAD_FIELD_ERROR,MYF(0), @@ -8357,7 +8320,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) last_checked_context->select_lex->nest_level); return FALSE; } - if (ref == 0) + if (unlikely(ref == 0)) { /* The item was not a table field and not a reference */ my_error(ER_BAD_FIELD_ERROR, MYF(0), @@ -8423,6 +8386,7 @@ void Item_ref::set_properties() split_sum_func() doesn't try to change the reference. */ with_sum_func= (*ref)->with_sum_func; + with_param= (*ref)->with_param; with_window_func= (*ref)->with_window_func; with_field= (*ref)->with_field; fixed= 1; @@ -8848,6 +8812,7 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg): Type_std_attributes::set(orig_item); maybe_null= orig_item->maybe_null; with_sum_func= orig_item->with_sum_func; + with_param= orig_item->with_param; with_field= orig_item->with_field; name= item_arg->name; m_with_subquery= orig_item->with_subquery(); @@ -9781,7 +9746,7 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) if (arg->type() == REF_ITEM) arg= static_cast<Item_ref *>(arg)->ref[0]; - if (arg->type() != FIELD_ITEM) + if (unlikely(arg->type() != FIELD_ITEM)) { my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); return TRUE; @@ -9803,10 +9768,10 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) } else { - Field *tmp_field= field_arg->field; - /* charset doesn't matter here, it's to avoid sigsegv only */ - tmp_field= new Field_null(0, 0, Field::NONE, &field_arg->field->field_name, - &my_charset_bin); + static uchar null_bit=1; + /* charset doesn't matter here */ + Field *tmp_field= new Field_string(0, 0, &null_bit, 1, Field::NONE, + &field_arg->field->field_name, &my_charset_bin); if (tmp_field) { tmp_field->init(field_arg->field->table); @@ -9930,7 +9895,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items) /* Set field. */ - if (field_idx != (uint)-1) + if (likely(field_idx != (uint)-1)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS /* @@ -10980,11 +10945,6 @@ Item_field::excl_dep_on_grouping_fields(st_select_lex *sel) return find_matching_grouping_field(this, sel) != NULL; } -bool Item_field::vers_trx_id() const -{ - DBUG_ASSERT(field); - return field->vers_trx_id(); -} void Item::register_in(THD *thd) { diff --git a/sql/item.h b/sql/item.h index 117c6b5c6d5..c8ec16ab836 100644 --- a/sql/item.h +++ b/sql/item.h @@ -370,11 +370,37 @@ typedef enum monotonicity_info class sp_rcontext; +/** + A helper class to collect different behavior of various kinds of SP variables: + - local SP variables and SP parameters + - PACKAGE BODY routine variables + - (there will be more kinds in the future) +*/ + class Sp_rcontext_handler { public: virtual ~Sp_rcontext_handler() {} + /** + A prefix used for SP variable names in queries: + - EXPLAIN EXTENDED + - SHOW PROCEDURE CODE + Local variables and SP parameters have empty prefixes. + Package body variables are marked with a special prefix. + This improves readability of the output of these queries, + especially when a local variable or a parameter has the same + name with a package body variable. + */ virtual const LEX_CSTRING *get_name_prefix() const= 0; + /** + At execution time THD->spcont points to the run-time context (sp_rcontext) + of the currently executed routine. + Local variables store their data in the sp_rcontext pointed by thd->spcont. + Package body variables store data in separate sp_rcontext that belongs + to the package. + This method provides access to the proper sp_rcontext structure, + depending on the SP variable kind. + */ virtual sp_rcontext *get_rcontext(sp_rcontext *ctx) const= 0; }; @@ -804,6 +830,12 @@ protected: value= NULL; return value; } + bool get_date_from_item(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) + { + bool rc= item->get_date(ltime, fuzzydate); + null_value= MY_TEST(rc || item->null_value); + return rc; + } /* This method is used if the item was not null but convertion to TIME/DATE/DATETIME failed. We return a zero date if allowed, @@ -837,6 +869,7 @@ public: of a query with ROLLUP */ bool null_value; /* if item is null */ bool with_sum_func; /* True if item contains a sum func */ + bool with_param; /* True if contains an SP parameter */ bool with_window_func; /* True if item contains a window func */ /** True if any item except Item_sum contains a field. Set during parsing. @@ -949,6 +982,10 @@ public: { return type_handler(); } + virtual const Type_handler *type_handler_for_system_time() const + { + return real_type_handler(); + } /* result_type() of an item specifies how the value should be returned */ Item_result result_type() const { @@ -1647,6 +1684,7 @@ public: set field of temporary table for Item which can be switched on temporary table during query processing (grouping and so on) */ + virtual void set_result_field(Field *field) {} virtual bool is_result_field() { return 0; } virtual bool is_json_type() { return false; } virtual bool is_bool_literal() const { return false; } @@ -1819,7 +1857,7 @@ public: fields. */ virtual bool check_partition_func_processor(void *arg) { return 1;} - virtual bool vcol_in_partition_func_processor(void *arg) { return 0; } + virtual bool post_fix_fields_part_expr_processor(void *arg) { return 0; } virtual bool rename_fields_processor(void *arg) { return 0; } /** Processor used to check acceptability of an item in the defining expression for a virtual column @@ -1936,8 +1974,6 @@ public: const Tmp_field_param *param)= 0; virtual Item_field *field_for_view_update() { return 0; } - virtual bool vers_trx_id() const - { return false; } virtual Item *neg_transformer(THD *thd) { return NULL; } virtual Item *update_value_transformer(THD *thd, uchar *select_arg) { return this; } @@ -2184,7 +2220,7 @@ template <class T> inline Item* get_item_copy (THD *thd, T* item) { Item *copy= new (get_thd_memroot(thd)) T(*item); - if (copy) + if (likely(copy)) copy->register_in(thd); return copy; } @@ -2332,7 +2368,7 @@ public: Item_args(THD *thd, Item *a, Item *b, Item *c) { arg_count= 0; - if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 3))) + if (likely((args= (Item**) thd_alloc(thd, sizeof(Item*) * 3)))) { arg_count= 3; args[0]= a; args[1]= b; args[2]= c; @@ -2341,7 +2377,7 @@ public: Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d) { arg_count= 0; - if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 4))) + if (likely((args= (Item**) thd_alloc(thd, sizeof(Item*) * 4)))) { arg_count= 4; args[0]= a; args[1]= b; args[2]= c; args[3]= d; @@ -2350,7 +2386,7 @@ public: Item_args(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e) { arg_count= 5; - if ((args= (Item**) thd_alloc(thd, sizeof(Item*) * 5))) + if (likely((args= (Item**) thd_alloc(thd, sizeof(Item*) * 5)))) { arg_count= 5; args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e; @@ -2676,7 +2712,7 @@ public: based on result_type(), which is less exact. */ Field *create_field_for_create_select(TABLE *table) - { return tmp_table_field_from_field_type(table); } + { return create_table_field_from_handler(table); } bool is_valid_limit_clause_variable_with_error() const { @@ -2930,6 +2966,7 @@ public: return table map of the temporary table. */ table_map used_tables() const { return 1; } + void set_result_field(Field *field) { result_field= field; } bool is_result_field() { return true; } void save_in_result_field(bool no_conversions) { @@ -3019,7 +3056,7 @@ public: const char *table_name_arg): Item(thd), field(par_field), db_name(db_arg), table_name(table_name_arg) { - Type_std_attributes::set(par_field); + Type_std_attributes::set(par_field->type_std_attributes()); } enum Type type() const { return FIELD_ITEM; } Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src, @@ -3149,10 +3186,6 @@ public: Field *create_tmp_field_ex(TABLE *table, Tmp_field_src *src, const Tmp_field_param *param); TYPELIB *get_typelib() const { return field->get_typelib(); } - uint32 field_flags() const - { - return field->flags; - } enum_monotonicity_info get_monotonicity_info() const { return MONOTONIC_STRICT_INCREASING; @@ -3204,7 +3237,7 @@ public: cond_equal_ref); } bool is_result_field() { return false; } - void save_in_result_field(bool no_conversions) { } + void save_in_result_field(bool no_conversions); Item *get_tmp_table_item(THD *thd); bool collect_item_field_processor(void * arg); bool add_field_to_set_processor(void * arg); @@ -3213,7 +3246,7 @@ public: bool register_field_in_write_map(void *arg); bool register_field_in_bitmap(void *arg); bool check_partition_func_processor(void *int_arg) {return FALSE;} - bool vcol_in_partition_func_processor(void *bool_arg); + bool post_fix_fields_part_expr_processor(void *bool_arg); bool check_valid_arguments_processor(void *bool_arg); bool check_field_expression_processor(void *arg); bool enumerate_field_refs_processor(void *arg); @@ -3249,7 +3282,6 @@ public: uint32 max_display_length() const { return field->max_display_length(); } Item_field *field_for_view_update() { return this; } int fix_outer_field(THD *thd, Field **field, Item **reference); - virtual bool vers_trx_id() const; virtual Item *update_value_transformer(THD *thd, uchar *select_arg); Item *derived_field_transformer_for_having(THD *thd, uchar *arg); Item *derived_field_transformer_for_where(THD *thd, uchar *arg); @@ -4444,7 +4476,7 @@ public: { // following assert is redundant, because fixed=1 assigned in constructor DBUG_ASSERT(fixed == 1); - ulonglong value= (ulonglong) Item_hex_hybrid::val_int(); + longlong value= Item_hex_hybrid::val_int(); int2my_decimal(E_DEC_FATAL_ERROR, value, TRUE, decimal_value); return decimal_value; } @@ -4457,6 +4489,10 @@ public: { return &type_handler_longlong; } + const Type_handler *type_handler_for_system_time() const + { + return &type_handler_longlong; + } void print(String *str, enum_query_type query_type); Item *get_copy(THD *thd) { return get_item_copy<Item_hex_hybrid>(thd, this); } @@ -4889,6 +4925,7 @@ public: */ Field *sp_result_field; Item_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name_arg); + Item_sp(THD *thd, Item_sp *item); const char *func_name(THD *thd) const; void cleanup(); bool sp_check_access(THD *thd); @@ -5121,12 +5158,6 @@ public: return 0; return cleanup_processor(arg); } - virtual bool vers_trx_id() const - { - DBUG_ASSERT(ref); - DBUG_ASSERT(*ref); - return (*ref)->vers_trx_id(); - } }; @@ -6635,29 +6666,14 @@ class Item_type_holder: public Item, { protected: TYPELIB *enum_set_typelib; -private: - void init_flags(Item *item) - { - if (item->real_type() == Item::FIELD_ITEM) - { - Item_field *item_field= (Item_field *)item->real_item(); - m_flags|= (item_field->field->flags & - (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG)); - // TODO: additional field flag? - m_vers_trx_id= item_field->field->vers_trx_id(); - } - } public: Item_type_holder(THD *thd, Item *item) :Item(thd, item), Type_handler_hybrid_field_type(item->real_type_handler()), - enum_set_typelib(0), - m_flags(0), - m_vers_trx_id(false) + enum_set_typelib(0) { DBUG_ASSERT(item->fixed); maybe_null= item->maybe_null; - init_flags(item); } Item_type_holder(THD *thd, Item *item, @@ -6667,27 +6683,20 @@ public: :Item(thd), Type_handler_hybrid_field_type(handler), Type_geometry_attributes(handler, attr), - enum_set_typelib(attr->get_typelib()), - m_flags(0), - m_vers_trx_id(false) + enum_set_typelib(attr->get_typelib()) { name= item->name; Type_std_attributes::set(*attr); maybe_null= maybe_null_arg; - init_flags(item); } const Type_handler *type_handler() const { - const Type_handler *handler= m_vers_trx_id ? - &type_handler_vers_trx_id : - Type_handler_hybrid_field_type::type_handler(); - return handler->type_handler_for_item_field(); + return Type_handler_hybrid_field_type::type_handler()-> + type_handler_for_item_field(); } const Type_handler *real_type_handler() const { - if (m_vers_trx_id) - return &type_handler_vers_trx_id; return Type_handler_hybrid_field_type::type_handler(); } @@ -6715,18 +6724,6 @@ public: } Item* get_copy(THD *thd) { return 0; } -private: - uint m_flags; - bool m_vers_trx_id; -public: - uint32 field_flags() const - { - return m_flags; - } - virtual bool vers_trx_id() const - { - return m_vers_trx_id; - } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ba503f18855..76f4788c1cf 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -126,12 +126,9 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const char *funcname, many cases. */ set_handler(items[0]->type_handler()->type_handler_for_comparison()); - m_vers_trx_id= items[0]->vers_trx_id(); for (uint i= 1 ; i < nitems ; i++) { unsigned_count+= items[i]->unsigned_flag; - if (!m_vers_trx_id) - m_vers_trx_id= items[i]->vers_trx_id(); if (aggregate_for_comparison(items[i]->type_handler()-> type_handler_for_comparison())) { @@ -423,7 +420,8 @@ void Item_func::convert_const_compared_to_int_field(THD *thd) args[field= 1]->real_item()->type() == FIELD_ITEM) { Item_field *field_item= (Item_field*) (args[field]->real_item()); - if (((field_item->field_type() == MYSQL_TYPE_LONGLONG && !field_item->vers_trx_id()) || + if (((field_item->field_type() == MYSQL_TYPE_LONGLONG && + field_item->type_handler() != &type_handler_vers_trx_id) || field_item->field_type() == MYSQL_TYPE_YEAR)) convert_const_to_int(thd, field_item, &args[!field]); } @@ -1294,6 +1292,7 @@ bool Item_in_optimizer::fix_left(THD *thd) } eval_not_null_tables(NULL); with_sum_func= args[0]->with_sum_func; + with_param= args[0]->with_param || args[1]->with_param; with_field= args[0]->with_field; if ((const_item_cache= args[0]->const_item())) { @@ -1342,6 +1341,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref) m_with_subquery= true; with_sum_func= with_sum_func || args[1]->with_sum_func; with_field= with_field || args[1]->with_field; + with_param= args[0]->with_param || args[1]->with_param; used_tables_and_const_cache_join(args[1]); fixed= 1; return FALSE; @@ -1891,6 +1891,7 @@ void Item_func_interval::fix_length_and_dec() used_tables_and_const_cache_join(row); not_null_tables_cache= row->not_null_tables(); with_sum_func= with_sum_func || row->with_sum_func; + with_param= with_param || row->with_param; with_field= with_field || row->with_field; } @@ -2831,7 +2832,7 @@ Item_func_nullif::time_op(MYSQL_TIME *ltime) bool Item_func_nullif::is_null() { - return (null_value= (!compare() ? 1 : args[2]->null_value)); + return (null_value= (!compare() ? 1 : args[2]->is_null())); } void Item_func_case::reorder_args(uint start) @@ -4304,7 +4305,7 @@ bool cmp_item_row::prepare_comparators(THD *thd, Item **args, uint arg_count) bool Item_func_in::fix_for_row_comparison_using_bisection(THD *thd) { uint cols= args[0]->cols(); - if (!(array= new (thd->mem_root) in_row(thd, arg_count-1, 0))) + if (unlikely(!(array= new (thd->mem_root) in_row(thd, arg_count-1, 0)))) return true; cmp_item_row *cmp= &((in_row*)array)->tmp; if (cmp->alloc_comparators(thd, cols) || @@ -4315,7 +4316,7 @@ bool Item_func_in::fix_for_row_comparison_using_bisection(THD *thd) Call store_value() to setup others. */ cmp->store_value(args[0]); - if (thd->is_fatal_error) // OOM + if (unlikely(thd->is_fatal_error)) // OOM return true; fix_in_vector(); return false; @@ -4528,6 +4529,7 @@ Item_cond::fix_fields(THD *thd, Item **ref) List_iterator<Item> li(list); Item *item; uchar buff[sizeof(char*)]; // Max local vars in function + longlong is_and_cond= functype() == Item_func::COND_AND_FUNC; not_null_tables_cache= 0; used_tables_and_const_cache_init(); @@ -4590,26 +4592,33 @@ Item_cond::fix_fields(THD *thd, Item **ref) (item= *li.ref())->check_cols(1)) return TRUE; /* purecov: inspected */ used_tables_cache|= item->used_tables(); - if (item->const_item()) + if (item->const_item() && !item->with_param && + !item->is_expensive() && !cond_has_datetime_is_null(item)) { - if (!item->is_expensive() && !cond_has_datetime_is_null(item) && - item->val_int() == 0) + if (item->val_int() == is_and_cond && top_level()) { /* - This is "... OR false_cond OR ..." + a. This is "... AND true_cond AND ..." + In this case, true_cond has no effect on cond_and->not_null_tables() + b. This is "... OR false_cond/null cond OR ..." In this case, false_cond has no effect on cond_or->not_null_tables() */ } else { /* - This is "... OR const_cond OR ..." + a. This is "... AND false_cond/null_cond AND ..." + The whole condition is FALSE/UNKNOWN. + b. This is "... OR const_cond OR ..." In this case, cond_or->not_null_tables()=0, because the condition const_cond might evaluate to true (regardless of whether some tables were NULL-complemented). */ + not_null_tables_cache= (table_map) 0; and_tables_cache= (table_map) 0; } + if (thd->is_error()) + return TRUE; } else { @@ -4621,6 +4630,7 @@ Item_cond::fix_fields(THD *thd, Item **ref) } with_sum_func|= item->with_sum_func; + with_param|= item->with_param; with_field|= item->with_field; m_with_subquery|= item->with_subquery(); with_window_func|= item->with_window_func; @@ -4636,30 +4646,36 @@ bool Item_cond::eval_not_null_tables(void *opt_arg) { Item *item; + longlong is_and_cond= functype() == Item_func::COND_AND_FUNC; List_iterator<Item> li(list); not_null_tables_cache= (table_map) 0; and_tables_cache= ~(table_map) 0; while ((item=li++)) { table_map tmp_table_map; - if (item->const_item()) + if (item->const_item() && !item->with_param && + !item->is_expensive() && !cond_has_datetime_is_null(item)) { - if (!item->is_expensive() && !cond_has_datetime_is_null(item) && - item->val_int() == 0) + if (item->val_int() == is_and_cond && top_level()) { /* - This is "... OR false_cond OR ..." + a. This is "... AND true_cond AND ..." + In this case, true_cond has no effect on cond_and->not_null_tables() + b. This is "... OR false_cond/null cond OR ..." In this case, false_cond has no effect on cond_or->not_null_tables() */ } else { /* - This is "... OR const_cond OR ..." + a. This is "... AND false_cond/null_cond AND ..." + The whole condition is FALSE/UNKNOWN. + b. This is "... OR const_cond OR ..." In this case, cond_or->not_null_tables()=0, because the condition - some_cond_or might be true regardless of what tables are - NULL-complemented. + const_cond might evaluate to true (regardless of whether some tables + were NULL-complemented). */ + not_null_tables_cache= (table_map) 0; and_tables_cache= (table_map) 0; } } @@ -5439,7 +5455,7 @@ bool Regexp_processor_pcre::compile(String *pattern, bool send_error) m_pcre= pcre_compile(pattern->c_ptr_safe(), m_library_flags, &pcreErrorStr, &pcreErrorOffset, NULL); - if (m_pcre == NULL) + if (unlikely(m_pcre == NULL)) { if (send_error) { @@ -5458,7 +5474,7 @@ bool Regexp_processor_pcre::compile(Item *item, bool send_error) char buff[MAX_FIELD_WIDTH]; String tmp(buff, sizeof(buff), &my_charset_bin); String *pattern= item->val_str(&tmp); - if (item->null_value || compile(pattern, send_error)) + if (unlikely(item->null_value) || (unlikely(compile(pattern, send_error)))) return true; return false; } @@ -5577,7 +5593,7 @@ int Regexp_processor_pcre::pcre_exec_with_warn(const pcre *code, int rc= pcre_exec(code, extra, subject, length, startoffset, options, ovector, ovecsize); DBUG_EXECUTE_IF("pcre_exec_error_123", rc= -123;); - if (rc < PCRE_ERROR_NOMATCH) + if (unlikely(rc < PCRE_ERROR_NOMATCH)) pcre_exec_warn(rc); return rc; } @@ -5857,8 +5873,8 @@ void Item_func_like::turboBM_compute_bad_character_shifts() bool Item_func_like::turboBM_matches(const char* text, int text_len) const { - register int bcShift; - register int turboShift; + int bcShift; + int turboShift; int shift = pattern_len; int j = 0; int u = 0; @@ -5872,7 +5888,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const { while (j <= tlmpl) { - register int i= plm1; + int i= plm1; while (i >= 0 && pattern[i] == text[i + j]) { i--; @@ -5882,7 +5898,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const if (i < 0) return 1; - register const int v = plm1 - i; + const int v= plm1 - i; turboShift = u - v; bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i; shift = MY_MAX(turboShift, bcShift); @@ -5903,7 +5919,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const { while (j <= tlmpl) { - register int i = plm1; + int i= plm1; while (i >= 0 && likeconv(cs,pattern[i]) == likeconv(cs,text[i + j])) { i--; @@ -5913,7 +5929,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const if (i < 0) return 1; - register const int v = plm1 - i; + const int v= plm1 - i; turboShift = u - v; bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i; shift = MY_MAX(turboShift, bcShift); diff --git a/sql/item_create.cc b/sql/item_create.cc index 901dfa06f40..ab91e378be3 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -3313,7 +3313,7 @@ Create_qfunc::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) { LEX_CSTRING db; - if (! thd->db.str && ! thd->lex->sphead) + if (unlikely(! thd->db.str && ! thd->lex->sphead)) { /* The proper error message should be in the lines of: @@ -3462,7 +3462,7 @@ Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, const Sp_handler *sph= &sp_handler_function; Database_qualified_name pkgname(&null_clex_str, &null_clex_str); - if (has_named_parameters(item_list)) + if (unlikely(has_named_parameters(item_list))) { /* The syntax "db.foo(expr AS p1, expr AS p2, ...) is invalid, @@ -3481,8 +3481,8 @@ Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, arg_count= item_list->elements; qname= new (thd->mem_root) sp_name(db, name, use_explicit_name); - if (sph->sp_resolve_package_routine(thd, thd->lex->sphead, - qname, &sph, &pkgname)) + if (unlikely(sph->sp_resolve_package_routine(thd, thd->lex->sphead, + qname, &sph, &pkgname))) return NULL; sph->add_used_routine(lex, thd, qname); if (pkgname.m_name.length) @@ -3502,7 +3502,7 @@ Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name, Item* Create_native_func::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list) { - if (has_named_parameters(item_list)) + if (unlikely(has_named_parameters(item_list))) { my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3520,7 +3520,7 @@ Create_func_arg0::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list if (item_list != NULL) arg_count= item_list->elements; - if (arg_count != 0) + if (unlikely(arg_count != 0)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3538,7 +3538,7 @@ Create_func_arg1::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list if (item_list) arg_count= item_list->elements; - if (arg_count != 1) + if (unlikely(arg_count != 1)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3546,7 +3546,7 @@ Create_func_arg1::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list Item *param_1= item_list->pop(); - if (! param_1->is_autogenerated_name) + if (unlikely(! param_1->is_autogenerated_name)) { my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3564,7 +3564,7 @@ Create_func_arg2::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list if (item_list) arg_count= item_list->elements; - if (arg_count != 2) + if (unlikely(arg_count != 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3573,8 +3573,8 @@ Create_func_arg2::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list Item *param_1= item_list->pop(); Item *param_2= item_list->pop(); - if ( (! param_1->is_autogenerated_name) - || (! param_2->is_autogenerated_name)) + if (unlikely(!param_1->is_autogenerated_name || + !param_2->is_autogenerated_name)) { my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3592,7 +3592,7 @@ Create_func_arg3::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list if (item_list) arg_count= item_list->elements; - if (arg_count != 3) + if (unlikely(arg_count != 3)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3602,9 +3602,9 @@ Create_func_arg3::create_func(THD *thd, LEX_CSTRING *name, List<Item> *item_list Item *param_2= item_list->pop(); Item *param_3= item_list->pop(); - if ( (! param_1->is_autogenerated_name) - || (! param_2->is_autogenerated_name) - || (! param_3->is_autogenerated_name)) + if (unlikely(!param_1->is_autogenerated_name || + !param_2->is_autogenerated_name || + !param_3->is_autogenerated_name)) { my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3765,7 +3765,7 @@ Item* Create_func_binlog_gtid_pos::create_2_arg(THD *thd, Item *arg1, Item *arg2) { #ifdef HAVE_REPLICATION - if (!mysql_bin_log.is_open()) + if (unlikely(!mysql_bin_log.is_open())) #endif { my_error(ER_NO_BINARY_LOGGING, MYF(0)); @@ -3903,7 +3903,7 @@ Create_func_concat::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 1) + if (unlikely(arg_count < 1)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3926,7 +3926,7 @@ Create_func_concat_operator_oracle::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 1) + if (unlikely(arg_count < 1)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3950,7 +3950,7 @@ Create_func_decode_oracle::create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list) { uint arg_count= item_list ? item_list->elements : 0; - if (arg_count < 3) + if (unlikely(arg_count < 3)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -3970,7 +3970,7 @@ Create_func_concat_ws::create_native(THD *thd, LEX_CSTRING *name, arg_count= item_list->elements; /* "WS" stands for "With Separator": this function takes 2+ arguments */ - if (arg_count < 2) + if (unlikely(arg_count < 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -4272,7 +4272,7 @@ Create_func_elt::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2) + if (unlikely(arg_count < 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -4468,7 +4468,7 @@ Create_func_field::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2) + if (unlikely(arg_count < 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -4841,7 +4841,7 @@ Create_func_greatest::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2) + if (unlikely(arg_count < 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -5118,6 +5118,7 @@ Create_func_json_exists Create_func_json_exists::s_singleton; Item* Create_func_json_exists::create_2_arg(THD *thd, Item *arg1, Item *arg2) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_exists(thd, arg1, arg2); } @@ -5134,7 +5135,7 @@ Create_func_json_detailed::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 1 || arg_count > 2 /* json_doc, [path]...*/) + if (unlikely(arg_count < 1 || arg_count > 2 /* json_doc, [path]...*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5143,6 +5144,7 @@ Create_func_json_detailed::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_format(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5152,6 +5154,7 @@ Create_func_json_loose Create_func_json_loose::s_singleton; Item* Create_func_json_loose::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_format(thd, arg1, Item_func_json_format::LOOSE); } @@ -5162,6 +5165,7 @@ Create_func_json_compact Create_func_json_compact::s_singleton; Item* Create_func_json_compact::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_format(thd, arg1, Item_func_json_format::COMPACT); } @@ -5172,6 +5176,7 @@ Create_func_json_valid Create_func_json_valid::s_singleton; Item* Create_func_json_valid::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_valid(thd, arg1); } @@ -5181,6 +5186,7 @@ Create_func_json_type Create_func_json_type::s_singleton; Item* Create_func_json_type::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_type(thd, arg1); } @@ -5190,6 +5196,7 @@ Create_func_json_depth Create_func_json_depth::s_singleton; Item* Create_func_json_depth::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_depth(thd, arg1); } @@ -5199,6 +5206,7 @@ Create_func_json_value Create_func_json_value::s_singleton; Item* Create_func_json_value::create_2_arg(THD *thd, Item *arg1, Item *arg2) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_value(thd, arg1, arg2); } @@ -5208,6 +5216,7 @@ Create_func_json_query Create_func_json_query::s_singleton; Item* Create_func_json_query::create_2_arg(THD *thd, Item *arg1, Item *arg2) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_query(thd, arg1, arg2); } @@ -5217,6 +5226,7 @@ Create_func_json_quote Create_func_json_quote::s_singleton; Item* Create_func_json_quote::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_quote(thd, arg1); } @@ -5226,6 +5236,7 @@ Create_func_json_unquote Create_func_json_unquote::s_singleton; Item* Create_func_json_unquote::create_1_arg(THD *thd, Item *arg1) { + status_var_increment(current_thd->status_var.feature_json); return new (thd->mem_root) Item_func_json_unquote(thd, arg1); } @@ -5256,6 +5267,7 @@ Create_func_json_array::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_array(thd); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5272,7 +5284,7 @@ Create_func_json_array_append::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 || (arg_count & 1) == 0 /*is even*/) + if (unlikely(arg_count < 3 || (arg_count & 1) == 0 /*is even*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5281,6 +5293,7 @@ Create_func_json_array_append::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_array_append(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5297,7 +5310,7 @@ Create_func_json_array_insert::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 || (arg_count & 1) == 0 /*is even*/) + if (unlikely(arg_count < 3 || (arg_count & 1) == 0 /*is even*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5306,6 +5319,7 @@ Create_func_json_array_insert::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_array_insert(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5322,7 +5336,7 @@ Create_func_json_insert::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 || (arg_count & 1) == 0 /*is even*/) + if (unlikely(arg_count < 3 || (arg_count & 1) == 0 /*is even*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5332,6 +5346,7 @@ Create_func_json_insert::create_native(THD *thd, LEX_CSTRING *name, thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5348,7 +5363,7 @@ Create_func_json_set::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 || (arg_count & 1) == 0 /*is even*/) + if (unlikely(arg_count < 3 || (arg_count & 1) == 0 /*is even*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5358,6 +5373,7 @@ Create_func_json_set::create_native(THD *thd, LEX_CSTRING *name, thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5374,7 +5390,7 @@ Create_func_json_replace::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 || (arg_count & 1) == 0 /*is even*/) + if (unlikely(arg_count < 3 || (arg_count & 1) == 0 /*is even*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5384,6 +5400,7 @@ Create_func_json_replace::create_native(THD *thd, LEX_CSTRING *name, thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5400,7 +5417,7 @@ Create_func_json_remove::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2 /*json_doc, path [,path]*/) + if (unlikely(arg_count < 2 /*json_doc, path [,path]*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5409,6 +5426,7 @@ Create_func_json_remove::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_remove(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5425,7 +5443,7 @@ Create_func_json_object::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) { arg_count= item_list->elements; - if ((arg_count & 1) != 0 /*is odd*/) + if (unlikely((arg_count & 1) != 0 /*is odd*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); func= NULL; @@ -5441,6 +5459,7 @@ Create_func_json_object::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_object(thd); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5454,8 +5473,8 @@ Create_func_json_length::create_native(THD *thd, LEX_CSTRING *name, Item *func; int arg_count; - if (item_list == NULL || - (arg_count= item_list->elements) == 0) + if (unlikely(item_list == NULL || + (arg_count= item_list->elements) == 0)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); func= NULL; @@ -5465,6 +5484,7 @@ Create_func_json_length::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_length(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5478,8 +5498,8 @@ Create_func_json_merge::create_native(THD *thd, LEX_CSTRING *name, Item *func; int arg_count; - if (item_list == NULL || - (arg_count= item_list->elements) < 2) // json, json + if (unlikely(item_list == NULL || + (arg_count= item_list->elements) < 2)) // json, json { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); func= NULL; @@ -5489,6 +5509,7 @@ Create_func_json_merge::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_merge(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5505,7 +5526,7 @@ Create_func_json_contains::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count == 2 || arg_count == 3/* json_doc, val, [path] */) + if (unlikely(arg_count == 2 || arg_count == 3/* json_doc, val, [path] */)) { func= new (thd->mem_root) Item_func_json_contains(thd, *item_list); } @@ -5514,6 +5535,7 @@ Create_func_json_contains::create_native(THD *thd, LEX_CSTRING *name, my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5530,7 +5552,7 @@ Create_func_json_keys::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 1 || arg_count > 2 /* json_doc, [path]...*/) + if (unlikely(arg_count < 1 || arg_count > 2 /* json_doc, [path]...*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5539,6 +5561,7 @@ Create_func_json_keys::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_keys(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5555,7 +5578,7 @@ Create_func_json_contains_path::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 /* json_doc, one_or_all, path, [path]...*/) + if (unlikely(arg_count < 3 /* json_doc, one_or_all, path, [path]...*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5564,6 +5587,7 @@ Create_func_json_contains_path::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_contains_path(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5580,7 +5604,7 @@ Create_func_json_extract::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2 /* json_doc, path, [path]...*/) + if (unlikely(arg_count < 2 /* json_doc, path, [path]...*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5589,6 +5613,7 @@ Create_func_json_extract::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_extract(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5605,7 +5630,7 @@ Create_func_json_search::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 3 /* json_doc, one_or_all, search_str, [escape_char[, path]...*/) + if (unlikely(arg_count < 3 /* json_doc, one_or_all, search_str, [escape_char[, path]...*/)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); } @@ -5614,6 +5639,7 @@ Create_func_json_search::create_native(THD *thd, LEX_CSTRING *name, func= new (thd->mem_root) Item_func_json_search(thd, *item_list); } + status_var_increment(current_thd->status_var.feature_json); return func; } @@ -5675,7 +5701,7 @@ Create_func_least::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2) + if (unlikely(arg_count < 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -5953,7 +5979,7 @@ Create_func_make_set::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2) + if (unlikely(arg_count < 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return NULL; @@ -5978,7 +6004,7 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2 || arg_count > 4) + if (unlikely(arg_count < 2 || arg_count > 4)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return func; @@ -6028,7 +6054,7 @@ Create_func_master_gtid_wait::create_native(THD *thd, LEX_CSTRING *name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 1 || arg_count > 2) + if (unlikely(arg_count < 1 || arg_count > 2)) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); return func; @@ -7461,7 +7487,7 @@ Item *create_temporal_literal(THD *thd, DBUG_ASSERT(0); } - if (item) + if (likely(item)) { if (status.warnings) // e.g. a note on nanosecond truncation { @@ -7570,7 +7596,7 @@ Item *create_func_dyncol_get(THD *thd, Item *str, Item *num, { Item *res; - if (!(res= new (thd->mem_root) Item_dyncol_get(thd, str, num))) + if (likely(!(res= new (thd->mem_root) Item_dyncol_get(thd, str, num)))) return res; // Return NULL return handler->create_typecast_item(thd, res, Type_cast_attributes(c_len, c_dec, cs)); diff --git a/sql/item_func.cc b/sql/item_func.cc index e2740272385..c291e897957 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -62,9 +62,9 @@ bool check_reserved_words(const LEX_CSTRING *name) { - if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") || - !my_strcasecmp(system_charset_info, name->str, "LOCAL") || - !my_strcasecmp(system_charset_info, name->str, "SESSION")) + if (lex_string_eq(name, STRING_WITH_LEN("GLOBAL")) || + lex_string_eq(name, STRING_WITH_LEN("LOCAL")) || + lex_string_eq(name, STRING_WITH_LEN("SESSION"))) return TRUE; return FALSE; } @@ -148,6 +148,7 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list) with_sum_func|= item->with_sum_func; with_window_func|= item->with_window_func; with_field|= item->with_field; + with_param|= item->with_param; } } @@ -367,6 +368,7 @@ Item_func::fix_fields(THD *thd, Item **ref) maybe_null=1; with_sum_func= with_sum_func || item->with_sum_func; + with_param= with_param || item->with_param; with_window_func= with_window_func || item->with_window_func; with_field= with_field || item->with_field; used_tables_and_const_cache_join(item); @@ -376,7 +378,7 @@ Item_func::fix_fields(THD *thd, Item **ref) if (check_arguments()) return true; fix_length_and_dec(); - if (thd->is_error()) // An error inside fix_length_and_dec occurred + if (unlikely(thd->is_error())) // An error inside fix_length_and_dec occurred return TRUE; fixed= 1; return FALSE; @@ -1149,7 +1151,8 @@ double Item_double_typecast::val_real() if ((null_value= args[0]->null_value)) return 0.0; - if ((error= truncate_double(&tmp, max_length, decimals, 0, DBL_MAX))) + if (unlikely((error= truncate_double(&tmp, max_length, decimals, 0, + DBL_MAX)))) { THD *thd= current_thd; push_warning_printf(thd, @@ -1935,6 +1938,9 @@ void Item_func_neg::fix_length_and_dec_double() set_handler(&type_handler_double); decimals= args[0]->decimals; // Preserve NOT_FIXED_DEC max_length= args[0]->max_length + 1; + // Limit length with something reasonable + uint32 mlen= type_handler()->max_display_length(this); + set_if_smaller(max_length, mlen); unsigned_flag= false; } @@ -2503,12 +2509,12 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, volatile double value_div_tmp= value / tmp; volatile double value_mul_tmp= value * tmp; - if (!dec_negative && my_isinf(tmp)) // "dec" is too large positive number + if (!dec_negative && std::isinf(tmp)) // "dec" is too large positive number return value; - if (dec_negative && my_isinf(tmp)) + if (dec_negative && std::isinf(tmp)) tmp2= 0.0; - else if (!dec_negative && my_isinf(value_mul_tmp)) + else if (!dec_negative && std::isinf(value_mul_tmp)) tmp2= value; else if (truncate) { @@ -2738,7 +2744,7 @@ bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date) longlong res= args[i]->val_datetime_packed(); /* Check if we need to stop (because of error or KILL) and stop the loop */ - if (args[i]->null_value) + if (unlikely(args[i]->null_value)) return (null_value= 1); if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0) @@ -2747,7 +2753,7 @@ bool Item_func_min_max::get_date_native(MYSQL_TIME *ltime, ulonglong fuzzy_date) unpack_time(min_max, ltime, mysql_timestamp_type()); if (!(fuzzy_date & TIME_TIME_ONLY) && - ((null_value= check_date_with_warn(ltime, fuzzy_date, + unlikely((null_value= check_date_with_warn(ltime, fuzzy_date, MYSQL_TIMESTAMP_ERROR)))) return true; @@ -3074,8 +3080,8 @@ longlong Item_func_ord::val_int() #ifdef USE_MB if (use_mb(res->charset())) { - register const char *str=res->ptr(); - register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length()); + const char *str=res->ptr(); + uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length()); if (!l) return (longlong)((uchar) *str); while (l--) @@ -3297,6 +3303,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, func->maybe_null=1; func->with_sum_func= func->with_sum_func || item->with_sum_func; func->with_field= func->with_field || item->with_field; + func->with_param= func->with_param || item->with_param; func->With_subquery_cache::join(item); func->used_tables_and_const_cache_join(item); f_args.arg_type[i]=item->result_type(); @@ -3376,7 +3383,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, } } Udf_func_init init= u_d->func_init; - if ((error=(uchar) init(&initid, &f_args, init_msg_buff))) + if (unlikely((error=(uchar) init(&initid, &f_args, init_msg_buff)))) { my_error(ER_CANT_INITIALIZE_UDF, MYF(0), u_d->name.str, init_msg_buff); @@ -3394,7 +3401,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, func->decimals=MY_MIN(initid.decimals,NOT_FIXED_DEC); } initialized=1; - if (error) + if (unlikely(error)) { my_error(ER_CANT_INITIALIZE_UDF, MYF(0), u_d->name.str, ER_THD(thd, ER_UNKNOWN_ERROR)); @@ -3406,7 +3413,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, bool udf_handler::get_arguments() { - if (error) + if (unlikely(error)) return 1; // Got an error earlier char *to= num_buffer; uint str_count=0; @@ -3481,7 +3488,7 @@ String *udf_handler::val_str(String *str,String *save_str) char *res=func(&initid, &f_args, (char*) str->ptr(), &res_length, &is_null_tmp, &error); DBUG_PRINT("info", ("udf func returned, res_length: %lu", res_length)); - if (is_null_tmp || !res || error) // The !res is for safety + if (is_null_tmp || !res || unlikely(error)) // The !res is for safety { DBUG_PRINT("info", ("Null or error")); DBUG_RETURN(0); @@ -3517,7 +3524,7 @@ my_decimal *udf_handler::val_decimal(my_bool *null_value, my_decimal *dec_buf) u_d->func; char *res= func(&initid, &f_args, buf, &res_length, &is_null, &error); - if (is_null || error) + if (is_null || unlikely(error)) { *null_value= 1; return 0; @@ -4078,7 +4085,7 @@ longlong Item_func_get_lock::val_int() thd->push_internal_handler(&lock_wait_timeout_handler); bool error= thd->mdl_context.acquire_lock(&ull_request, timeout); (void) thd->pop_internal_handler(); - if (error) + if (unlikely(error)) { if (lock_wait_timeout_handler.m_lock_wait_timeout) null_value= 0; @@ -5351,13 +5358,14 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command, new (thd->mem_root) Item_null(thd))), thd->mem_root); /* Create the variable if the above allocations succeeded */ - if (thd->is_fatal_error || sql_set_variables(thd, &tmp_var_list, false)) + if (unlikely(thd->is_fatal_error) || + unlikely(sql_set_variables(thd, &tmp_var_list, false))) { thd->lex= sav_lex; goto err; } thd->lex= sav_lex; - if (!(var_entry= get_variable(&thd->user_vars, name, 0))) + if (unlikely(!(var_entry= get_variable(&thd->user_vars, name, 0)))) goto err; } else if (var_entry->used_query_id == thd->query_id || @@ -5386,8 +5394,8 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command, destroyed. */ size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length; - if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) - alloc_root(thd->user_var_events_alloc, size))) + if (unlikely(!(user_var_event= (BINLOG_USER_VAR_EVENT *) + alloc_root(thd->user_var_events_alloc, size)))) goto err; user_var_event->value= (char*) user_var_event + @@ -5436,7 +5444,7 @@ void Item_func_get_user_var::fix_length_and_dec() 'm_var_entry' is NULL only if there occurred an error during the call to get_var_with_binlog. */ - if (!error && m_var_entry) + if (likely(!error && m_var_entry)) { unsigned_flag= m_var_entry->unsigned_flag; max_length= (uint32)m_var_entry->length; @@ -5927,8 +5935,8 @@ bool Item_func_match::init_search(THD *thd, bool no_order) for (uint i= 1; i < arg_count; i++) fields.push_back(args[i]); concat_ws= new (thd->mem_root) Item_func_concat_ws(thd, fields); - if (thd->is_fatal_error) - DBUG_RETURN(1); // OOM + if (unlikely(thd->is_fatal_error)) + DBUG_RETURN(1); // OOM in new or push_back /* Above function used only to get value and do not need fix_fields for it: Item_string - basic constant @@ -6803,7 +6811,7 @@ longlong Item_func_nextval::val_int() entry->value= value; entry->set_version(table); - if (error) // Warning already printed + if (unlikely(error)) // Warning already printed entry->null_value= null_value= 1; // For not strict mode DBUG_RETURN(value); } @@ -6915,7 +6923,7 @@ longlong Item_func_setval::val_int() DBUG_ASSERT(table && table->s->sequence); thd= table->in_use; - if (thd->count_cuted_fields == CHECK_FIELD_EXPRESSION) + if (unlikely(thd->count_cuted_fields == CHECK_FIELD_EXPRESSION)) { /* Alter table checking if function works */ null_value= 0; @@ -6924,7 +6932,7 @@ longlong Item_func_setval::val_int() value= nextval; error= table->s->sequence->set_value(table, nextval, round, is_used); - if (error) + if (unlikely(error)) { null_value= 1; value= 0; diff --git a/sql/item_func.h b/sql/item_func.h index 59fc49ead39..a6fcf8f4870 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -32,6 +32,7 @@ extern "C" /* Bug in BSDI include file */ #include "sql_udf.h" // udf_handler #include "my_decimal.h" // string2my_decimal +#include <cmath> class Item_func :public Item_func_or_sum @@ -70,7 +71,7 @@ public: SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_RELATE_FUNC, - NOT_FUNC, NOT_ALL_FUNC, + NOT_FUNC, NOT_ALL_FUNC, TEMPTABLE_ROWID, NOW_FUNC, NOW_UTC_FUNC, SYSDATE_FUNC, TRIG_COND_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, @@ -82,16 +83,19 @@ public: { with_sum_func= 0; with_field= 0; + with_param= 0; } Item_func(THD *thd, Item *a): Item_func_or_sum(thd, a) { with_sum_func= a->with_sum_func; + with_param= a->with_param; with_field= a->with_field; } Item_func(THD *thd, Item *a, Item *b): Item_func_or_sum(thd, a, b) { with_sum_func= a->with_sum_func || b->with_sum_func; + with_param= a->with_param || b->with_param; with_field= a->with_field || b->with_field; } Item_func(THD *thd, Item *a, Item *b, Item *c): @@ -99,6 +103,7 @@ public: { with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func; with_field= a->with_field || b->with_field || c->with_field; + with_param= a->with_param || b->with_param || c->with_param; } Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d): Item_func_or_sum(thd, a, b, c, d) @@ -107,6 +112,8 @@ public: c->with_sum_func || d->with_sum_func; with_field= a->with_field || b->with_field || c->with_field || d->with_field; + with_param= a->with_param || b->with_param || + c->with_param || d->with_param; } Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e): Item_func_or_sum(thd, a, b, c, d, e) @@ -115,6 +122,8 @@ public: c->with_sum_func || d->with_sum_func || e->with_sum_func; with_field= a->with_field || b->with_field || c->with_field || d->with_field || e->with_field; + with_param= a->with_param || b->with_param || + c->with_param || d->with_param || e->with_param; } Item_func(THD *thd, List<Item> &list): Item_func_or_sum(thd, list) @@ -229,7 +238,7 @@ public: */ inline double check_float_overflow(double value) { - return isfinite(value) ? value : raise_float_overflow(); + return std::isfinite(value) ? value : raise_float_overflow(); } /** Throw an error if the input BIGINT value represented by the @@ -1612,14 +1621,13 @@ public: { name= a->name; } - double val_real() { return args[0]->val_real(); } - longlong val_int() { return args[0]->val_int(); } - String *val_str(String *str) { return args[0]->val_str(str); } - my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); } + double val_real() { return val_real_from_item(args[0]); } + longlong val_int() { return val_int_from_item(args[0]); } + String *val_str(String *str) { return val_str_from_item(args[0], str); } + my_decimal *val_decimal(my_decimal *dec) + { return val_decimal_from_item(args[0], dec); } bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) - { - return args[0]->get_date(ltime, fuzzydate); - } + { return get_date_from_item(args[0], ltime, fuzzydate); } const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } const Type_handler *type_handler() const { return args[0]->type_handler(); } @@ -1627,9 +1635,7 @@ public: { collation= args[0]->collation; max_length= args[0]->max_length; - decimals=args[0]->decimals; - /* The item could be a NULL constant. */ - null_value= args[0]->is_null(); + decimals=args[0]->decimals; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_rollup_const>(thd, this); } @@ -2851,7 +2857,7 @@ public: { return result_type() != STRING_RESULT ? sp_result_field : - tmp_table_field_from_field_type(table); + create_table_field_from_handler(table); } void make_send_field(THD *thd, Send_field *tmp_field); @@ -3014,6 +3020,7 @@ public: Item_func_uuid_short(THD *thd): Item_longlong_func(thd) {} const char *func_name() const { return "uuid_short"; } longlong val_int(); + bool const_item() const { return false; } void fix_length_and_dec() { max_length= 21; unsigned_flag=1; } table_map used_tables() const { return RAND_TABLE_BIT; } diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc index d4788a39d5e..8a3345ecc81 100644 --- a/sql/item_inetfunc.cc +++ b/sql/item_inetfunc.cc @@ -149,13 +149,14 @@ longlong Item_func_inet_bool_base::val_int() { DBUG_ASSERT(fixed); - if (args[0]->result_type() != STRING_RESULT) // String argument expected + // String argument expected + if (unlikely(args[0]->result_type() != STRING_RESULT)) return 0; String buffer; String *arg_str= args[0]->val_str(&buffer); - if (!arg_str) // Out-of memory happened. The error has been reported. + if (unlikely(!arg_str)) // Out-of memory happened. error has been reported. return 0; // Or: the underlying field is NULL return calc_value(arg_str) ? 1 : 0; @@ -175,7 +176,8 @@ String *Item_func_inet_str_base::val_str_ascii(String *buffer) { DBUG_ASSERT(fixed); - if (args[0]->result_type() != STRING_RESULT) // String argument expected + // String argument expected + if (unlikely(args[0]->result_type() != STRING_RESULT)) { null_value= true; return NULL; @@ -183,15 +185,17 @@ String *Item_func_inet_str_base::val_str_ascii(String *buffer) StringBuffer<STRING_BUFFER_USUAL_SIZE> tmp; String *arg_str= args[0]->val_str(&tmp); - if (!arg_str) // Out-of memory happened. The error has been reported. - { // Or: the underlying field is NULL + if (unlikely(!arg_str)) + { + // Out-of memory happened. error has been reported. + // Or: the underlying field is NULL null_value= true; return NULL; } null_value= !calc_value(arg_str, buffer); - return null_value ? NULL : buffer; + return unlikely(null_value) ? NULL : buffer; } /////////////////////////////////////////////////////////////////////////// diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index be1d84982de..a45baec8e92 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -173,7 +173,7 @@ static int json_nice(json_engine_t *je, String *nice_js, key_end= je->s.c_str; } while (json_read_keyname_chr(je) == 0); - if (je->s.error) + if (unlikely(je->s.error)) goto error; if (!first_value) @@ -492,7 +492,7 @@ continue_search: if (json_read_value(&je)) goto err_return; - if (check_and_get_value(&je, str, &error)) + if (unlikely(check_and_get_value(&je, str, &error))) { if (error) goto err_return; @@ -623,7 +623,7 @@ String *Item_func_json_unquote::val_str(String *str) if (!(js= read_json(&je))) return NULL; - if (je.s.error || je.value_type != JSON_VALUE_STRING) + if (unlikely(je.s.error) || je.value_type != JSON_VALUE_STRING) return js; str->length(0); @@ -835,7 +835,7 @@ String *Item_func_json_extract::read_json(String *str, } } - if (je.s.error) + if (unlikely(je.s.error)) goto error; if (!not_first_value) @@ -994,7 +994,7 @@ static int check_contains(json_engine_t *js, json_engine_t *value) k_end= value->s.c_str; } while (json_read_keyname_chr(value) == 0); - if (value->s.error || json_read_value(value)) + if (unlikely(value->s.error) || json_read_value(value)) return FALSE; if (set_js) @@ -1037,7 +1037,7 @@ static int check_contains(json_engine_t *js, json_engine_t *value) return FALSE; return TRUE; } - if (value->s.error || js->s.error || + if (unlikely(value->s.error) || unlikely(js->s.error) || (!v_scalar && json_skip_to_level(js, c_level))) return FALSE; } @@ -1165,7 +1165,7 @@ longlong Item_func_json_contains::val_int() goto error; result= check_contains(&je, &ve); - if (je.s.error || ve.s.error) + if (unlikely(je.s.error || ve.s.error)) goto error; return result; @@ -1385,7 +1385,7 @@ longlong Item_func_json_contains_path::val_int() } } - if (je.s.error == 0) + if (likely(je.s.error == 0)) return result; report_json_error(js, &je, 0); @@ -1749,7 +1749,7 @@ String *Item_func_json_array_insert::val_str(String *str) goto js_error; } - if (je.s.error) + if (unlikely(je.s.error)) goto js_error; str->length(0); @@ -1881,7 +1881,7 @@ static int do_merge(String *str, json_engine_t *je1, json_engine_t *je2) key_end= je1->s.c_str; } while (json_read_keyname_chr(je1) == 0); - if (je1->s.error) + if (unlikely(je1->s.error)) return 1; if (first_key) @@ -1916,7 +1916,7 @@ static int do_merge(String *str, json_engine_t *je1, json_engine_t *je2) return ires; goto merged_j1; } - if (je2->s.error) + if (unlikely(je2->s.error)) return 2; key_start= je1->s.c_str; @@ -1946,7 +1946,7 @@ merged_j1: key_end= je2->s.c_str; } while (json_read_keyname_chr(je2) == 0); - if (je2->s.error) + if (unlikely(je2->s.error)) return 1; *je1= sav_je1; @@ -1957,7 +1957,7 @@ merged_j1: json_string_set_str(&key_name, key_start, key_end); if (!json_key_matches(je1, &key_name)) { - if (je1->s.error || json_skip_key(je1)) + if (unlikely(je1->s.error || json_skip_key(je1))) return 2; continue; } @@ -1967,7 +1967,7 @@ merged_j1: goto continue_j2; } - if (je1->s.error) + if (unlikely(je1->s.error)) return 2; if (first_key) @@ -2008,7 +2008,7 @@ continue_j2: empty_array= 0; } - if (je1->s.error) + if (unlikely(je1->s.error)) return 1; end1= je1->s.c_str - je1->sav_c_len; @@ -2206,7 +2206,7 @@ longlong Item_func_json_length::val_int() while (json_scan_next(&je) == 0) {} } - if (!je.s.error) + if (likely(!je.s.error)) return length; err_return: @@ -2260,7 +2260,7 @@ longlong Item_func_json_depth::val_int() } } while (json_scan_next(&je) == 0); - if (!je.s.error) + if (likely(!je.s.error)) return depth; report_json_error(js, &je, 0); @@ -2475,7 +2475,7 @@ String *Item_func_json_insert::val_str(String *str) } } - if (je.s.error) + if (unlikely(je.s.error)) goto js_error; if (!mode_insert) @@ -2513,7 +2513,7 @@ String *Item_func_json_insert::val_str(String *str) } } - if (je.s.error) + if (unlikely(je.s.error)) goto js_error; if (!mode_insert) @@ -2615,7 +2615,7 @@ String *Item_func_json_remove::val_str(String *str) { uint array_counters[JSON_DEPTH_LIMIT]; json_path_with_flags *c_path= paths + n_path; - const char *rem_start, *rem_end; + const char *rem_start= 0, *rem_end; const json_path_step_t *lp; uint n_item= 0; @@ -2686,7 +2686,7 @@ String *Item_func_json_remove::val_str(String *str) } } - if (je.s.error) + if (unlikely(je.s.error)) goto js_error; continue; @@ -2718,7 +2718,7 @@ String *Item_func_json_remove::val_str(String *str) } } - if (je.s.error) + if (unlikely(je.s.error)) goto js_error; continue; @@ -2883,7 +2883,7 @@ skip_search: { key_end= je.s.c_str; } while (json_read_keyname_chr(&je) == 0); - if (je.s.error) + if (unlikely(je.s.error)) goto err_return; key_len= (int)(key_end - key_start); @@ -2907,7 +2907,7 @@ skip_search: } } - if (je.s.error || str->append("]", 1)) + if (unlikely(je.s.error || str->append("]", 1))) goto err_return; null_value= 0; @@ -3091,7 +3091,7 @@ String *Item_func_json_search::val_str(String *str) } } - if (je.s.error) + if (unlikely(je.s.error)) goto js_error; end: diff --git a/sql/item_row.cc b/sql/item_row.cc index 64794093bec..74ea9ecc0c2 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -65,6 +65,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref) with_window_func = with_window_func || item->with_window_func; with_field= with_field || item->with_field; m_with_subquery|= item->with_subquery(); + with_param|= item->with_param; } fixed= 1; return FALSE; @@ -178,4 +179,3 @@ Item* Item_row::build_clone(THD *thd) } return copy; } - diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 85e578f4595..6af49d494d4 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1078,7 +1078,7 @@ String *Item_func_reverse::val_str(String *str) #ifdef USE_MB if (use_mb(res->charset())) { - register uint32 l; + uint32 l; while (ptr < end) { if ((l= my_ismbchar(res->charset(),ptr,end))) @@ -1128,7 +1128,7 @@ String *Item_func_replace::val_str_internal(String *str, bool alloced=0; #ifdef USE_MB const char *ptr,*end,*strend,*search,*search_end; - register uint32 l; + uint32 l; bool binary_cmp; #endif THD *thd= 0; @@ -1188,7 +1188,7 @@ redo: { if (*ptr == *search) { - register char *i,*j; + char *i,*j; i=(char*) ptr+1; j=(char*) search+1; while (j != search_end) if (*i++ != *j++) goto skip; @@ -1799,14 +1799,14 @@ String *Item_func_substr_index::val_str(String *str) const char *search= delimiter->ptr(); const char *search_end= search+delimiter_length; int32 n=0,c=count,pass; - register uint32 l; + uint32 l; for (pass=(count>0);pass<2;++pass) { while (ptr < end) { if (*ptr == *search) { - register char *i,*j; + char *i,*j; i=(char*) ptr+1; j=(char*) search+1; while (j != search_end) if (*i++ != *j++) goto skip; @@ -1974,7 +1974,7 @@ String *Item_func_rtrim::val_str(String *str) end= ptr+res->length(); #ifdef USE_MB char *p=ptr; - register uint32 l; + uint32 l; #endif if (remove_length == 1) { @@ -2059,7 +2059,7 @@ String *Item_func_trim::val_str(String *str) if (use_mb(collation.collation)) { char *p=ptr; - register uint32 l; + uint32 l; loop: while (ptr + remove_length < end) { @@ -2641,7 +2641,7 @@ String *Item_func_format::val_str_ascii(String *str) return 0; /* purecov: inspected */ nr= my_double_round(nr, (longlong) dec, FALSE, FALSE); str->set_real(nr, dec, &my_charset_numeric); - if (!isfinite(nr)) + if (!std::isfinite(nr)) return str; str_length=str->length(); } @@ -4918,7 +4918,7 @@ longlong Item_dyncol_get::val_int() char *end= val.x.string.value.str + val.x.string.value.length, *org_end= end; num= my_strtoll10(val.x.string.value.str, &end, &error); - if (end != org_end || error > 0) + if (unlikely(end != org_end || error > 0)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_BAD_DATA, @@ -5204,3 +5204,23 @@ null: my_free(names); return NULL; } + +Item_temptable_rowid::Item_temptable_rowid(TABLE *table_arg) + : Item_str_func(table_arg->in_use), table(table_arg) +{ + max_length= table->file->ref_length; +} + +void Item_temptable_rowid::fix_length_and_dec() +{ + used_tables_cache= table->map; + const_item_cache= false; +} + +String *Item_temptable_rowid::val_str(String *str) +{ + if (!((null_value= table->null_row))) + table->file->position(table->record[0]); + str_value.set((char*)(table->file->ref), max_length, &my_charset_bin); + return &str_value; +} diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index cff9fdee072..eb084c3f58d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -1630,6 +1630,7 @@ public: DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII); fix_char_length(MY_UUID_STRING_LENGTH); } + bool const_item() const { return false; } table_map used_tables() const { return RAND_TABLE_BIT; } const char *func_name() const{ return "uuid"; } String *val_str(String *); @@ -1750,5 +1751,25 @@ public: { return get_item_copy<Item_func_dyncol_list>(thd, this); } }; -#endif /* ITEM_STRFUNC_INCLUDED */ +/* + this is used by JOIN_TAB::keep_current_rowid + and stores handler::position(). + It has nothing to do with _rowid pseudo-column, that the parser supports. +*/ +class Item_temptable_rowid :public Item_str_func +{ +public: + TABLE *table; + Item_temptable_rowid(TABLE *table_arg); + const Type_handler *type_handler() const { return &type_handler_string; } + Field *create_tmp_field(bool group, TABLE *table) + { return create_table_field_from_handler(table); } + String *val_str(String *str); + enum Functype functype() const { return TEMPTABLE_ROWID; } + const char *func_name() const { return "<rowid>"; } + void fix_length_and_dec(); + Item *get_copy(THD *thd) + { return get_item_copy<Item_temptable_rowid>(thd, this); } +}; +#endif /* ITEM_STRFUNC_INCLUDED */ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6378e9b76bf..143894ad949 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -156,6 +156,7 @@ void Item_subselect::cleanup() reset(); filesort_buffer.free_sort_buffer(); my_free(sortbuffer.str); + sortbuffer.str= 0; value_assigned= 0; expr_cache= 0; @@ -710,7 +711,7 @@ bool Item_subselect::exec() Do not execute subselect in case of a fatal error or if the query has been killed. */ - if (thd->is_error() || thd->killed) + if (unlikely(thd->is_error() || thd->killed)) DBUG_RETURN(true); DBUG_ASSERT(!thd->lex->context_analysis_only); @@ -1417,14 +1418,14 @@ void Item_exists_subselect::print(String *str, enum_query_type query_type) bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg) { - if (unit_arg->fake_select_lex && - unit_arg->fake_select_lex->test_limit()) + if (unlikely(unit_arg->fake_select_lex && + unit_arg->fake_select_lex->test_limit())) return(1); SELECT_LEX *sl= unit_arg->first_select(); for (; sl; sl= sl->next_select()) { - if (sl->test_limit()) + if (unlikely(sl->test_limit())) return(1); } return(0); @@ -3674,7 +3675,7 @@ int subselect_single_select_engine::prepare(THD *thd) int subselect_union_engine::prepare(THD *thd_arg) { set_thd(thd_arg); - return unit->prepare(thd, result, SELECT_NO_UNLOCK); + return unit->prepare(unit->derived, result, SELECT_NO_UNLOCK); } int subselect_uniquesubquery_engine::prepare(THD *) @@ -3935,12 +3936,8 @@ int subselect_uniquesubquery_engine::scan_table() for (;;) { error=table->file->ha_rnd_next(table->record[0]); - if (error) { - if (error == HA_ERR_RECORD_DELETED) - { - error= 0; - continue; - } + if (unlikely(error)) + { if (error == HA_ERR_END_OF_FILE) { error= 0; @@ -4076,8 +4073,8 @@ int subselect_uniquesubquery_engine::exec() make_prev_keypart_map(tab-> ref.key_parts), HA_READ_KEY_EXACT); - if (error && - error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + if (unlikely(error && + error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)) error= report_error(table, error); else { @@ -4115,7 +4112,8 @@ int subselect_uniquesubquery_engine::index_lookup() HA_READ_KEY_EXACT); DBUG_PRINT("info", ("lookup result: %i", error)); - if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + if (unlikely(error && error != HA_ERR_KEY_NOT_FOUND && + error != HA_ERR_END_OF_FILE)) { /* TIMOUR: I don't understand at all when do we need to call report_error. @@ -4246,8 +4244,8 @@ int subselect_indexsubquery_engine::exec() make_prev_keypart_map(tab-> ref.key_parts), HA_READ_KEY_EXACT); - if (error && - error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + if (unlikely(error && + error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)) error= report_error(table, error); else { @@ -4269,7 +4267,7 @@ int subselect_indexsubquery_engine::exec() error= table->file->ha_index_next_same(table->record[0], tab->ref.key_buff, tab->ref.key_length); - if (error && error != HA_ERR_END_OF_FILE) + if (unlikely(error && error != HA_ERR_END_OF_FILE)) { error= report_error(table, error); break; @@ -4282,7 +4280,7 @@ int subselect_indexsubquery_engine::exec() *tab->ref.null_ref_key= 1; null_finding= 1; /* Check if there exists a row with a null value in the index */ - if ((error= (safe_index_read(tab) == 1))) + if (unlikely((error= (safe_index_read(tab) == 1)))) break; } } @@ -5425,8 +5423,8 @@ int subselect_hash_sj_engine::exec() DBUG_ASSERT(materialize_join->optimization_state == JOIN::OPTIMIZATION_DONE && !is_materialized); materialize_join->exec(); - if ((res= MY_TEST(materialize_join->error || thd->is_fatal_error || - thd->is_error()))) + if (unlikely((res= MY_TEST(materialize_join->error || thd->is_fatal_error || + thd->is_error())))) goto err; /* @@ -5784,14 +5782,14 @@ Ordered_key::cmp_keys_by_row_data(ha_rows a, ha_rows b) rowid_a= row_num_to_rowid + a * rowid_length; rowid_b= row_num_to_rowid + b * rowid_length; /* Fetch the rows for comparison. */ - if ((error= tbl->file->ha_rnd_pos(tbl->record[0], rowid_a))) + if (unlikely((error= tbl->file->ha_rnd_pos(tbl->record[0], rowid_a)))) { /* purecov: begin inspected */ tbl->file->print_error(error, MYF(ME_FATALERROR)); // Sets fatal_error return 0; /* purecov: end */ } - if ((error= tbl->file->ha_rnd_pos(tbl->record[1], rowid_b))) + if (unlikely((error= tbl->file->ha_rnd_pos(tbl->record[1], rowid_b)))) { /* purecov: begin inspected */ tbl->file->print_error(error, MYF(ME_FATALERROR)); // Sets fatal_error @@ -5873,7 +5871,7 @@ int Ordered_key::cmp_key_with_search_key(rownum_t row_num) int __attribute__((unused)) error; int cmp_res; - if ((error= tbl->file->ha_rnd_pos(tbl->record[0], cur_rowid))) + if (unlikely((error= tbl->file->ha_rnd_pos(tbl->record[0], cur_rowid)))) { /* purecov: begin inspected */ tbl->file->print_error(error, MYF(ME_FATALERROR)); // Sets fatal_error @@ -6222,7 +6220,7 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts, DBUG_ASSERT(cur_keyid == merge_keys_count); /* Populate the indexes with data from the temporary table. */ - if (tmp_table->file->ha_rnd_init_with_error(1)) + if (unlikely(tmp_table->file->ha_rnd_init_with_error(1))) return TRUE; tmp_table->file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); @@ -6230,17 +6228,12 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts, while (TRUE) { error= tmp_table->file->ha_rnd_next(tmp_table->record[0]); - if (error == HA_ERR_RECORD_DELETED) - { - /* We get this for duplicate records that should not be in tmp_table. */ - continue; - } /* This is a temp table that we fully own, there should be no other cause to stop the iteration than EOF. */ DBUG_ASSERT(!error || error == HA_ERR_END_OF_FILE); - if (error == HA_ERR_END_OF_FILE) + if (unlikely(error == HA_ERR_END_OF_FILE)) { DBUG_ASSERT(cur_rownum == tmp_table->file->stats.records); break; @@ -6460,7 +6453,7 @@ bool subselect_rowid_merge_engine::partial_match() DBUG_ASSERT(!pq.elements); /* All data accesses during execution are via handler::ha_rnd_pos() */ - if (tmp_table->file->ha_rnd_init_with_error(0)) + if (unlikely(tmp_table->file->ha_rnd_init_with_error(0))) { res= FALSE; goto end; @@ -6666,7 +6659,7 @@ bool subselect_table_scan_engine::partial_match() int error; bool res; - if (tmp_table->file->ha_rnd_init_with_error(1)) + if (unlikely(tmp_table->file->ha_rnd_init_with_error(1))) { res= FALSE; goto end; @@ -6677,12 +6670,8 @@ bool subselect_table_scan_engine::partial_match() for (;;) { error= tmp_table->file->ha_rnd_next(tmp_table->record[0]); - if (error) { - if (error == HA_ERR_RECORD_DELETED) - { - error= 0; - continue; - } + if (unlikely(error)) + { if (error == HA_ERR_END_OF_FILE) { error= 0; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 4a951896135..19e94be7882 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -999,7 +999,7 @@ bool Aggregator_distinct::add() */ return tree->unique_add(table->record[0] + table->s->null_bytes); } - if ((error= table->file->ha_write_tmp_row(table->record[0])) && + if (unlikely((error= table->file->ha_write_tmp_row(table->record[0]))) && table->file->is_fatal_error(error, HA_CHECK_DUP)) return TRUE; return FALSE; @@ -1133,6 +1133,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) return TRUE; set_if_bigger(decimals, args[i]->decimals); m_with_subquery|= args[i]->with_subquery(); + with_param|= args[i]->with_param; with_window_func|= args[i]->with_window_func; } result_field=0; @@ -1166,6 +1167,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref) DBUG_RETURN(TRUE); m_with_subquery= args[0]->with_subquery(); + with_param= args[0]->with_param; with_window_func|= args[0]->with_window_func; fix_length_and_dec(); @@ -1269,6 +1271,12 @@ Item_sum_sp::Item_sum_sp(THD *thd, Name_resolution_context *context_arg, m_sp= sp; } +Item_sum_sp::Item_sum_sp(THD *thd, Item_sum_sp *item): + Item_sum(thd, item), Item_sp(thd, item) +{ + maybe_null= item->maybe_null; + quick_group= item->quick_group; +} bool Item_sum_sp::fix_fields(THD *thd, Item **ref) @@ -1388,7 +1396,7 @@ Item_sum_sp::fix_length_and_dec() { DBUG_ENTER("Item_sum_sp::fix_length_and_dec"); DBUG_ASSERT(sp_result_field); - Type_std_attributes::set(sp_result_field); + Type_std_attributes::set(sp_result_field->type_std_attributes()); Item_sum::fix_length_and_dec(); DBUG_VOID_RETURN; } @@ -1400,6 +1408,14 @@ Item_sum_sp::func_name() const return Item_sp::func_name(thd); } +Item* Item_sum_sp::copy_or_same(THD *thd) +{ + Item_sum_sp *copy_item= new (thd->mem_root) Item_sum_sp(thd, this); + copy_item->init_result_field(thd, max_length, maybe_null, + ©_item->null_value, ©_item->name); + return copy_item; +} + /*********************************************************************** ** reset and add of sum_func ***********************************************************************/ @@ -2027,7 +2043,7 @@ double Item_sum_std::val_real() { DBUG_ASSERT(fixed == 1); double nr= Item_sum_variance::val_real(); - if (my_isinf(nr)) + if (std::isinf(nr)) return DBL_MAX; DBUG_ASSERT(nr >= 0.0); return sqrt(nr); @@ -2458,7 +2474,7 @@ Item *Item_sum_max::copy_or_same(THD* thd) bool Item_sum_max::add() { - Item *tmp_item; + Item * UNINIT_VAR(tmp_item); DBUG_ENTER("Item_sum_max::add"); DBUG_PRINT("enter", ("this: %p", this)); @@ -2663,7 +2679,7 @@ void Item_sum_num::reset_field() void Item_sum_hybrid::reset_field() { - Item *tmp_item, *arg0; + Item *UNINIT_VAR(tmp_item), *arg0; DBUG_ENTER("Item_sum_hybrid::reset_field"); arg0= args[0]; @@ -3020,7 +3036,7 @@ Item *Item_sum_avg::result_item(THD *thd, Field *field) void Item_sum_hybrid::update_field() { DBUG_ENTER("Item_sum_hybrid::update_field"); - Item *tmp_item; + Item *UNINIT_VAR(tmp_item); if (unlikely(direct_added)) { tmp_item= args[0]; @@ -3900,6 +3916,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) args[i]->check_cols(1)) return TRUE; m_with_subquery|= args[i]->with_subquery(); + with_param|= args[i]->with_param; with_window_func|= args[i]->with_window_func; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 96f115357f9..b0dea818f01 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1297,11 +1297,16 @@ public: Item_sum_sp(THD *thd, Name_resolution_context *context_arg, sp_name *name, sp_head *sp, List<Item> &list); + Item_sum_sp(THD *thd, Item_sum_sp *item); enum Sumfunctype sum_func () const { return SP_AGGREGATE_FUNC; } + Field *create_field_for_create_select(TABLE *table) + { + return create_table_field_from_handler(table); + } void fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); const char *func_name() const; @@ -1362,6 +1367,7 @@ public: } Item *get_copy(THD *thd) { return get_item_copy<Item_sum_sp>(thd, this); } + Item *copy_or_same(THD *thd); }; /* Items to get the value of a stored sum function */ diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 5f4a489fca1..e01114fb0ad 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -257,8 +257,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, break; case 'w': tmp= (char*) val + 1; - if ((weekday= (int) my_strtoll10(val, &tmp, &error)) < 0 || - weekday >= 7) + if (unlikely((weekday= (int) my_strtoll10(val, &tmp, &error)) < 0 || + weekday >= 7)) goto err; /* We should use the same 1 - 7 scale for %w as for %W */ if (!weekday) @@ -279,9 +279,10 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V'); strict_week_number= (*ptr=='V' || *ptr=='v'); tmp= (char*) val + MY_MIN(val_len, 2); - if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 || - (strict_week_number && !week_number) || - week_number > 53) + if (unlikely((week_number= + (int) my_strtoll10(val, &tmp, &error)) < 0 || + (strict_week_number && !week_number) || + week_number > 53)) goto err; val= tmp; break; @@ -331,7 +332,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, default: goto err; } - if (error) // Error from my_strtoll10 + if (unlikely(error)) // Error from my_strtoll10 goto err; } else if (!my_isspace(cs, *ptr)) @@ -3232,13 +3233,7 @@ void Item_func_str_to_date::fix_length_and_dec() if (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1)) return; if (collation.collation->mbminlen > 1) - { -#if MYSQL_VERSION_ID > 50500 internal_charset= &my_charset_utf8mb4_general_ci; -#else - internal_charset= &my_charset_utf8_general_ci; -#endif - } maybe_null= true; set_handler(&type_handler_datetime2); diff --git a/sql/item_vers.cc b/sql/item_vers.cc index 32a6c67f2fe..d7361f687f9 100644 --- a/sql/item_vers.cc +++ b/sql/item_vers.cc @@ -26,9 +26,9 @@ #include "tztime.h" #include "item.h" -Item_func_vtq_ts::Item_func_vtq_ts(THD *thd, Item* a, TR_table::field_id_t _vtq_field) : +Item_func_trt_ts::Item_func_trt_ts(THD *thd, Item* a, TR_table::field_id_t _trt_field) : Item_datetimefunc(thd, a), - vtq_field(_vtq_field) + trt_field(_trt_field) { decimals= 6; null_value= true; @@ -37,7 +37,7 @@ Item_func_vtq_ts::Item_func_vtq_ts(THD *thd, Item* a, TR_table::field_id_t _vtq_ bool -Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date) +Item_func_trt_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date) { THD *thd= current_thd; // can it differ from constructor's? DBUG_ASSERT(thd); @@ -67,14 +67,14 @@ Item_func_vtq_ts::get_date(MYSQL_TIME *res, ulonglong fuzzy_date) return true; } - return trt[vtq_field]->get_date(res, fuzzy_date); + return trt[trt_field]->get_date(res, fuzzy_date); } -Item_func_vtq_id::Item_func_vtq_id(THD *thd, Item* a, TR_table::field_id_t _vtq_field, +Item_func_trt_id::Item_func_trt_id(THD *thd, Item* a, TR_table::field_id_t _trt_field, bool _backwards) : Item_longlong_func(thd, a), - vtq_field(_vtq_field), + trt_field(_trt_field), backwards(_backwards) { decimals= 0; @@ -83,9 +83,9 @@ Item_func_vtq_id::Item_func_vtq_id(THD *thd, Item* a, TR_table::field_id_t _vtq_ DBUG_ASSERT(arg_count == 1 && args[0]); } -Item_func_vtq_id::Item_func_vtq_id(THD *thd, Item* a, Item* b, TR_table::field_id_t _vtq_field) : +Item_func_trt_id::Item_func_trt_id(THD *thd, Item* a, Item* b, TR_table::field_id_t _trt_field) : Item_longlong_func(thd, a, b), - vtq_field(_vtq_field), + trt_field(_trt_field), backwards(false) { decimals= 0; @@ -95,7 +95,7 @@ Item_func_vtq_id::Item_func_vtq_id(THD *thd, Item* a, Item* b, TR_table::field_i } longlong -Item_func_vtq_id::get_by_trx_id(ulonglong trx_id) +Item_func_trt_id::get_by_trx_id(ulonglong trx_id) { THD *thd= current_thd; DBUG_ASSERT(thd); @@ -111,11 +111,11 @@ Item_func_vtq_id::get_by_trx_id(ulonglong trx_id) if (null_value) return 0; - return trt[vtq_field]->val_int(); + return trt[trt_field]->val_int(); } longlong -Item_func_vtq_id::get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards) +Item_func_trt_id::get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards) { THD *thd= current_thd; DBUG_ASSERT(thd); @@ -123,17 +123,17 @@ Item_func_vtq_id::get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards) TR_table trt(thd); null_value= !trt.query(commit_ts, backwards); if (null_value) - return 0; + return backwards ? ULONGLONG_MAX : 0; - return trt[vtq_field]->val_int(); + return trt[trt_field]->val_int(); } longlong -Item_func_vtq_id::val_int() +Item_func_trt_id::val_int() { if (args[0]->is_null()) { - if (arg_count < 2 || vtq_field == TR_table::FLD_TRX_ID) + if (arg_count < 2 || trt_field == TR_table::FLD_TRX_ID) { null_value= true; return 0; @@ -157,7 +157,7 @@ Item_func_vtq_id::val_int() } } -Item_func_vtq_trx_sees::Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b) : +Item_func_trt_trx_sees::Item_func_trt_trx_sees(THD *thd, Item* a, Item* b) : Item_bool_func(thd, a, b), accept_eq(false) { @@ -166,7 +166,7 @@ Item_func_vtq_trx_sees::Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b) : } longlong -Item_func_vtq_trx_sees::val_int() +Item_func_trt_trx_sees::val_int() { THD *thd= current_thd; DBUG_ASSERT(thd); diff --git a/sql/item_vers.h b/sql/item_vers.h index 39ed4ecda1f..17ad3daa73c 100644 --- a/sql/item_vers.h +++ b/sql/item_vers.h @@ -22,47 +22,47 @@ #pragma interface /* gcc class implementation */ #endif -class Item_func_vtq_ts: public Item_datetimefunc +class Item_func_trt_ts: public Item_datetimefunc { - TR_table::field_id_t vtq_field; + TR_table::field_id_t trt_field; public: - Item_func_vtq_ts(THD *thd, Item* a, TR_table::field_id_t _vtq_field); + Item_func_trt_ts(THD *thd, Item* a, TR_table::field_id_t _trt_field); const char *func_name() const { - if (vtq_field == TR_table::FLD_BEGIN_TS) + if (trt_field == TR_table::FLD_BEGIN_TS) { - return "vtq_begin_ts"; + return "trt_begin_ts"; } - return "vtq_commit_ts"; + return "trt_commit_ts"; } bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); Item *get_copy(THD *thd) - { return get_item_copy<Item_func_vtq_ts>(thd, this); } + { return get_item_copy<Item_func_trt_ts>(thd, this); } void fix_length_and_dec() { fix_attributes_datetime(decimals); } }; -class Item_func_vtq_id : public Item_longlong_func +class Item_func_trt_id : public Item_longlong_func { - TR_table::field_id_t vtq_field; + TR_table::field_id_t trt_field; bool backwards; longlong get_by_trx_id(ulonglong trx_id); longlong get_by_commit_ts(MYSQL_TIME &commit_ts, bool backwards); public: - Item_func_vtq_id(THD *thd, Item* a, TR_table::field_id_t _vtq_field, bool _backwards= false); - Item_func_vtq_id(THD *thd, Item* a, Item* b, TR_table::field_id_t _vtq_field); + Item_func_trt_id(THD *thd, Item* a, TR_table::field_id_t _trt_field, bool _backwards= false); + Item_func_trt_id(THD *thd, Item* a, Item* b, TR_table::field_id_t _trt_field); const char *func_name() const { - switch (vtq_field) + switch (trt_field) { case TR_table::FLD_TRX_ID: - return "vtq_trx_id"; + return "trt_trx_id"; case TR_table::FLD_COMMIT_ID: - return "vtq_commit_id"; + return "trt_commit_id"; case TR_table::FLD_ISO_LEVEL: - return "vtq_iso_level"; + return "trt_iso_level"; default: DBUG_ASSERT(0); } @@ -77,37 +77,37 @@ public: longlong val_int(); Item *get_copy(THD *thd) - { return get_item_copy<Item_func_vtq_id>(thd, this); } + { return get_item_copy<Item_func_trt_id>(thd, this); } }; -class Item_func_vtq_trx_sees : public Item_bool_func +class Item_func_trt_trx_sees : public Item_bool_func { protected: bool accept_eq; public: - Item_func_vtq_trx_sees(THD *thd, Item* a, Item* b); + Item_func_trt_trx_sees(THD *thd, Item* a, Item* b); const char *func_name() const { - return "vtq_trx_sees"; + return "trt_trx_sees"; } longlong val_int(); Item *get_copy(THD *thd) - { return get_item_copy<Item_func_vtq_trx_sees>(thd, this); } + { return get_item_copy<Item_func_trt_trx_sees>(thd, this); } }; -class Item_func_vtq_trx_sees_eq : - public Item_func_vtq_trx_sees +class Item_func_trt_trx_sees_eq : + public Item_func_trt_trx_sees { public: - Item_func_vtq_trx_sees_eq(THD *thd, Item* a, Item* b) : - Item_func_vtq_trx_sees(thd, a, b) + Item_func_trt_trx_sees_eq(THD *thd, Item* a, Item* b) : + Item_func_trt_trx_sees(thd, a, b) { accept_eq= true; } const char *func_name() const { - return "vtq_trx_sees_eq"; + return "trt_trx_sees_eq"; } }; diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index a4221661ae4..b38e06b3778 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2646,6 +2646,10 @@ my_xpath_parse_VariableReference(MY_XPATH *xpath) sp_variable *spv; const Sp_rcontext_handler *rh; LEX *lex; + /* + We call lex->find_variable() rather than thd->lex->spcont->find_variable() + to make sure package body variables are properly supported. + */ if ((lex= thd->lex) && (spv= lex->find_variable(&name, &rh))) { diff --git a/sql/key.cc b/sql/key.cc index 8642820ff3f..34196a973c5 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -52,8 +52,8 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field, uint *key_length, uint *keypart) { - reg2 int i; - reg3 KEY *key_info; + int i; + KEY *key_info; uint fieldpos; fieldpos= field->offset(record); @@ -499,7 +499,7 @@ int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length) if (key_part->null_bit) { /* This key part allows null values; NULL is lower than everything */ - register bool field_is_null= key_part->field->is_null(); + bool field_is_null= key_part->field->is_null(); if (*key) // If range key is null { /* the range is expecting a null value */ diff --git a/sql/lex.h b/sql/lex.h index 7be3e4c9251..d336c273a18 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -722,7 +722,7 @@ static SYMBOL symbols[] = { { "YEAR", SYM(YEAR_SYM)}, { "YEAR_MONTH", SYM(YEAR_MONTH_SYM)}, { "ZEROFILL", SYM(ZEROFILL)}, - { "||", SYM(OR_OR_SYM)} + { "||", SYM(OR2_SYM)} }; diff --git a/sql/lex_string.h b/sql/lex_string.h index 25f2c83a372..a5209165be0 100644 --- a/sql/lex_string.h +++ b/sql/lex_string.h @@ -21,6 +21,7 @@ typedef struct st_mysql_const_lex_string LEX_CSTRING; /* Functions to compare if two lex strings are equal */ + static inline bool lex_string_cmp(CHARSET_INFO *charset, const LEX_CSTRING *a, const LEX_CSTRING *b) { @@ -30,6 +31,7 @@ static inline bool lex_string_cmp(CHARSET_INFO *charset, const LEX_CSTRING *a, /* Compare to LEX_CSTRING's and return 0 if equal */ + static inline bool cmp(const LEX_CSTRING *a, const LEX_CSTRING *b) { return (a->length != b->length || @@ -40,6 +42,7 @@ static inline bool cmp(const LEX_CSTRING *a, const LEX_CSTRING *b) Compare if two LEX_CSTRING are equal. Assumption is that character set is ASCII (like for plugin names) */ + static inline bool lex_string_eq(const LEX_CSTRING *a, const LEX_CSTRING *b) { if (a->length != b->length) @@ -48,12 +51,15 @@ static inline bool lex_string_eq(const LEX_CSTRING *a, const LEX_CSTRING *b) } /* - Compare if two LEX_CSTRING are equal in system character set - (field names, user variables, etc - but *not* table names) + To be used when calling lex_string_eq with STRING_WITH_LEN() as second + argument */ -static inline bool lex_string_syseq(const LEX_CSTRING *a, const LEX_CSTRING *b) + +static inline bool lex_string_eq(const LEX_CSTRING *a, const char *b, size_t b_length) { - return lex_string_cmp(system_charset_info, a, b) == 0; + if (a->length != b_length) + return 0; /* Different */ + return strcasecmp(a->str, b) == 0; } #endif /* LEX_STRING_INCLUDED */ diff --git a/sql/lock.cc b/sql/lock.cc index 2d9409fc7c3..17629f17291 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -379,7 +379,7 @@ end: static int lock_external(THD *thd, TABLE **tables, uint count) { - reg1 uint i; + uint i; int lock_type,error; DBUG_ENTER("lock_external"); @@ -393,7 +393,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count) (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT)) lock_type=F_RDLCK; - if ((error=(*tables)->file->ha_external_lock(thd,lock_type))) + if (unlikely((error=(*tables)->file->ha_external_lock(thd,lock_type)))) { (*tables)->file->print_error(error, MYF(0)); while (--i) @@ -439,7 +439,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock) DBUG_ASSERT(!(sql_lock->flags & GET_LOCK_ON_THD)); my_free(sql_lock); } - if (!errors) + if (likely(!errors)) thd->clear_error(); THD_STAGE_INFO(thd, org_stage); DBUG_VOID_RETURN; @@ -539,7 +539,7 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table) { if (locked) { - reg1 uint i; + uint i; for (i=0; i < locked->table_count; i++) { if (locked->table[i] == table) @@ -726,7 +726,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count) if ((*table)->current_lock != F_UNLCK) { (*table)->current_lock = F_UNLCK; - if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK))) + if (unlikely((error=(*table)->file->ha_external_lock(thd, F_UNLCK)))) { error_code= error; (*table)->file->print_error(error, MYF(0)); diff --git a/sql/log.cc b/sql/log.cc index 8ed53a60195..ff4b0366b43 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2044,7 +2044,7 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all) - We are in a transaction and a full transaction is committed. Otherwise, we accumulate the changes. */ - if (!error && ending_trans(thd, all)) + if (likely(!error) && ending_trans(thd, all)) error= binlog_commit_flush_trx_cache(thd, all, cache_mngr); /* @@ -2122,7 +2122,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) */ error |= binlog_truncate_trx_cache(thd, cache_mngr, all); } - else if (!error) + else if (likely(!error)) { if (ending_trans(thd, all) && trans_cannot_safely_rollback(thd, all)) error= binlog_rollback_flush_trx_cache(thd, all, cache_mngr); @@ -2174,7 +2174,7 @@ void MYSQL_BIN_LOG::set_write_error(THD *thd, bool is_transactional) write_error= 1; - if (check_write_error(thd)) + if (unlikely(check_write_error(thd))) DBUG_VOID_RETURN; if (my_errno == EFBIG) @@ -2202,7 +2202,7 @@ bool MYSQL_BIN_LOG::check_write_error(THD *thd) bool checked= FALSE; - if (!thd->is_error()) + if (likely(!thd->is_error())) DBUG_RETURN(checked); switch (thd->get_stmt_da()->sql_errno()) @@ -2273,7 +2273,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) or "RELEASE S" without the preceding "SAVEPOINT S" in the binary log. */ - if (!(error= mysql_bin_log.write(&qinfo))) + if (likely(!(error= mysql_bin_log.write(&qinfo)))) binlog_trans_log_savepos(thd, (my_off_t*) sv); DBUG_RETURN(error); @@ -2459,7 +2459,7 @@ static int find_uniq_filename(char *name, ulong next_log_number) uint i; char buff[FN_REFLEN], ext_buf[FN_REFLEN]; struct st_my_dir *dir_info; - reg1 struct fileinfo *file_info; + struct fileinfo *file_info; ulong max_found, next, UNINIT_VAR(number); size_t buf_length, length; char *start, *end; @@ -2474,7 +2474,8 @@ static int find_uniq_filename(char *name, ulong next_log_number) length= (size_t) (end - start + 1); if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1, - !(dir_info= my_dir(buff,MYF(MY_DONT_SORT)))))) + unlikely(!(dir_info= my_dir(buff, + MYF(MY_DONT_SORT))))))) { // This shouldn't happen strmov(end,".1"); // use name+1 DBUG_RETURN(1); @@ -2666,7 +2667,7 @@ bool MYSQL_LOG::open( #ifdef EMBEDDED_LIBRARY "embedded library\n", my_progname, server_version, MYSQL_COMPILATION_COMMENT -#elif _WIN32 +#elif defined(_WIN32) "started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, MYSQL_COMPILATION_COMMENT, mysqld_port, mysqld_unix_port @@ -2784,10 +2785,10 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name, if (!fn_ext(log_name)[0]) { if (DBUG_EVALUATE_IF("binlog_inject_new_name_error", TRUE, FALSE) || - find_uniq_filename(new_name, next_log_number)) + unlikely(find_uniq_filename(new_name, next_log_number))) { THD *thd= current_thd; - if (thd) + if (unlikely(thd)) my_error(ER_NO_UNIQUE_LOGFILE, MYF(ME_FATALERROR), log_name); sql_print_error(ER_DEFAULT(ER_NO_UNIQUE_LOGFILE), log_name); return 1; @@ -3136,7 +3137,7 @@ end: err: error= 1; - if (! write_error) + if (!write_error) { write_error= 1; sql_print_error(ER_THD(thd, ER_ERROR_ON_WRITE), name, errno); @@ -4192,7 +4193,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, for (;;) { - if ((error= my_delete(linfo.log_file_name, MYF(0))) != 0) + if (unlikely((error= my_delete(linfo.log_file_name, MYF(0))))) { if (my_errno == ENOENT) { @@ -4235,7 +4236,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, /* Start logging with a new file */ close(LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED); - if ((error= my_delete(index_file_name, MYF(0)))) // Reset (open will update) + // Reset (open will update) + if (unlikely((error= my_delete(index_file_name, MYF(0))))) { if (my_errno == ENOENT) { @@ -4264,8 +4266,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD *thd, bool create_new_log, } } if (create_new_log && !open_index_file(index_file_name, 0, FALSE)) - if ((error= open(save_name, log_type, 0, next_log_number, - io_cache_type, max_size, 0, FALSE))) + if (unlikely((error= open(save_name, log_type, 0, next_log_number, + io_cache_type, max_size, 0, FALSE)))) goto err; my_free((void *) save_name); @@ -4413,8 +4415,9 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) Read the next log file name from the index file and pass it back to the caller. */ - if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) || - (error=find_next_log(&rli->linfo, 0))) + if (unlikely((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, + 0))) || + unlikely((error=find_next_log(&rli->linfo, 0)))) { sql_print_error("next log error: %d offset: %llu log: %s included: %d", error, rli->linfo.index_file_offset, @@ -4529,14 +4532,14 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, if (need_mutex) mysql_mutex_lock(&LOCK_index); - if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) + if (unlikely((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) ) { sql_print_error("MYSQL_BIN_LOG::purge_logs was called with file %s not " "listed in the index.", to_log); goto err; } - if ((error= open_purge_index_file(TRUE))) + if (unlikely((error= open_purge_index_file(TRUE)))) { sql_print_error("MYSQL_BIN_LOG::purge_logs failed to sync the index file."); goto err; @@ -4546,12 +4549,12 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, File name exists in index file; delete until we find this file or a file that is used. */ - if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/))) + if (unlikely((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))) goto err; while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) && can_purge_log(log_info.log_file_name)) { - if ((error= register_purge_index_entry(log_info.log_file_name))) + if (unlikely((error= register_purge_index_entry(log_info.log_file_name)))) { sql_print_error("MYSQL_BIN_LOG::purge_logs failed to copy %s to register file.", log_info.log_file_name); @@ -4564,14 +4567,14 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE();); - if ((error= sync_purge_index_file())) + if (unlikely((error= sync_purge_index_file()))) { sql_print_error("MYSQL_BIN_LOG::purge_logs failed to flush register file."); goto err; } /* We know how many files to delete. Update index file. */ - if ((error=update_log_index(&log_info, need_update_threads))) + if (unlikely((error=update_log_index(&log_info, need_update_threads)))) { sql_print_error("MYSQL_BIN_LOG::purge_logs failed to update the index file"); goto err; @@ -4662,8 +4665,9 @@ int MYSQL_BIN_LOG::sync_purge_index_file() int error= 0; DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file"); - if ((error= flush_io_cache(&purge_index_file)) || - (error= my_sync(purge_index_file.file, MYF(MY_WME|MY_SYNC_FILESIZE)))) + if (unlikely((error= flush_io_cache(&purge_index_file))) || + unlikely((error= my_sync(purge_index_file.file, + MYF(MY_WME | MY_SYNC_FILESIZE))))) DBUG_RETURN(error); DBUG_RETURN(error); @@ -4674,8 +4678,9 @@ int MYSQL_BIN_LOG::register_purge_index_entry(const char *entry) int error= 0; DBUG_ENTER("MYSQL_BIN_LOG::register_purge_index_entry"); - if ((error=my_b_write(&purge_index_file, (const uchar*)entry, strlen(entry))) || - (error=my_b_write(&purge_index_file, (const uchar*)"\n", 1))) + if (unlikely((error=my_b_write(&purge_index_file, (const uchar*)entry, + strlen(entry)))) || + unlikely((error=my_b_write(&purge_index_file, (const uchar*)"\n", 1)))) DBUG_RETURN (error); DBUG_RETURN(error); @@ -4698,7 +4703,8 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space, DBUG_ASSERT(my_b_inited(&purge_index_file)); - if ((error=reinit_io_cache(&purge_index_file, READ_CACHE, 0, 0, 0))) + if (unlikely((error= reinit_io_cache(&purge_index_file, READ_CACHE, 0, 0, + 0)))) { sql_print_error("MYSQL_BIN_LOG::purge_index_entry failed to reinit register file " "for read"); @@ -4727,7 +4733,8 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space, /* Get rid of the trailing '\n' */ log_info.log_file_name[length-1]= 0; - if (!mysql_file_stat(m_key_file_log, log_info.log_file_name, &s, MYF(0))) + if (unlikely(!mysql_file_stat(m_key_file_log, log_info.log_file_name, &s, + MYF(0)))) { if (my_errno == ENOENT) { @@ -4774,7 +4781,8 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space, } else { - if ((error= find_log_pos(&check_log_info, log_info.log_file_name, need_mutex))) + if (unlikely((error= find_log_pos(&check_log_info, + log_info.log_file_name, need_mutex)))) { if (error != LOG_INFO_EOF) { @@ -4887,7 +4895,7 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time) mysql_mutex_lock(&LOCK_index); to_log[0]= 0; - if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/))) + if (unlikely((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))) goto err; while (strcmp(log_file_name, log_info.log_file_name) && @@ -5154,7 +5162,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) We have to do this here and not in open as we want to store the new file name in the current binary log file. */ - if ((error= generate_new_name(new_name, name, 0))) + if (unlikely((error= generate_new_name(new_name, name, 0)))) { #ifdef ENABLE_AND_FIX_HANG close_on_error= TRUE; @@ -5198,7 +5206,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) log rotation should give the waiting thread a signal to discover EOF and move on to the next log. */ - if ((error= flush_io_cache(&log_file))) + if (unlikely((error= flush_io_cache(&log_file)))) { close_on_error= TRUE; goto end; @@ -5244,7 +5252,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) /* reopen index binlog file, BUG#34582 */ file_to_open= index_file_name; error= open_index_file(index_file_name, 0, FALSE); - if (!error) + if (likely(!error)) { /* reopen the binary log file. */ file_to_open= new_name_ptr; @@ -5253,7 +5261,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) } /* handle reopening errors */ - if (error) + if (unlikely(error)) { my_error(ER_CANT_OPEN_FILE, MYF(ME_FATALERROR), file_to_open, error); close_on_error= TRUE; @@ -5269,7 +5277,7 @@ end: mysql_file_close(old_file, MYF(MY_WME)); } - if (error && close_on_error /* rotate or reopen failed */) + if (unlikely(error && close_on_error)) /* rotate or reopen failed */ { /* Close whatever was left opened. @@ -5395,7 +5403,7 @@ bool MYSQL_BIN_LOG::write_event_buffer(uchar* buf, uint len) error= new_file_without_locking(); err: my_safe_afree(ebuf, len); - if (!error) + if (likely(!error)) update_binlog_end_pos(); DBUG_RETURN(error); } @@ -5778,14 +5786,14 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional, Annotate_rows_log_event anno(table->in_use, is_transactional, false); /* Annotate event should be written not more than once */ *with_annotate= 0; - if ((error= writer.write(&anno))) + if (unlikely((error= writer.write(&anno)))) { if (my_errno == EFBIG) cache_data->set_incident(); DBUG_RETURN(error); } } - if ((error= writer.write(&the_event))) + if (unlikely((error= writer.write(&the_event)))) DBUG_RETURN(error); binlog_table_maps++; @@ -6433,7 +6441,7 @@ err: bool check_purge= false; DBUG_ASSERT(!is_relay_log); - if (!error) + if (likely(!error)) { bool synced; @@ -6463,7 +6471,7 @@ err: it's list before dump-thread tries to send it */ update_binlog_end_pos(offset); - if ((error= rotate(false, &check_purge))) + if (unlikely((error= rotate(false, &check_purge)))) check_purge= false; } } @@ -6501,7 +6509,7 @@ err: checkpoint_and_purge(prev_binlog_id); } - if (error) + if (unlikely(error)) { set_write_error(thd, is_trans_cache); if (check_write_error(thd) && cache_data && @@ -6697,7 +6705,7 @@ int MYSQL_BIN_LOG::rotate(bool force_rotate, bool* check_purge) */ mark_xids_active(binlog_id, 1); - if ((error= new_file_without_locking())) + if (unlikely((error= new_file_without_locking()))) { /** Be conservative... There are possible lost events (eg, @@ -6893,7 +6901,7 @@ int MYSQL_BIN_LOG::rotate_and_purge(bool force_rotate, if (err_gtid < 0) error= 1; // otherwise error is propagated the user } - else if ((error= rotate(force_rotate, &check_purge))) + else if (unlikely((error= rotate(force_rotate, &check_purge)))) check_purge= false; /* NOTE: Run purge_logs wo/ holding LOCK_log because it does not need @@ -7134,6 +7142,8 @@ int query_error_code(THD *thd, bool not_killed) if (not_killed || (killed_mask_hard(thd->killed) == KILL_BAD_DATA)) { error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0; + if (!error) + return error; /* thd->get_get_stmt_da()->sql_errno() might be ER_SERVER_SHUTDOWN or ER_QUERY_INTERRUPTED, So here we need to make sure that error @@ -7184,11 +7194,11 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd) if (likely(is_open())) { prev_binlog_id= current_binlog_id; - if (!(error= write_incident_already_locked(thd)) && - !(error= flush_and_sync(0))) + if (likely(!(error= write_incident_already_locked(thd))) && + likely(!(error= flush_and_sync(0)))) { update_binlog_end_pos(); - if ((error= rotate(false, &check_purge))) + if (unlikely((error= rotate(false, &check_purge)))) check_purge= false; } @@ -7431,7 +7441,7 @@ MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry *orig_entry) &wfc->LOCK_wait_commit, &stage_waiting_for_prior_transaction_to_commit, &old_stage); - while ((loc_waitee= wfc->waitee) && !orig_entry->thd->check_killed()) + while ((loc_waitee= wfc->waitee) && !orig_entry->thd->check_killed(1)) mysql_cond_wait(&wfc->COND_wait_commit, &wfc->LOCK_wait_commit); wfc->opaque_pointer= NULL; DBUG_PRINT("info", ("After waiting for prior commit, queued_by_other=%d", @@ -7864,7 +7874,8 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) */ DBUG_ASSERT(!cache_mngr->stmt_cache.empty() || !cache_mngr->trx_cache.empty()); - if ((current->error= write_transaction_or_stmt(current, commit_id))) + if (unlikely((current->error= write_transaction_or_stmt(current, + commit_id)))) current->commit_errno= errno; strmake_buf(cache_mngr->last_commit_pos_file, log_file_name); @@ -7892,7 +7903,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) } bool synced= 0; - if (flush_and_sync(&synced)) + if (unlikely(flush_and_sync(&synced))) { for (current= queue; current != NULL; current= current->next) { @@ -7916,12 +7927,13 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) for (current= queue; current != NULL; current= current->next) { #ifdef HAVE_REPLICATION - if (!current->error && - repl_semisync_master. - report_binlog_update(current->thd, - current->cache_mngr->last_commit_pos_file, - current->cache_mngr-> - last_commit_pos_offset)) + if (likely(!current->error) && + unlikely(repl_semisync_master. + report_binlog_update(current->thd, + current->cache_mngr-> + last_commit_pos_file, + current->cache_mngr-> + last_commit_pos_offset))) { current->error= ER_ERROR_ON_WRITE; current->commit_errno= -1; @@ -7939,7 +7951,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) */ update_binlog_end_pos(commit_offset); - if (any_error) + if (unlikely(any_error)) sql_print_error("Failed to run 'after_flush' hooks"); } @@ -8004,7 +8016,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) { last= current->next == NULL; #ifdef HAVE_REPLICATION - if (!current->error) + if (likely(!current->error)) current->error= repl_semisync_master.wait_after_sync(current->cache_mngr-> last_commit_pos_file, @@ -8066,7 +8078,7 @@ MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader) DEBUG_SYNC(leader->thd, "commit_loop_entry_commit_ordered"); ++num_commits; - if (current->cache_mngr->using_xa && !current->error && + if (current->cache_mngr->using_xa && likely(!current->error) && DBUG_EVALUATE_IF("skip_commit_ordered", 0, 1)) run_commit_ordered(current->thd, current->all); current->thd->wakeup_subsequent_commits(current->error); @@ -8158,12 +8170,12 @@ MYSQL_BIN_LOG::write_transaction_or_stmt(group_commit_entry *entry, } } - if (mngr->get_binlog_cache_log(FALSE)->error) // Error on read + if (unlikely(mngr->get_binlog_cache_log(FALSE)->error)) { entry->error_cache= &mngr->stmt_cache.cache_log; DBUG_RETURN(ER_ERROR_ON_WRITE); } - if (mngr->get_binlog_cache_log(TRUE)->error) // Error on read + if (unlikely(mngr->get_binlog_cache_log(TRUE)->error)) // Error on read { entry->error_cache= &mngr->trx_cache.cache_log; DBUG_RETURN(ER_ERROR_ON_WRITE); @@ -8455,7 +8467,8 @@ void MYSQL_BIN_LOG::close(uint exiting) if ((exiting & LOG_CLOSE_INDEX) && my_b_inited(&index_file)) { end_io_cache(&index_file); - if (mysql_file_close(index_file.file, MYF(0)) < 0 && ! write_error) + if (unlikely(mysql_file_close(index_file.file, MYF(0)) < 0) && + ! write_error) { write_error= 1; sql_print_error(ER_THD_OR_DEFAULT(current_thd, ER_ERROR_ON_WRITE), @@ -8516,10 +8529,9 @@ void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg) 0 String is not a number */ -static bool test_if_number(register const char *str, - ulong *res, bool allow_wildcards) +static bool test_if_number(const char *str, ulong *res, bool allow_wildcards) { - reg2 int flag; + int flag; const char *start; DBUG_ENTER("test_if_number"); @@ -8775,16 +8787,20 @@ void sql_print_information(const char *format, ...) va_list args; DBUG_ENTER("sql_print_information"); - if (disable_log_notes) - DBUG_VOID_RETURN; // Skip notes during start/shutdown - va_start(args, format); - error_log_print(INFORMATION_LEVEL, format, args); + sql_print_information_v(format, args); va_end(args); DBUG_VOID_RETURN; } +void sql_print_information_v(const char *format, va_list ap) +{ + if (disable_log_notes) + return; // Skip notes during start/shutdown + + error_log_print(INFORMATION_LEVEL, format, ap); +} void TC_LOG::run_prepare_ordered(THD *thd, bool all) @@ -10215,7 +10231,7 @@ MYSQL_BIN_LOG::do_binlog_recovery(const char *opt_name, bool do_xa_recovery) char log_name[FN_REFLEN]; int error; - if ((error= find_log_pos(&log_info, NullS, 1))) + if (unlikely((error= find_log_pos(&log_info, NullS, 1)))) { /* If there are no binlog files (LOG_INFO_EOF), then we still try to read @@ -10273,7 +10289,7 @@ MYSQL_BIN_LOG::do_binlog_recovery(const char *opt_name, bool do_xa_recovery) else { error= read_state_from_file(); - if (error == 2) + if (unlikely(error == 2)) { /* The binlog exists, but the .state file is missing. This is normal if diff --git a/sql/log.h b/sql/log.h index 098824d9ec8..7dfdb36c442 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1111,6 +1111,7 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args); void sql_print_error(const char *format, ...); void sql_print_warning(const char *format, ...); void sql_print_information(const char *format, ...); +void sql_print_information_v(const char *format, va_list ap); typedef void (*sql_print_message_func)(const char *format, ...); extern sql_print_message_func sql_print_message_handlers[]; diff --git a/sql/log_event.cc b/sql/log_event.cc index cd47cbba9bd..7a6d0a1821b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -53,6 +53,7 @@ #include "rpl_constants.h" #include "sql_digest.h" #include "zlib.h" +#include "my_atomic.h" #define my_b_write_string(A, B) my_b_write((A), (uchar*)(B), (uint) (sizeof(B) - 1)) @@ -394,7 +395,7 @@ static bool pretty_print_str(IO_CACHE* cache, const char* str, int len) error= my_b_write_byte(cache, c); break; } - if (error) + if (unlikely(error)) goto err; } return my_b_write_byte(cache, '\''); @@ -1924,7 +1925,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, res->register_temp_buf(event.release(), true); err: - if (error) + if (unlikely(error)) { DBUG_ASSERT(!res); #ifdef MYSQL_CLIENT @@ -3120,7 +3121,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td, typestr, sizeof(typestr)); error= copy_event_cache_to_string_and_reinit(&tmp_cache, &review_str); close_cached_file(&tmp_cache); - if (error) + if (unlikely(error)) return 0; switch (td->type(i)) // Converting a string to HEX format @@ -3740,15 +3741,15 @@ bool Log_event::print_base64(IO_CACHE* file, } if (my_b_tell(file) == 0) - if (my_b_write_string(file, "\nBINLOG '\n")) + if (unlikely(my_b_write_string(file, "\nBINLOG '\n"))) error= 1; - if (!error && my_b_printf(file, "%s\n", tmp_str)) + if (likely(!error) && unlikely(my_b_printf(file, "%s\n", tmp_str))) error= 1; - if (!more && !error) - if (my_b_printf(file, "'%s\n", print_event_info->delimiter)) + if (!more && likely(!error)) + if (unlikely(my_b_printf(file, "'%s\n", print_event_info->delimiter))) error= 1; my_free(tmp_str); - if (error) + if (unlikely(error)) goto err; } @@ -3855,7 +3856,7 @@ bool Log_event::print_base64(IO_CACHE* file, error= ev->print_verbose(&tmp_cache, print_event_info); close_cached_file(&tmp_cache); - if (error) + if (unlikely(error)) { delete ev; goto err; @@ -3868,7 +3869,7 @@ bool Log_event::print_base64(IO_CACHE* file, ev->count_row_events(print_event_info); #endif delete ev; - if (error) + if (unlikely(error)) goto err; } } @@ -4830,6 +4831,24 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, db= (char *)start; query= (char *)(start + db_len + 1); q_len= data_len - db_len -1; + + if (data_len && (data_len < db_len || + data_len < q_len || + data_len != (db_len + q_len + 1))) + { + q_len= 0; + query= NULL; + DBUG_VOID_RETURN; + } + + uint32 max_length= uint32(event_len - ((const char*)(end + db_len + 1) - + (buf - common_header_len))); + if (q_len != max_length) + { + q_len= 0; + query= NULL; + DBUG_VOID_RETURN; + } /** Append the db length at the end of the buffer. This will be used by Query_cache::send_result_to_client() in case the query cache is On. @@ -5376,6 +5395,19 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, you. */ thd->catalog= catalog_len ? (char *) catalog : (char *)""; + + size_t valid_len= Well_formed_prefix(system_charset_info, + db, db_len, NAME_LEN).length(); + + if (valid_len != db_len) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid database name in Query event."); + thd->is_slave_error= true; + goto end; + } + new_db.length= db_len; new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); thd->set_db(&new_db); /* allocates a copy of 'db' */ @@ -5415,7 +5447,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, thd->variables.pseudo_thread_id= thread_id; // for temp tables DBUG_PRINT("query",("%s", thd->query())); - if (!(expected_error= error_code) || + if (unlikely(!(expected_error= error_code)) || ignored_error_code(expected_error) || !unexpected_error_code(expected_error)) { @@ -5517,7 +5549,23 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, } else thd->variables.collation_database= thd->db_charset; - + + { + const CHARSET_INFO *cs= thd->charset(); + /* + We cannot ask for parsing a statement using a character set + without state_maps (parser internal data). + */ + if (!cs->state_map) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "character_set cannot be parsed"); + thd->is_slave_error= true; + goto end; + } + } + /* Record any GTID in the same transaction, so slave state is transactionally consistent. @@ -5531,8 +5579,10 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, rgi->gtid_pending= false; gtid= rgi->current_gtid; - if (rpl_global_gtid_slave_state->record_gtid(thd, >id, sub_id, - true, false, &hton)) + if (unlikely(rpl_global_gtid_slave_state->record_gtid(thd, >id, + sub_id, + true, false, + &hton))) { int errcode= thd->get_stmt_da()->sql_errno(); if (!is_parallel_retry_error(rgi, errcode)) @@ -5559,7 +5609,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, it is a concurrency issue or ignorable issue, effects of the statement should be rolled back. */ - if (expected_error && + if (unlikely(expected_error) && (ignored_error_code(expected_error) || concurrency_error_code(expected_error))) { @@ -5628,7 +5678,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query()); } /* If the query was not ignored, it is printed to the general log */ - if (!thd->is_error() || + if (likely(!thd->is_error()) || thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE) general_log_write(thd, COM_QUERY, thd->query(), thd->query_length()); else @@ -5667,7 +5717,7 @@ compare_errors: DBUG_PRINT("info",("expected_error: %d sql_errno: %d", expected_error, actual_error)); - if ((expected_error && + if ((unlikely(expected_error) && !test_if_equal_repl_errors(expected_error, actual_error) && !concurrency_error_code(expected_error)) && !ignored_error_code(actual_error) && @@ -5702,7 +5752,7 @@ compare_errors: /* Other cases: mostly we expected no error and get one. */ - else if (thd->is_slave_error || thd->is_fatal_error) + else if (unlikely(thd->is_slave_error || thd->is_fatal_error)) { if (!is_parallel_retry_error(rgi, actual_error)) rli->report(ERROR_LEVEL, actual_error, rgi->gtid_info(), @@ -5752,7 +5802,7 @@ compare_errors: } end: - if (sub_id && !thd->is_slave_error) + if (unlikely(sub_id && !thd->is_slave_error)) rpl_global_gtid_slave_state->update_state_hash(sub_id, >id, hton, rgi); /* @@ -6073,7 +6123,13 @@ int Start_log_event_v3::do_apply_event(rpl_group_info *rgi) */ break; default: - /* this case is impossible */ + /* + This case is not expected. It can be either an event corruption or an + unsupported binary log version. + */ + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Binlog version not supported"); DBUG_RETURN(1); } DBUG_RETURN(error); @@ -6992,6 +7048,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, fields = (char*)field_lens + num_fields; table_name = fields + field_block_len; + if (strlen(table_name) > NAME_LEN) + goto err; + db = table_name + table_name_len + 1; DBUG_EXECUTE_IF ("simulate_invalid_address", db_len = data_len;); @@ -7419,7 +7478,7 @@ error: DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", thd->is_slave_error= 0; thd->is_fatal_error= 1;); - if (thd->is_slave_error) + if (unlikely(thd->is_slave_error)) { /* this err/sql_errno code is copy-paste from net_send_error() */ const char *err; @@ -7442,7 +7501,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", } free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) { char buf[256]; my_snprintf(buf, sizeof(buf), @@ -7973,6 +8032,23 @@ Gtid_log_event::do_apply_event(rpl_group_info *rgi) } DBUG_ASSERT((bits & OPTION_GTID_BEGIN) == 0); + + Master_info *mi=rgi->rli->mi; + switch (flags2 & (FL_DDL | FL_TRANSACTIONAL)) + { + case FL_TRANSACTIONAL: + my_atomic_add64_explicit((volatile int64 *)&mi->total_trans_groups, 1, + MY_MEMORY_ORDER_RELAXED); + break; + case FL_DDL: + my_atomic_add64_explicit((volatile int64 *)&mi->total_ddl_groups, 1, + MY_MEMORY_ORDER_RELAXED); + break; + default: + my_atomic_add64_explicit((volatile int64 *)&mi->total_non_trans_groups, 1, + MY_MEMORY_ORDER_RELAXED); + } + if (flags2 & FL_STANDALONE) return 0; @@ -8841,7 +8917,7 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi) gtid= rgi->current_gtid; err= rpl_global_gtid_slave_state->record_gtid(thd, >id, sub_id, true, false, &hton); - if (err) + if (unlikely(err)) { int ec= thd->get_stmt_da()->sql_errno(); /* @@ -8872,7 +8948,7 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi) res= trans_commit(thd); /* Automatically rolls back on error. */ thd->mdl_context.release_transactional_locks(); - if (!res && sub_id) + if (likely(!res) && sub_id) rpl_global_gtid_slave_state->update_state_hash(sub_id, >id, hton, rgi); /* @@ -9048,6 +9124,13 @@ User_var_log_event(const char* buf, uint event_len, buf+= description_event->common_header_len + description_event->post_header_len[USER_VAR_EVENT-1]; name_len= uint4korr(buf); + /* Avoid reading out of buffer */ + if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len) + { + error= true; + goto err; + } + name= (char *) buf + UV_NAME_LEN_SIZE; /* @@ -9104,7 +9187,12 @@ User_var_log_event(const char* buf, uint event_len, Old events will not have this extra byte, thence, we keep the flags set to UNDEF_F. */ - size_t bytes_read= ((val + val_len) - buf_start); + size_t bytes_read= (val + val_len) - buf_start; + if (bytes_read > size_t(event_len)) + { + error= true; + goto err; + } if ((data_written - bytes_read) > 0) { flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + @@ -9114,7 +9202,7 @@ User_var_log_event(const char* buf, uint event_len, } err: - if (error) + if (unlikely(error)) name= 0; } @@ -9294,7 +9382,7 @@ bool User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) cs->csname, hex_str, cs->name, print_event_info->delimiter); my_free(hex_str); - if (error) + if (unlikely(error)) goto err; break; } @@ -9336,7 +9424,12 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi) } if (!(charset= get_charset(charset_number, MYF(MY_WME)))) + { + rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid character set for User var event"); DBUG_RETURN(1); + } LEX_CSTRING user_var_name; user_var_name.str= name; user_var_name.length= name_len; @@ -9351,12 +9444,26 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi) { switch (type) { case REAL_RESULT: + if (val_len != 8) + { + rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } float8get(real_val, val); it= new (thd->mem_root) Item_float(thd, real_val, 0); val= (char*) &real_val; // Pointer to value in native format val_len= 8; break; case INT_RESULT: + if (val_len != 8) + { + rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } int_val= (longlong) uint8korr(val); it= new (thd->mem_root) Item_int(thd, int_val); val= (char*) &int_val; // Pointer to value in native format @@ -9364,6 +9471,13 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi) break; case DECIMAL_RESULT: { + if (val_len < 3) + { + rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } Item_decimal *dec= new (thd->mem_root) Item_decimal(thd, (uchar*) val+2, val[0], val[1]); it= dec; val= (char *)dec->val_decimal(NULL); @@ -9806,9 +9920,9 @@ int Create_file_log_event::do_apply_event(rpl_group_info *rgi) error=0; // Everything is ok err: - if (error) + if (unlikely(error)) end_io_cache(&file); - if (fd >= 0) + if (likely(fd >= 0)) mysql_file_close(fd, MYF(0)); return error != 0; } @@ -10519,7 +10633,7 @@ Execute_load_query_log_event::do_apply_event(rpl_group_info *rgi) If there was an error the slave is going to stop, leave the file so that we can re-execute this event at START SLAVE. */ - if (!error) + if (unlikely(!error)) mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME)); my_free(buf); @@ -10779,6 +10893,14 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); m_width = net_field_length(&ptr_after_width); DBUG_PRINT("debug", ("m_width=%lu", m_width)); + + /* Avoid reading out of buffer */ + if (ptr_after_width + (m_width + 7) / 8 > (uchar*)buf + event_len) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + /* if my_bitmap_init fails, catched in is_valid() */ if (likely(!my_bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, @@ -10827,7 +10949,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; - size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); + size_t const read_size= ptr_rows_data - (const unsigned char *) buf; + if (read_size > event_len) + { + DBUG_VOID_RETURN; + } + size_t const data_size= event_len - read_size; DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu", m_table_id, m_flags, m_width, (ulong) data_size)); @@ -11146,7 +11273,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) lex->query_tables_last= &tables->next_global; } } - if (open_and_lock_tables(thd, rgi->tables_to_lock, FALSE, 0)) + if (unlikely(open_and_lock_tables(thd, rgi->tables_to_lock, FALSE, 0))) { uint actual_error= thd->get_stmt_da()->sql_errno(); #ifdef WITH_WSREP @@ -11399,13 +11526,13 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) error= do_exec_row(rgi); - if (error) + if (unlikely(error)) DBUG_PRINT("info", ("error: %s", HA_ERR(error))); DBUG_ASSERT(error != HA_ERR_RECORD_DELETED); table->in_use = old_thd; - if (error) + if (unlikely(error)) { int actual_error= convert_handler_error(error, thd, table); bool idempotent_error= (idempotent_error_code(error) && @@ -11436,12 +11563,12 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) DBUG_PRINT("info", ("curr_row: %p; curr_row_end: %p; rows_end:%p", m_curr_row, m_curr_row_end, m_rows_end)); - if (!m_curr_row_end && !error) + if (!m_curr_row_end && likely(!error)) error= unpack_current_row(rgi); m_curr_row= m_curr_row_end; - if (error == 0 && !transactional_table) + if (likely(error == 0) && !transactional_table) thd->transaction.all.modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table= TRUE; } // row processing loop @@ -11463,7 +11590,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) const_cast<Relay_log_info*>(rli)->abort_slave= 1;); } - if ((error= do_after_row_operations(rli, error)) && + if (unlikely(error= do_after_row_operations(rli, error)) && ignored_error_code(convert_handler_error(error, thd, table))) { @@ -11477,7 +11604,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) } // if (table) - if (error) + if (unlikely(error)) { slave_rows_error_report(ERROR_LEVEL, error, rgi, thd, table, get_type_str(), @@ -11506,7 +11633,8 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) } #endif /* WITH_WSREP && HAVE_QUERY_CACHE */ - if (get_flags(STMT_END_F) && (error= rows_event_stmt_cleanup(rgi, thd))) + if (unlikely(get_flags(STMT_END_F) && + (error= rows_event_stmt_cleanup(rgi, thd)))) slave_rows_error_report(ERROR_LEVEL, thd->is_error() ? 0 : error, rgi, thd, table, @@ -12863,7 +12991,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability * ultimately. Still todo: fix */ } - if ((local_error= m_table->file->ha_end_bulk_insert())) + if (unlikely((local_error= m_table->file->ha_end_bulk_insert()))) { m_table->file->print_error(local_error, MYF(0)); } @@ -12981,7 +13109,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, prepare_record(table, m_width, true); /* unpack row into table->record[0] */ - if ((error= unpack_current_row(rgi))) + if (unlikely((error= unpack_current_row(rgi)))) { table->file->print_error(error, MYF(0)); DBUG_RETURN(error); @@ -13021,9 +13149,9 @@ Rows_log_event::write_row(rpl_group_info *rgi, DBUG_PRINT_BITSET("debug", "read_set: %s", table->read_set); if (invoke_triggers && - process_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE, TRUE)) + unlikely(process_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE, TRUE))) { - DBUG_RETURN(HA_ERR_GENERIC); // in case if error is not set yet + DBUG_RETURN(HA_ERR_GENERIC); // in case if error is not set yet } // Handle INSERT. @@ -13047,7 +13175,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, if (table->s->sequence) error= update_sequence(); - else while ((error= table->file->ha_write_row(table->record[0]))) + else while (unlikely(error= table->file->ha_write_row(table->record[0]))) { if (error == HA_ERR_LOCK_DEADLOCK || error == HA_ERR_LOCK_WAIT_TIMEOUT || @@ -13079,11 +13207,9 @@ Rows_log_event::write_row(rpl_group_info *rgi, { DBUG_PRINT("info",("Locating offending record using rnd_pos()")); error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -13114,11 +13240,9 @@ Rows_log_event::write_row(rpl_group_info *rgi, (const uchar*)key.get(), HA_WHOLE_KEY, HA_READ_KEY_EXACT); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error))); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -13189,18 +13313,20 @@ Rows_log_event::write_row(rpl_group_info *rgi, { DBUG_PRINT("info",("Deleting offending row and trying to write new one again")); if (invoke_triggers && - process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, TRUE)) + unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, + TRUE))) error= HA_ERR_GENERIC; // in case if error is not set yet else { - if ((error= table->file->ha_delete_row(table->record[1]))) + if (unlikely((error= table->file->ha_delete_row(table->record[1])))) { DBUG_PRINT("info",("ha_delete_row() returns error %d",error)); table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } if (invoke_triggers && - process_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER, TRUE)) + unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER, + TRUE))) DBUG_RETURN(HA_ERR_GENERIC); // in case if error is not set yet } /* Will retry ha_write_row() with the offending row removed. */ @@ -13208,7 +13334,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, } if (invoke_triggers && - process_triggers(TRG_EVENT_INSERT, TRG_ACTION_AFTER, TRUE)) + unlikely(process_triggers(TRG_EVENT_INSERT, TRG_ACTION_AFTER, TRUE))) error= HA_ERR_GENERIC; // in case if error is not set yet DBUG_RETURN(error); @@ -13262,7 +13388,7 @@ Write_rows_log_event::do_exec_row(rpl_group_info *rgi) error= write_row(rgi, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT); thd_proc_info(thd, tmp); - if (error && !thd->is_error()) + if (unlikely(error) && unlikely(!thd->is_error())) { DBUG_ASSERT(0); my_error(ER_UNKNOWN_ERROR, MYF(0)); @@ -13613,11 +13739,9 @@ int Rows_log_event::find_row(rpl_group_info *rgi) DBUG_RETURN(error); error= table->file->ha_rnd_pos_by_record(table->record[0]); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); } DBUG_RETURN(error); @@ -13677,13 +13801,12 @@ int Rows_log_event::find_row(rpl_group_info *rgi) table->record[0][table->s->null_bytes - 1]|= 256U - (1U << table->s->last_null_bit_pos); - if ((error= table->file->ha_index_read_map(table->record[0], m_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if (unlikely((error= table->file->ha_index_read_map(table->record[0], + m_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)))) { DBUG_PRINT("info",("no record matching the key found in the table")); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); table->file->ha_index_end(); goto end; @@ -13759,9 +13882,6 @@ int Rows_log_event::find_row(rpl_group_info *rgi) { while ((error= table->file->ha_index_next(table->record[0]))) { - /* We just skip records that has already been deleted */ - if (error == HA_ERR_RECORD_DELETED) - continue; DBUG_PRINT("info",("no record matching the given row found")); table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -13776,7 +13896,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi) DBUG_EXECUTE_IF("slave_crash_if_table_scan", abort();); /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init_with_error(1))) + if (unlikely((error= table->file->ha_rnd_init_with_error(1)))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); @@ -13788,10 +13908,9 @@ int Rows_log_event::find_row(rpl_group_info *rgi) /* Continue until we find the right record or have made a full loop */ do { - restart_rnd_next: error= table->file->ha_rnd_next(table->record[0]); - if (error) + if (unlikely(error)) DBUG_PRINT("info", ("error: %s", HA_ERR(error))); switch (error) { @@ -13804,13 +13923,6 @@ int Rows_log_event::find_row(rpl_group_info *rgi) table->file->ha_rnd_end(); goto end; - /* - If the record was deleted, we pick the next one without doing - any comparisons. - */ - case HA_ERR_RECORD_DELETED: - goto restart_rnd_next; - default: DBUG_PRINT("info", ("Failed to get next record" " (rnd_next returns %d)",error)); @@ -13941,7 +14053,7 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi) #endif /* WSREP_PROC_INFO */ thd_proc_info(thd, message); - if (!(error= find_row(rgi))) + if (likely(!(error= find_row(rgi)))) { /* Delete the record found, located in record[0] @@ -13956,9 +14068,9 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi) thd_proc_info(thd, message); if (invoke_triggers && - process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)) + unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE))) error= HA_ERR_GENERIC; // in case if error is not set yet - if (!error) + if (likely(!error)) { m_table->mark_columns_per_binlog_row_image(); if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP)) @@ -13976,8 +14088,8 @@ int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi) } m_table->default_column_bitmaps(); } - if (invoke_triggers && !error && - process_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER, FALSE)) + if (invoke_triggers && likely(!error) && + unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER, FALSE))) error= HA_ERR_GENERIC; // in case if error is not set yet m_table->file->ha_index_or_rnd_end(); } @@ -14162,7 +14274,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) thd_proc_info(thd, message); int error= find_row(rgi); - if (error) + if (unlikely(error)) { /* We need to read the second image in the event of error to be @@ -14198,7 +14310,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) /* this also updates m_curr_row_end */ thd_proc_info(thd, message); - if ((error= unpack_current_row(rgi, &m_cols_ai))) + if (unlikely((error= unpack_current_row(rgi, &m_cols_ai)))) goto err; /* @@ -14225,7 +14337,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) thd_proc_info(thd, message); if (invoke_triggers && - process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, TRUE)) + unlikely(process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, TRUE))) { error= HA_ERR_GENERIC; // in case if error is not set yet goto err; @@ -14239,7 +14351,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP)) m_table->vers_update_fields(); error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]); - if (error == HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error == HA_ERR_RECORD_IS_THE_SAME)) error= 0; if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP)) { @@ -14249,8 +14361,8 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi) } m_table->default_column_bitmaps(); - if (invoke_triggers && !error && - process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE)) + if (invoke_triggers && likely(!error) && + unlikely(process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))) error= HA_ERR_GENERIC; // in case if error is not set yet thd_proc_info(thd, tmp); @@ -14391,7 +14503,7 @@ void Incident_log_event::pack_info(Protocol *protocol) #endif /* MYSQL_CLIENT */ -#if WITH_WSREP && !defined(MYSQL_CLIENT) +#if defined(WITH_WSREP) && !defined(MYSQL_CLIENT) /* read the first event from (*buf). The size of the (*buf) is (*buf_len). At the end (*buf) is shitfed to point to the following event or NULL and diff --git a/sql/log_event.h b/sql/log_event.h index a2b58b1e023..84025554ee9 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -5034,7 +5034,8 @@ public: DBUG_ENTER("Incident_log_event::Incident_log_event"); DBUG_PRINT("enter", ("m_incident: %d", m_incident)); m_message.length= 0; - if (!(m_message.str= (char*) my_malloc(msg->length+1, MYF(MY_WME)))) + if (unlikely(!(m_message.str= (char*) my_malloc(msg->length+1, + MYF(MY_WME))))) { /* Mark this event invalid */ m_incident= INCIDENT_NONE; diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 20986050203..66c4c2bef42 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2007, 2016, Oracle and/or its affiliates. +/* Copyright (c) 2007, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -98,7 +99,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) */ ev_thd->lex->set_stmt_row_injection(); - if (open_and_lock_tables(ev_thd, rgi->tables_to_lock, FALSE, 0)) + if (unlikely(open_and_lock_tables(ev_thd, rgi->tables_to_lock, FALSE, 0))) { uint actual_error= ev_thd->get_stmt_da()->sql_errno(); if (ev_thd->is_slave_error || ev_thd->is_fatal_error) @@ -227,7 +228,8 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) while (error == 0 && row_start < ev->m_rows_end) { uchar const *row_end= NULL; - if ((error= do_prepare_row(ev_thd, rgi, table, row_start, &row_end))) + if (unlikely((error= do_prepare_row(ev_thd, rgi, table, row_start, + &row_end)))) break; // We should perform the after-row operation even in // the case of error @@ -266,7 +268,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi) error= do_after_row_operations(table, error); } - if (error) + if (unlikely(error)) { /* error has occurred during the transaction */ rli->report(ERROR_LEVEL, ev_thd->get_stmt_da()->sql_errno(), NULL, "Error in %s event: error during transaction execution " @@ -477,14 +479,14 @@ replace_record(THD *thd, TABLE *table, DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set); #endif - while ((error= table->file->ha_write_row(table->record[0]))) + while (unlikely(error= table->file->ha_write_row(table->record[0]))) { if (error == HA_ERR_LOCK_DEADLOCK || error == HA_ERR_LOCK_WAIT_TIMEOUT) { table->file->print_error(error, MYF(0)); /* to check at exec_relay_log_event */ DBUG_RETURN(error); } - if ((keynum= table->file->get_dup_key(error)) < 0) + if (unlikely((keynum= table->file->get_dup_key(error)) < 0)) { table->file->print_error(error, MYF(0)); /* @@ -508,18 +510,16 @@ replace_record(THD *thd, TABLE *table, if (table->file->ha_table_flags() & HA_DUPLICATE_POS) { error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } } else { - if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) + if (unlikely(table->file->extra(HA_EXTRA_FLUSH_CACHE))) { DBUG_RETURN(my_errno); } @@ -527,7 +527,7 @@ replace_record(THD *thd, TABLE *table, if (key.get() == NULL) { key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length))); - if (key.get() == NULL) + if (unlikely(key.get() == NULL)) DBUG_RETURN(ENOMEM); } @@ -537,11 +537,9 @@ replace_record(THD *thd, TABLE *table, (const uchar*)key.get(), HA_WHOLE_KEY, HA_READ_KEY_EXACT); - if (error) + if (unlikely(error)) { DBUG_PRINT("info", ("index_read_idx() returns error %d", error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -577,7 +575,7 @@ replace_record(THD *thd, TABLE *table, { error=table->file->ha_update_row(table->record[1], table->record[0]); - if (error && error != HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error) && error != HA_ERR_RECORD_IS_THE_SAME) table->file->print_error(error, MYF(0)); else error= 0; @@ -585,7 +583,7 @@ replace_record(THD *thd, TABLE *table, } else { - if ((error= table->file->ha_delete_row(table->record[1]))) + if (unlikely((error= table->file->ha_delete_row(table->record[1])))) { table->file->print_error(error, MYF(0)); DBUG_RETURN(error); @@ -671,7 +669,8 @@ static int find_and_fetch_row(TABLE *table, uchar *key) { int error; /* We have a key: search the table using the index */ - if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE))) + if (!table->file->inited && + unlikely(error= table->file->ha_index_init(0, FALSE))) { table->file->print_error(error, MYF(0)); DBUG_RETURN(error); @@ -695,9 +694,9 @@ static int find_and_fetch_row(TABLE *table, uchar *key) my_ptrdiff_t const pos= table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0; table->record[1][pos]= 0xFF; - if ((error= table->file->ha_index_read_map(table->record[1], key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if (unlikely((error= table->file->ha_index_read_map(table->record[1], key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)))) { table->file->print_error(error, MYF(0)); table->file->ha_index_end(); @@ -738,9 +737,6 @@ static int find_and_fetch_row(TABLE *table, uchar *key) while ((error= table->file->ha_index_next(table->record[1]))) { - /* We just skip records that has already been deleted */ - if (error == HA_ERR_RECORD_DELETED) - continue; table->file->print_error(error, MYF(0)); table->file->ha_index_end(); DBUG_RETURN(error); @@ -758,13 +754,12 @@ static int find_and_fetch_row(TABLE *table, uchar *key) int error; /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init_with_error(1))) + if (unlikely((error= table->file->ha_rnd_init_with_error(1)))) return error; /* Continue until we find the right record or have made a full loop */ do { - restart_rnd_next: error= table->file->ha_rnd_next(table->record[1]); DBUG_DUMP("record[0]", table->record[0], table->s->reclength); @@ -774,18 +769,11 @@ static int find_and_fetch_row(TABLE *table, uchar *key) case 0: break; - /* - If the record was deleted, we pick the next one without doing - any comparisons. - */ - case HA_ERR_RECORD_DELETED: - goto restart_rnd_next; - case HA_ERR_END_OF_FILE: if (++restart_count < 2) { int error2; - if ((error2= table->file->ha_rnd_init_with_error(1))) + if (unlikely((error2= table->file->ha_rnd_init_with_error(1)))) DBUG_RETURN(error2); } break; @@ -853,7 +841,7 @@ int Write_rows_log_event_old::do_after_row_operations(TABLE *table, int error) fires bug#27077 todo: explain or fix */ - if ((local_error= table->file->ha_end_bulk_insert())) + if (unlikely((local_error= table->file->ha_end_bulk_insert()))) { table->file->print_error(local_error, MYF(0)); } @@ -985,7 +973,7 @@ int Delete_rows_log_event_old::do_exec_row(TABLE *table) int error; DBUG_ASSERT(table != NULL); - if (!(error= ::find_and_fetch_row(table, m_key))) + if (likely(!(error= ::find_and_fetch_row(table, m_key)))) { /* Now we should have the right row to delete. We are using @@ -1094,7 +1082,7 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table) DBUG_ASSERT(table != NULL); int error= ::find_and_fetch_row(table, m_key); - if (error) + if (unlikely(error)) return error; /* @@ -1120,7 +1108,7 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table) database into the after image delivered from the master. */ error= table->file->ha_update_row(table->record[1], table->record[0]); - if (error == HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error == HA_ERR_RECORD_IS_THE_SAME)) error= 0; return error; @@ -1233,6 +1221,13 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len, DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); m_width = net_field_length(&ptr_after_width); DBUG_PRINT("debug", ("m_width=%lu", m_width)); + /* Avoid reading out of buffer */ + if (ptr_after_width + m_width > (uchar *)buf + event_len) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + /* if my_bitmap_init fails, catched in is_valid() */ if (likely(!my_bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, @@ -1409,8 +1404,8 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) */ lex_start(thd); - if ((error= lock_tables(thd, rgi->tables_to_lock, - rgi->tables_to_lock_count, 0))) + if (unlikely((error= lock_tables(thd, rgi->tables_to_lock, + rgi->tables_to_lock_count, 0)))) { if (thd->is_slave_error || thd->is_fatal_error) { @@ -1602,7 +1597,7 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) DBUG_PRINT("info", ("curr_row: %p; curr_row_end:%p; rows_end: %p", m_curr_row, m_curr_row_end, m_rows_end)); - if (!m_curr_row_end && !error) + if (!m_curr_row_end && likely(!error)) unpack_current_row(rgi); // at this moment m_curr_row_end should be set @@ -1619,7 +1614,7 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) error= do_after_row_operations(rli, error); } // if (table) - if (error) + if (unlikely(error)) { /* error has occurred during the transaction */ rli->report(ERROR_LEVEL, thd->net.last_errno, NULL, "Error in %s event: error during transaction execution " @@ -1703,7 +1698,9 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) already. So there should be no need to rollback the transaction. */ DBUG_ASSERT(! thd->transaction_rollback_request); - if ((error= (binlog_error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd)))) + if (unlikely((error= (binlog_error ? + trans_rollback_stmt(thd) : + trans_commit_stmt(thd))))) rli->report(ERROR_LEVEL, error, NULL, "Error in %s event: commit of row events failed, " "table `%s`.`%s`", @@ -1924,8 +1921,9 @@ Old_rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) /* fill table->record[0] with default values */ - if ((error= prepare_record(table, m_width, - TRUE /* check if columns have def. values */))) + if (unlikely((error= + prepare_record(table, m_width, + TRUE /* check if columns have def. values */)))) DBUG_RETURN(error); /* unpack row into table->record[0] */ @@ -1946,14 +1944,14 @@ Old_rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) TODO: Add safety measures against infinite looping. */ - while ((error= table->file->ha_write_row(table->record[0]))) + while (unlikely(error= table->file->ha_write_row(table->record[0]))) { if (error == HA_ERR_LOCK_DEADLOCK || error == HA_ERR_LOCK_WAIT_TIMEOUT) { table->file->print_error(error, MYF(0)); /* to check at exec_relay_log_event */ DBUG_RETURN(error); } - if ((keynum= table->file->get_dup_key(error)) < 0) + if (unlikely((keynum= table->file->get_dup_key(error)) < 0)) { DBUG_PRINT("info",("Can't locate duplicate key (get_dup_key returns %d)",keynum)); table->file->print_error(error, MYF(0)); @@ -1979,11 +1977,9 @@ Old_rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) { DBUG_PRINT("info",("Locating offending record using rnd_pos()")); error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("rnd_pos() returns error %d",error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -2001,7 +1997,7 @@ Old_rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) if (key.get() == NULL) { key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length))); - if (key.get() == NULL) + if (unlikely(key.get() == NULL)) { DBUG_PRINT("info",("Can't allocate key buffer")); DBUG_RETURN(ENOMEM); @@ -2014,11 +2010,9 @@ Old_rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) (const uchar*)key.get(), HA_WHOLE_KEY, HA_READ_KEY_EXACT); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("index_read_idx() returns error %d", error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -2087,7 +2081,7 @@ Old_rows_log_event::write_row(rpl_group_info *rgi, const bool overwrite) else { DBUG_PRINT("info",("Deleting offending row and trying to write new one again")); - if ((error= table->file->ha_delete_row(table->record[1]))) + if (unlikely((error= table->file->ha_delete_row(table->record[1])))) { DBUG_PRINT("info",("ha_delete_row() returns error %d",error)); table->file->print_error(error, MYF(0)); @@ -2175,11 +2169,9 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) */ DBUG_PRINT("info",("locating record using primary key (position)")); int error= table->file->ha_rnd_pos_by_record(table->record[0]); - if (error) + if (unlikely(error)) { DBUG_PRINT("info",("rnd_pos returns error %d",error)); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); } DBUG_RETURN(error); @@ -2204,7 +2196,8 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) DBUG_PRINT("info",("locating record using primary key (index_read)")); /* We have a key: search the table using the index */ - if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE))) + if (!table->file->inited && + unlikely(error= table->file->ha_index_init(0, FALSE))) { DBUG_PRINT("info",("ha_index_init returns error %d",error)); table->file->print_error(error, MYF(0)); @@ -2234,13 +2227,12 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0; table->record[0][pos]= 0xFF; - if ((error= table->file->ha_index_read_map(table->record[0], m_key, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if (unlikely((error= table->file->ha_index_read_map(table->record[0], + m_key, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)))) { DBUG_PRINT("info",("no record matching the key found in the table")); - if (error == HA_ERR_RECORD_DELETED) - error= HA_ERR_KEY_NOT_FOUND; table->file->print_error(error, MYF(0)); table->file->ha_index_end(); DBUG_RETURN(error); @@ -2308,11 +2300,8 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) while (record_compare(table)) { - while ((error= table->file->ha_index_next(table->record[0]))) + while (unlikely(error= table->file->ha_index_next(table->record[0]))) { - /* We just skip records that has already been deleted */ - if (error == HA_ERR_RECORD_DELETED) - continue; DBUG_PRINT("info",("no record matching the given row found")); table->file->print_error(error, MYF(0)); (void) table->file->ha_index_end(); @@ -2327,7 +2316,7 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) int restart_count= 0; // Number of times scanning has restarted from top /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init_with_error(1))) + if (unlikely((error= table->file->ha_rnd_init_with_error(1)))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); @@ -2345,15 +2334,12 @@ int Old_rows_log_event::find_row(rpl_group_info *rgi) case 0: break; - case HA_ERR_RECORD_DELETED: - goto restart_rnd_next; - case HA_ERR_END_OF_FILE: if (++restart_count < 2) { int error2; table->file->ha_rnd_end(); - if ((error2= table->file->ha_rnd_init_with_error(1))) + if (unlikely((error2= table->file->ha_rnd_init_with_error(1)))) DBUG_RETURN(error2); goto restart_rnd_next; } @@ -2472,7 +2458,7 @@ Write_rows_log_event_old::do_after_row_operations(const Slave_reporting_capabili fires bug#27077 todo: explain or fix */ - if ((local_error= m_table->file->ha_end_bulk_insert())) + if (unlikely((local_error= m_table->file->ha_end_bulk_insert()))) { m_table->file->print_error(local_error, MYF(0)); } @@ -2486,7 +2472,7 @@ Write_rows_log_event_old::do_exec_row(rpl_group_info *rgi) DBUG_ASSERT(m_table != NULL); int error= write_row(rgi, TRUE /* overwrite */); - if (error && !thd->net.last_errno) + if (unlikely(error) && !thd->net.last_errno) thd->net.last_errno= error; return error; @@ -2589,7 +2575,7 @@ int Delete_rows_log_event_old::do_exec_row(rpl_group_info *rgi) int error; DBUG_ASSERT(m_table != NULL); - if (!(error= find_row(rgi))) + if (likely(!(error= find_row(rgi))) ) { /* Delete the record found, located in record[0] @@ -2689,7 +2675,7 @@ Update_rows_log_event_old::do_exec_row(rpl_group_info *rgi) DBUG_ASSERT(m_table != NULL); int error= find_row(rgi); - if (error) + if (unlikely(error)) { /* We need to read the second image in the event of error to be @@ -2733,7 +2719,7 @@ Update_rows_log_event_old::do_exec_row(rpl_group_info *rgi) error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]); m_table->file->ha_index_or_rnd_end(); - if (error == HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error == HA_ERR_RECORD_IS_THE_SAME)) error= 0; return error; diff --git a/sql/mdl.h b/sql/mdl.h index a537022484f..952d97d301c 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -456,7 +456,7 @@ public: static void *operator new(size_t size, MEM_ROOT *mem_root) throw () { return alloc_root(mem_root, size); } - static void operator delete(void *ptr, MEM_ROOT *mem_root) {} + static void operator delete(void *, MEM_ROOT *) {} void init(MDL_key::enum_mdl_namespace namespace_arg, const char *db_arg, const char *name_arg, @@ -497,7 +497,7 @@ public: is mandatory. Can only be used before the request has been granted. */ - MDL_request& operator=(const MDL_request &rhs) + MDL_request& operator=(const MDL_request &) { ticket= NULL; /* Do nothing, in particular, don't try to copy the key. */ diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc index 3d3b4da11db..495d78804b0 100644 --- a/sql/mf_iocache.cc +++ b/sql/mf_iocache.cc @@ -49,8 +49,7 @@ extern "C" { */ -int _my_b_net_read(register IO_CACHE *info, uchar *Buffer, - size_t Count __attribute__((unused))) +int _my_b_net_read(IO_CACHE *info, uchar *Buffer, size_t) { ulong read_length; NET *net= &(current_thd)->net; @@ -59,12 +58,12 @@ int _my_b_net_read(register IO_CACHE *info, uchar *Buffer, if (!info->end_of_file) DBUG_RETURN(1); /* because my_b_get (no _) takes 1 byte at a time */ read_length= my_net_read_packet(net, 0); - if (read_length == packet_error) + if (unlikely(read_length == packet_error)) { info->error= -1; DBUG_RETURN(1); } - if (read_length == 0) + if (unlikely(read_length == 0)) { info->end_of_file= 0; /* End of file from client */ DBUG_RETURN(1); diff --git a/sql/mf_iocache_encr.cc b/sql/mf_iocache_encr.cc index 9724ca4e19e..d2e6d554ba7 100644 --- a/sql/mf_iocache_encr.cc +++ b/sql/mf_iocache_encr.cc @@ -49,8 +49,8 @@ static int my_b_encr_read(IO_CACHE *info, uchar *Buffer, size_t Count) if (pos_in_file == info->end_of_file) { - info->read_pos= info->read_end= info->buffer; - info->pos_in_file= pos_in_file; + /* reading past EOF should not empty the cache */ + info->read_pos= info->read_end; info->error= 0; DBUG_RETURN(MY_TEST(Count)); } diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index ec3c85b34c4..cf587ef4acd 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -757,12 +757,6 @@ int Mrr_ordered_rndpos_reader::get_next(range_id_t *range_info) res= file->ha_rnd_pos(file->get_table()->record[0], rowid_buffer->read_ptr1); - if (res == HA_ERR_RECORD_DELETED) - { - /* not likely to get this code with current storage engines, but still */ - continue; - } - if (res) return res; /* Some fatal error */ diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index c76b279048b..0483c7f5fbf 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -545,7 +545,6 @@ static int create_db_instance() } CreateDirectory("mysql",NULL); - CreateDirectory("test", NULL); /* Set data directory permissions for both current user and diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4309748fe06..2205538f2d3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -304,7 +304,6 @@ static TYPELIB tc_heuristic_recover_typelib= const char *first_keyword= "first"; const char *my_localhost= "localhost", *delayed_user= "DELAYED"; -const char *quoted_string= "%`s"; bool opt_large_files= sizeof(my_off_t) > 4; static my_bool opt_autocommit; ///< for --autocommit command-line option @@ -535,6 +534,7 @@ ulonglong slave_skipped_errors; ulong feature_files_opened_with_delayed_keys= 0, feature_check_constraint= 0; ulonglong denied_connections; my_decimal decimal_zero; +long opt_secure_timestamp; /* Maximum length of parameter value which can be set through @@ -1957,10 +1957,11 @@ void kill_mysql(THD *thd) pthread_t tmp; int error; abort_loop=1; - if ((error= mysql_thread_create(0, /* Not instrumented */ - &tmp, &connection_attrib, - kill_server_thread, (void*) 0))) - sql_print_error("Can't create thread to kill server (errno= %d).", error); + if (unlikely((error= mysql_thread_create(0, /* Not instrumented */ + &tmp, &connection_attrib, + kill_server_thread, (void*) 0)))) + sql_print_error("Can't create thread to kill server (errno= %d).", + error); } #endif DBUG_VOID_RETURN; @@ -2191,7 +2192,8 @@ static void mysqld_exit(int exit_code) if (opt_endinfo && global_status_var.global_memory_used) fprintf(stderr, "Warning: Memory not freed: %ld\n", (long) global_status_var.global_memory_used); - if (!opt_debugging && !my_disable_leak_check && exit_code == 0) + if (!opt_debugging && !my_disable_leak_check && exit_code == 0 && + debug_assert_on_not_freed_memory) { #ifdef SAFEMALLOC sf_report_leaked_memory(0); @@ -2240,14 +2242,14 @@ void clean_up(bool print_message) lex_free(); /* Free some memory */ item_create_cleanup(); tdc_start_shutdown(); +#ifdef HAVE_REPLICATION + semi_sync_master_deinit(); +#endif plugin_shutdown(); udf_free(); ha_end(); if (tc_log) tc_log->close(); -#ifdef HAVE_REPLICATION - semi_sync_master_deinit(); -#endif xid_cache_free(); tdc_deinit(); mdl_destroy(); @@ -2569,7 +2571,7 @@ static MYSQL_SOCKET activate_tcp_port(uint port) my_snprintf(port_buf, NI_MAXSERV, "%d", port); error= getaddrinfo(real_bind_addr_str, port_buf, &hints, &ai); - if (error != 0) + if (unlikely(error != 0)) { DBUG_PRINT("error",("Got error: %d from getaddrinfo()", error)); @@ -3485,8 +3487,9 @@ static void start_signal_handler(void) (void) my_setstacksize(&thr_attr,my_thread_stack_size); mysql_mutex_lock(&LOCK_start_thread); - if ((error= mysql_thread_create(key_thread_signal_hand, - &signal_thread, &thr_attr, signal_hand, 0))) + if (unlikely((error= mysql_thread_create(key_thread_signal_hand, + &signal_thread, &thr_attr, + signal_hand, 0)))) { sql_print_error("Can't create interrupt-thread (error %d, errno: %d)", error,errno); @@ -3588,10 +3591,10 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) PSI_CALL_delete_current_thread(); #ifdef USE_ONE_SIGNAL_HAND pthread_t tmp; - if ((error= mysql_thread_create(0, /* Not instrumented */ - &tmp, &connection_attrib, - kill_server_thread, - (void*) &sig))) + if (unlikely((error= mysql_thread_create(0, /* Not instrumented */ + &tmp, &connection_attrib, + kill_server_thread, + (void*) &sig)))) sql_print_error("Can't create thread to kill server (errno= %d)", error); #else @@ -3683,9 +3686,9 @@ void my_message_sql(uint error, const char *str, myf MyFlags) func= sql_print_error; } - if (thd) + if (likely(thd)) { - if (MyFlags & ME_FATALERROR) + if (unlikely(MyFlags & ME_FATALERROR)) thd->is_fatal_error= 1; (void) thd->raise_condition(error, NULL, level, str); } @@ -3695,7 +3698,7 @@ void my_message_sql(uint error, const char *str, myf MyFlags) /* When simulating OOM, skip writing to error log to avoid mtr errors */ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;); - if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH)) + if (unlikely(!thd) || thd->log_all_errors || (MyFlags & ME_NOREFRESH)) (*func)("%s: %s", my_progname_short, str); /* purecov: inspected */ DBUG_VOID_RETURN; } @@ -4101,7 +4104,7 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) thd->status_var.local_memory_used); if (size > 0 && thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && - !thd->killed && !thd->get_stmt_da()->is_set()) + likely(!thd->killed) && !thd->get_stmt_da()->is_set()) { /* Ensure we don't get called here again */ char buf[50], *buf2; @@ -5377,7 +5380,7 @@ static int init_server_components() init_global_index_stats(); /* Allow storage engine to give real error messages */ - if (ha_init_errors()) + if (unlikely(ha_init_errors())) DBUG_RETURN(1); tc_log= 0; // ha_initialize_handlerton() needs that @@ -5564,7 +5567,7 @@ static int init_server_components() error= mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, 0, WRITE_CACHE, max_binlog_size, 0, TRUE); mysql_mutex_unlock(log_lock); - if (error) + if (unlikely(error)) unireg_abort(1); } @@ -5598,7 +5601,7 @@ static int init_server_components() else error= mlockall(MCL_CURRENT); - if (error) + if (unlikely(error)) { if (global_system_variables.log_warnings) sql_print_warning("Failed to lock memory. Errno: %d\n",errno); @@ -5630,9 +5633,9 @@ static void create_shutdown_thread() hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name); pthread_t hThread; int error; - if ((error= mysql_thread_create(key_thread_handle_shutdown, - &hThread, &connection_attrib, - handle_shutdown, 0))) + if (unlikely((error= mysql_thread_create(key_thread_handle_shutdown, + &hThread, &connection_attrib, + handle_shutdown, 0)))) sql_print_warning("Can't create thread to handle shutdown requests" " (errno= %d)", error); @@ -8566,8 +8569,10 @@ SHOW_VAR status_vars[]= { {"Feature_fulltext", (char*) offsetof(STATUS_VAR, feature_fulltext), SHOW_LONG_STATUS}, {"Feature_gis", (char*) offsetof(STATUS_VAR, feature_gis), SHOW_LONG_STATUS}, {"Feature_invisible_columns", (char*) offsetof(STATUS_VAR, feature_invisible_columns), SHOW_LONG_STATUS}, + {"Feature_json", (char*) offsetof(STATUS_VAR, feature_json), SHOW_LONG_STATUS}, {"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS}, {"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS}, + {"Feature_system_versioning", (char*) offsetof(STATUS_VAR, feature_system_versioning), SHOW_LONG_STATUS}, {"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS}, {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS}, {"Feature_window_functions", (char*) offsetof(STATUS_VAR, feature_window_functions), SHOW_LONG_STATUS}, @@ -9011,7 +9016,7 @@ static int mysql_init_variables(void) #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) have_ssl=SHOW_OPTION_YES; -#if HAVE_YASSL +#if defined(HAVE_YASSL) have_openssl= SHOW_OPTION_NO; #else have_openssl= SHOW_OPTION_YES; @@ -9563,7 +9568,7 @@ mysql_getopt_value(const char *name, uint length, case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE: { KEY_CACHE *key_cache; - if (!(key_cache= get_or_create_key_cache(name, length))) + if (unlikely(!(key_cache= get_or_create_key_cache(name, length)))) { if (error) *error= EXIT_OUT_OF_MEMORY; @@ -9693,17 +9698,6 @@ static int get_options(int *argc_ptr, char ***argv_ptr) global_system_variables.max_allowed_packet); } -#if MYSQL_VERSION_ID > 101001 - /* - TIMESTAMP columns get implicit DEFAULT values when - --explicit_defaults_for_timestamp is not set. - */ - if (!opt_help && !opt_explicit_defaults_for_timestamp) - sql_print_warning("TIMESTAMP with implicit DEFAULT value is deprecated. " - "Please use --explicit_defaults_for_timestamp server " - "option (see documentation for more details)."); -#endif - if (log_error_file_ptr != disabled_my_option) opt_error_log= 1; else diff --git a/sql/mysqld.h b/sql/mysqld.h index 7a616097338..4a392eaf196 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -241,7 +241,7 @@ extern int max_user_connections; extern volatile ulong cached_thread_count; extern ulong what_to_log,flush_time; extern uint max_prepared_stmt_count, prepared_stmt_count; -extern ulong open_files_limit; +extern MYSQL_PLUGIN_IMPORT ulong open_files_limit; extern ulonglong binlog_cache_size, binlog_stmt_cache_size, binlog_file_cache_size; extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size; @@ -302,7 +302,9 @@ extern my_bool encrypt_binlog; extern my_bool encrypt_tmp_disk_tables, encrypt_tmp_files; extern ulong encryption_algorithm; extern const char *encryption_algorithm_names[]; -extern const char *quoted_string; +extern long opt_secure_timestamp; + +enum secure_timestamp { SECTIME_NO, SECTIME_SUPER, SECTIME_REPL, SECTIME_YES }; #ifdef HAVE_PSI_INTERFACE #ifdef HAVE_MMAP diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 4c3771bc710..0d3aa12465d 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -112,12 +112,12 @@ extern void query_cache_insert(void *thd, const char *packet, size_t length, unsigned pkt_nr); #endif // HAVE_QUERY_CACHE #define update_statistics(A) A -extern my_bool thd_net_is_killed(); +extern my_bool thd_net_is_killed(THD *thd); /* Additional instrumentation hooks for the server */ #include "mysql_com_server.h" #else #define update_statistics(A) -#define thd_net_is_killed() 0 +#define thd_net_is_killed(A) 0 #endif @@ -620,7 +620,7 @@ net_real_write(NET *net,const uchar *packet, size_t len) query_cache_insert(net->thd, (char*) packet, len, net->pkt_nr); #endif - if (net->error == 2) + if (unlikely(net->error == 2)) DBUG_RETURN(-1); /* socket can't be used */ net->reading_or_writing=2; @@ -960,7 +960,7 @@ retry: DBUG_PRINT("info",("vio_read returned %ld errno: %d", (long) length, vio_errno(net->vio))); - if (i== 0 && thd_net_is_killed()) + if (i== 0 && unlikely(thd_net_is_killed((THD*) net->thd))) { DBUG_PRINT("info", ("thd is killed")); len= packet_error; @@ -1246,13 +1246,13 @@ my_net_read_packet_reallen(NET *net, my_bool read_from_server, ulong* reallen) total_length += len; len = my_real_read(net,&complen, 0); } while (len == MAX_PACKET_LENGTH); - if (len != packet_error) + if (likely(len != packet_error)) len+= total_length; net->where_b = save_pos; } net->read_pos = net->buff + net->where_b; - if (len != packet_error) + if (likely(len != packet_error)) { net->read_pos[len]=0; /* Safeguard for mysql_use_result */ *reallen = (ulong)len; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9ccffd13bfc..64d3b08b1b1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1595,7 +1595,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler, selects. */ int error= quick->init_ror_merged_scan(TRUE, local_alloc); - if (error) + if (unlikely(error)) DBUG_RETURN(error); quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS); } @@ -1619,7 +1619,8 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler, quick->record= head->record[0]; } - if (need_to_fetch_row && head->file->ha_rnd_init_with_error(false)) + if (need_to_fetch_row && + unlikely(head->file->ha_rnd_init_with_error(false))) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); DBUG_RETURN(1); @@ -1793,9 +1794,9 @@ int QUICK_ROR_UNION_SELECT::reset() List_iterator_fast<QUICK_SELECT_I> it(quick_selects); while ((quick= it++)) { - if ((error= quick->reset())) + if (unlikely((error= quick->reset()))) DBUG_RETURN(error); - if ((error= quick->get_next())) + if (unlikely((error= quick->get_next()))) { if (error == HA_ERR_END_OF_FILE) continue; @@ -1805,12 +1806,12 @@ int QUICK_ROR_UNION_SELECT::reset() queue_insert(&queue, (uchar*)quick); } /* Prepare for ha_rnd_pos calls. */ - if (head->file->inited && (error= head->file->ha_rnd_end())) + if (head->file->inited && unlikely((error= head->file->ha_rnd_end()))) { DBUG_PRINT("error", ("ROR index_merge rnd_end call failed")); DBUG_RETURN(error); } - if ((error= head->file->ha_rnd_init(false))) + if (unlikely((error= head->file->ha_rnd_init(false)))) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); DBUG_RETURN(error); @@ -10835,8 +10836,9 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, goto err; quick->records= records; - if ((cp_buffer_from_ref(thd, table, ref) && thd->is_fatal_error) || - !(range= new(alloc) QUICK_RANGE())) + if ((cp_buffer_from_ref(thd, table, ref) && + unlikely(thd->is_fatal_error)) || + unlikely(!(range= new(alloc) QUICK_RANGE()))) goto err; // out of memory range->min_key= range->max_key= ref->key_buff; @@ -10845,8 +10847,8 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, make_prev_keypart_map(ref->key_parts); range->flag= EQ_RANGE; - if (!(quick->key_parts=key_part=(KEY_PART *) - alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts))) + if (unlikely(!(quick->key_parts=key_part=(KEY_PART *) + alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))) goto err; max_used_key_len=0; @@ -11164,103 +11166,100 @@ int QUICK_ROR_INTERSECT_SELECT::get_next() uint last_rowid_count=0; DBUG_ENTER("QUICK_ROR_INTERSECT_SELECT::get_next"); - do + /* Get a rowid for first quick and save it as a 'candidate' */ + qr= quick_it++; + quick= qr->quick; + error= quick->get_next(); + if (cpk_quick) { - /* Get a rowid for first quick and save it as a 'candidate' */ - qr= quick_it++; - quick= qr->quick; - error= quick->get_next(); - if (cpk_quick) + while (!error && !cpk_quick->row_in_ranges()) { - while (!error && !cpk_quick->row_in_ranges()) - { - quick->file->unlock_row(); /* row not in range; unlock */ - error= quick->get_next(); - } + quick->file->unlock_row(); /* row not in range; unlock */ + error= quick->get_next(); } - if (error) - DBUG_RETURN(error); + } + if (unlikely(error)) + DBUG_RETURN(error); - /* Save the read key tuple */ - key_copy(qr->key_tuple, record, head->key_info + quick->index, - quick->max_used_key_length); + /* Save the read key tuple */ + key_copy(qr->key_tuple, record, head->key_info + quick->index, + quick->max_used_key_length); + + quick->file->position(quick->record); + memcpy(last_rowid, quick->file->ref, head->file->ref_length); + last_rowid_count= 1; + quick_with_last_rowid= quick; - quick->file->position(quick->record); - memcpy(last_rowid, quick->file->ref, head->file->ref_length); - last_rowid_count= 1; - quick_with_last_rowid= quick; + while (last_rowid_count < quick_selects.elements) + { + if (!(qr= quick_it++)) + { + quick_it.rewind(); + qr= quick_it++; + } + quick= qr->quick; - while (last_rowid_count < quick_selects.elements) + do { - if (!(qr= quick_it++)) + DBUG_EXECUTE_IF("innodb_quick_report_deadlock", + DBUG_SET("+d,innodb_report_deadlock");); + if (unlikely((error= quick->get_next()))) { - quick_it.rewind(); - qr= quick_it++; + /* On certain errors like deadlock, trx might be rolled back.*/ + if (!thd->transaction_rollback_request) + quick_with_last_rowid->file->unlock_row(); + DBUG_RETURN(error); } - quick= qr->quick; - - do + quick->file->position(quick->record); + cmp= head->file->cmp_ref(quick->file->ref, last_rowid); + if (cmp < 0) { - DBUG_EXECUTE_IF("innodb_quick_report_deadlock", - DBUG_SET("+d,innodb_report_deadlock");); - if ((error= quick->get_next())) - { - /* On certain errors like deadlock, trx might be rolled back.*/ - if (!thd->transaction_rollback_request) - quick_with_last_rowid->file->unlock_row(); - DBUG_RETURN(error); - } - quick->file->position(quick->record); - cmp= head->file->cmp_ref(quick->file->ref, last_rowid); - if (cmp < 0) - { - /* This row is being skipped. Release lock on it. */ - quick->file->unlock_row(); - } - } while (cmp < 0); + /* This row is being skipped. Release lock on it. */ + quick->file->unlock_row(); + } + } while (cmp < 0); - key_copy(qr->key_tuple, record, head->key_info + quick->index, - quick->max_used_key_length); + key_copy(qr->key_tuple, record, head->key_info + quick->index, + quick->max_used_key_length); - /* Ok, current select 'caught up' and returned ref >= cur_ref */ - if (cmp > 0) + /* Ok, current select 'caught up' and returned ref >= cur_ref */ + if (cmp > 0) + { + /* Found a row with ref > cur_ref. Make it a new 'candidate' */ + if (cpk_quick) { - /* Found a row with ref > cur_ref. Make it a new 'candidate' */ - if (cpk_quick) + while (!cpk_quick->row_in_ranges()) { - while (!cpk_quick->row_in_ranges()) + quick->file->unlock_row(); /* row not in range; unlock */ + if (unlikely((error= quick->get_next()))) { - quick->file->unlock_row(); /* row not in range; unlock */ - if ((error= quick->get_next())) - { - /* On certain errors like deadlock, trx might be rolled back.*/ - if (!thd->transaction_rollback_request) - quick_with_last_rowid->file->unlock_row(); - DBUG_RETURN(error); - } + /* On certain errors like deadlock, trx might be rolled back.*/ + if (!thd->transaction_rollback_request) + quick_with_last_rowid->file->unlock_row(); + DBUG_RETURN(error); } - quick->file->position(quick->record); } - memcpy(last_rowid, quick->file->ref, head->file->ref_length); - quick_with_last_rowid->file->unlock_row(); - last_rowid_count= 1; - quick_with_last_rowid= quick; - - //save the fields here - key_copy(qr->key_tuple, record, head->key_info + quick->index, - quick->max_used_key_length); - } - else - { - /* current 'candidate' row confirmed by this select */ - last_rowid_count++; + quick->file->position(quick->record); } + memcpy(last_rowid, quick->file->ref, head->file->ref_length); + quick_with_last_rowid->file->unlock_row(); + last_rowid_count= 1; + quick_with_last_rowid= quick; + + //save the fields here + key_copy(qr->key_tuple, record, head->key_info + quick->index, + quick->max_used_key_length); } + else + { + /* current 'candidate' row confirmed by this select */ + last_rowid_count++; + } + } - /* We get here if we got the same row ref in all scans. */ - if (need_to_fetch_row) - error= head->file->ha_rnd_pos(head->record[0], last_rowid); - } while (error == HA_ERR_RECORD_DELETED); + /* We get here if we got the same row ref in all scans. */ + if (need_to_fetch_row) + error= head->file->ha_rnd_pos(head->record[0], last_rowid); if (!need_to_fetch_row) { @@ -11304,44 +11303,41 @@ int QUICK_ROR_UNION_SELECT::get_next() do { - do - { - if (!queue.elements) - DBUG_RETURN(HA_ERR_END_OF_FILE); - /* Ok, we have a queue with >= 1 scans */ + if (!queue.elements) + DBUG_RETURN(HA_ERR_END_OF_FILE); + /* Ok, we have a queue with >= 1 scans */ - quick= (QUICK_SELECT_I*)queue_top(&queue); - memcpy(cur_rowid, quick->last_rowid, rowid_length); + quick= (QUICK_SELECT_I*)queue_top(&queue); + memcpy(cur_rowid, quick->last_rowid, rowid_length); - /* put into queue rowid from the same stream as top element */ - if ((error= quick->get_next())) - { - if (error != HA_ERR_END_OF_FILE) - DBUG_RETURN(error); - queue_remove_top(&queue); - } - else - { - quick->save_last_pos(); - queue_replace_top(&queue); - } + /* put into queue rowid from the same stream as top element */ + if ((error= quick->get_next())) + { + if (error != HA_ERR_END_OF_FILE) + DBUG_RETURN(error); + queue_remove_top(&queue); + } + else + { + quick->save_last_pos(); + queue_replace_top(&queue); + } - if (!have_prev_rowid) - { - /* No rows have been returned yet */ - dup_row= FALSE; - have_prev_rowid= TRUE; - } - else - dup_row= !head->file->cmp_ref(cur_rowid, prev_rowid); - } while (dup_row); + if (!have_prev_rowid) + { + /* No rows have been returned yet */ + dup_row= FALSE; + have_prev_rowid= TRUE; + } + else + dup_row= !head->file->cmp_ref(cur_rowid, prev_rowid); + } while (dup_row); - tmp= cur_rowid; - cur_rowid= prev_rowid; - prev_rowid= tmp; + tmp= cur_rowid; + cur_rowid= prev_rowid; + prev_rowid= tmp; - error= head->file->ha_rnd_pos(quick->record, prev_rowid); - } while (error == HA_ERR_RECORD_DELETED); + error= head->file->ha_rnd_pos(quick->record, prev_rowid); DBUG_RETURN(error); } @@ -11363,7 +11359,7 @@ int QUICK_RANGE_SELECT::reset() if (file->inited == handler::RND) { /* Handler could be left in this state by MRR */ - if ((error= file->ha_rnd_end())) + if (unlikely((error= file->ha_rnd_end()))) DBUG_RETURN(error); } @@ -11375,7 +11371,7 @@ int QUICK_RANGE_SELECT::reset() { DBUG_EXECUTE_IF("bug14365043_2", DBUG_SET("+d,ha_index_init_fail");); - if ((error= file->ha_index_init(index,1))) + if (unlikely((error= file->ha_index_init(index,1)))) { file->print_error(error, MYF(0)); goto err; @@ -11718,7 +11714,7 @@ int QUICK_SELECT_DESC::get_next() if (last_range->flag & NO_MAX_RANGE) // Read last record { int local_error; - if ((local_error= file->ha_index_last(record))) + if (unlikely((local_error= file->ha_index_last(record)))) DBUG_RETURN(local_error); // Empty table if (cmp_prev(last_range) == 0) DBUG_RETURN(0); diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc index ace6208fd77..515d94e8748 100644 --- a/sql/opt_range_mrr.cc +++ b/sql/opt_range_mrr.cc @@ -135,7 +135,7 @@ static void step_down_to(SEL_ARG_RANGE_SEQ *arg, SEL_ARG *key_tree) TRUE No more ranges in the sequence */ -#if (_MSC_FULL_VER == 160030319) +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER == 160030319) /* Workaround Visual Studio 2010 RTM compiler backend bug, the function enters infinite loop. @@ -315,7 +315,7 @@ walk_up_n_right: return 0; } -#if (_MSC_FULL_VER == 160030319) +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER == 160030319) /* VS2010 compiler bug workaround */ #pragma optimize("g", on) #endif diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 6467706bc0b..37853bdbbe9 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -352,8 +352,9 @@ bool JOIN::check_for_splittable_materialized() Field *ord_field= ((Item_field *) (ord_item->real_item()))->field; - JOIN_TAB *tab= ord_field->table->reginfo.join_tab; - if (tab->is_inner_table_of_outer_join()) + /* Ignore fields from of inner tables of outer joins */ + TABLE_LIST *tbl= ord_field->table->pos_in_table_list; + if (tbl->is_inner_table_of_outer_join()) continue; List_iterator<Item> li(fields_list); @@ -543,7 +544,14 @@ void TABLE::add_splitting_info_for_key_field(KEY_FIELD *key_field) added_key_field->level= 0; added_key_field->optimize= KEY_OPTIMIZE_EQ; added_key_field->eq_func= true; - added_key_field->null_rejecting= true; + + Item *real= key_field->val->real_item(); + if ((real->type() == Item::FIELD_ITEM) && + ((Item_field*)real)->field->maybe_null()) + added_key_field->null_rejecting= true; + else + added_key_field->null_rejecting= false; + added_key_field->cond_guard= NULL; added_key_field->sj_pred_no= UINT_MAX; return; @@ -862,7 +870,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, table_map tables_usable_for_splitting= spl_opt_info->tables_usable_for_splitting; KEYUSE_EXT *keyuse_ext= &join->ext_keyuses_for_splitting->at(0); - KEYUSE_EXT *best_key_keyuse_ext_start; + KEYUSE_EXT *UNINIT_VAR(best_key_keyuse_ext_start); TABLE *best_table= 0; double best_rec_per_key= DBL_MAX; SplM_plan_info *spl_plan= 0; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index a55ce2d163c..800ee65fe26 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1063,8 +1063,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) while ((in_subq= li++)) { SELECT_LEX *subq_sel= in_subq->get_select_lex(); - if (subq_sel->handle_derived(thd->lex, DT_OPTIMIZE)) - DBUG_RETURN(1); if (subq_sel->handle_derived(thd->lex, DT_MERGE)) DBUG_RETURN(TRUE); if (subq_sel->join->transform_in_predicates_into_in_subq(thd)) @@ -3708,8 +3706,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab) sjm= emb_sj_nest->sj_mat_info; thd= tab->join->thd; /* First the calls come to the materialization function */ - //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list; - + DBUG_ASSERT(sjm->is_used); /* Set up the table to write to, do as select_union::create_result_table does @@ -3718,10 +3715,22 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab) sjm->sjm_table_param.bit_fields_as_long= TRUE; SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select(); const LEX_CSTRING sj_materialize_name= { STRING_WITH_LEN("sj-materialize") }; - Ref_ptr_array p_items= subq_select->ref_pointer_array; - for (uint i= 0; i < subq_select->item_list.elements; i++) - sjm->sjm_table_cols.push_back(p_items[i], thd->mem_root); - + List_iterator<Item> it(subq_select->item_list); + Item *item; + while((item= it++)) + { + /* + This semi-join replaced the subquery (subq_select) and so on + re-executing it will not be prepared. To use the Items from its + select list we have to prepare (fix_fields) them + */ + if (!item->fixed && item->fix_fields(thd, it.ref())) + DBUG_RETURN(TRUE); + item= *(it.ref()); // it can be changed by fix_fields + DBUG_ASSERT(!item->name.length || item->name.length == strlen(item->name.str)); + sjm->sjm_table_cols.push_back(item, thd->mem_root); + } + sjm->sjm_table_param.field_count= subq_select->item_list.elements; sjm->sjm_table_param.force_not_null_cols= TRUE; @@ -4352,7 +4361,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) } } - if (thd->is_fatal_error) // If end of memory + if (unlikely(thd->is_fatal_error)) // If end of memory goto err; share->db_record_offset= 1; table->no_rows= 1; // We don't need the data @@ -4361,10 +4370,11 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) recinfo++; if (share->db_type() == TMP_ENGINE_HTON) { - if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0)) + if (unlikely(create_internal_tmp_table(table, keyinfo, start_recinfo, + &recinfo, 0))) goto err; } - if (open_tmp_table(table)) + if (unlikely(open_tmp_table(table))) goto err; thd->mem_root= mem_root_save; @@ -4476,7 +4486,7 @@ int SJ_TMP_TABLE::sj_weedout_check_row(THD *thd) } error= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]); - if (error) + if (unlikely(error)) { /* create_internal_tmp_table_from_heap will generate error if needed */ if (!tmp_table->file->is_fatal_error(error, HA_CHECK_DUP)) @@ -5297,7 +5307,8 @@ enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab) hash_sj_engine->materialize_join->exec(); hash_sj_engine->is_materialized= TRUE; - if (hash_sj_engine->materialize_join->error || tab->join->thd->is_fatal_error) + if (unlikely(hash_sj_engine->materialize_join->error) || + unlikely(tab->join->thd->is_fatal_error)) DBUG_RETURN(NESTED_LOOP_ERROR); } } @@ -6316,6 +6327,7 @@ bool JOIN::choose_tableless_subquery_plan() tmp_having= having; } } + exec_const_cond= conds; return FALSE; } diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 43d1c2de7ad..82946709166 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -316,7 +316,7 @@ int opt_sum_query(THD *thd, else { error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); - if(error) + if (unlikely(error)) { tl->table->file->print_error(error, MYF(ME_FATALERROR)); DBUG_RETURN(error); @@ -400,15 +400,16 @@ int opt_sum_query(THD *thd, } longlong info_limit= 1; table->file->info_push(INFO_KIND_FORCE_LIMIT_BEGIN, &info_limit); - if (!(error= table->file->ha_index_init((uint) ref.key, 1))) + if (likely(!(error= table->file->ha_index_init((uint) ref.key, 1)))) error= (is_max ? get_index_max_value(table, &ref, range_fl) : get_index_min_value(table, &ref, item_field, range_fl, prefix_len)); /* Verify that the read tuple indeed matches the search key */ - if (!error && reckey_in_range(is_max, &ref, item_field->field, - conds, range_fl, prefix_len)) + if (!error && + reckey_in_range(is_max, &ref, item_field->field, + conds, range_fl, prefix_len)) error= HA_ERR_KEY_NOT_FOUND; table->file->ha_end_keyread(); table->file->ha_index_end(); @@ -478,7 +479,7 @@ int opt_sum_query(THD *thd, } } - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(thd->get_stmt_da()->sql_errno()); /* diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 90d766f15d2..751ca180f97 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -483,8 +483,7 @@ frm_error: my_error(ER_FPARSER_BAD_HEADER, MYF(0), file_name->str); DBUG_RETURN(0); } - else - DBUG_RETURN(parser); // upper level have to check parser->ok() + DBUG_RETURN(parser); // upper level have to check parser->ok() } diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 43ee92f6020..f09bde6a965 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -48,11 +48,9 @@ partition_info *partition_info::get_clone(THD *thd) List_iterator<partition_element> part_it(partitions); partition_element *part; partition_info *clone= new (mem_root) partition_info(*this); - if (!clone) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!clone)) DBUG_RETURN(NULL); - } + memset(&(clone->read_partitions), 0, sizeof(clone->read_partitions)); memset(&(clone->lock_partitions), 0, sizeof(clone->lock_partitions)); clone->bitmaps_are_initialized= FALSE; @@ -64,20 +62,16 @@ partition_info *partition_info::get_clone(THD *thd) partition_element *subpart; partition_element *part_clone= new (mem_root) partition_element(); if (!part_clone) - { - mem_alloc_error(sizeof(partition_element)); DBUG_RETURN(NULL); - } + memcpy(part_clone, part, sizeof(partition_element)); part_clone->subpartitions.empty(); while ((subpart= (subpart_it++))) { partition_element *subpart_clone= new (mem_root) partition_element(); if (!subpart_clone) - { - mem_alloc_error(sizeof(partition_element)); DBUG_RETURN(NULL); - } + memcpy(subpart_clone, subpart, sizeof(partition_element)); part_clone->subpartitions.push_back(subpart_clone, mem_root); } @@ -88,20 +82,15 @@ partition_info *partition_info::get_clone(THD *thd) (part_elem_value *)alloc_root(mem_root, sizeof(part_elem_value) * part->list_val_list.elements); if (!new_val_arr) - { - mem_alloc_error(sizeof(part_elem_value) * part->list_val_list.elements); DBUG_RETURN(NULL); - } + p_column_list_val *new_colval_arr= (p_column_list_val*)alloc_root(mem_root, sizeof(p_column_list_val) * num_columns * part->list_val_list.elements); if (!new_colval_arr) - { - mem_alloc_error(sizeof(p_column_list_val) * num_columns * - part->list_val_list.elements); DBUG_RETURN(NULL); - } + part_elem_value *val; while ((val= list_val_it++)) { @@ -394,10 +383,6 @@ char *partition_info::create_default_partition_names(THD *thd, uint part_no, move_ptr+= MAX_PART_NAME_SIZE; } while (++i < num_parts_arg); } - else - { - mem_alloc_error(num_parts_arg*MAX_PART_NAME_SIZE); - } DBUG_RETURN(ptr); } @@ -422,13 +407,8 @@ char *partition_info::create_default_subpartition_name(THD *thd, uint subpart_no DBUG_ENTER("create_default_subpartition_name"); if (likely(ptr != NULL)) - { my_snprintf(ptr, size_alloc, "%ssp%u", part_name, subpart_no); - } - else - { - mem_alloc_error(size_alloc); - } + DBUG_RETURN(ptr); } @@ -505,10 +485,7 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, default_name+=MAX_PART_NAME_SIZE; } else - { - mem_alloc_error(sizeof(partition_element)); goto end; - } } while (++i < num_parts); result= FALSE; end: @@ -574,10 +551,7 @@ bool partition_info::set_up_default_subpartitions(THD *thd, handler *file, subpart_elem->partition_name= ptr; } else - { - mem_alloc_error(sizeof(partition_element)); goto end; - } } while (++j < num_subparts); } while (++i < num_parts); result= FALSE; @@ -885,7 +859,7 @@ void partition_info::vers_set_hist_part(THD *thd) if (vers_info->interval.is_set()) { - if (vers_info->hist_part->range_value > thd->systime()) + if (vers_info->hist_part->range_value > thd->query_start()) return; partition_element *next= NULL; @@ -896,7 +870,7 @@ void partition_info::vers_set_hist_part(THD *thd) while ((next= it++) != vers_info->now_part) { vers_info->hist_part= next; - if (next->range_value > thd->systime()) + if (next->range_value > thd->query_start()) return; } goto warn; @@ -1506,11 +1480,9 @@ bool partition_info::set_part_expr(THD *thd, char *start_token, Item *item_ptr, size_t expr_len= end_token - start_token; char *func_string= (char*) thd->memdup(start_token, expr_len); - if (!func_string) - { - mem_alloc_error(expr_len); + if (unlikely(!func_string)) return TRUE; - } + if (is_subpart) { list_of_subpart_fields= FALSE; @@ -1665,7 +1637,6 @@ bool partition_info::set_up_charset_field_preps(THD *thd) } DBUG_RETURN(FALSE); error: - mem_alloc_error(size); DBUG_RETURN(TRUE); } @@ -1698,17 +1669,19 @@ bool check_partition_dirs(partition_info *part_info) partition_element *subpart_elem; while ((subpart_elem= sub_it++)) { - if (error_if_data_home_dir(subpart_elem->data_file_name, - "DATA DIRECTORY") || - error_if_data_home_dir(subpart_elem->index_file_name, - "INDEX DIRECTORY")) + if (unlikely(error_if_data_home_dir(subpart_elem->data_file_name, + "DATA DIRECTORY")) || + unlikely(error_if_data_home_dir(subpart_elem->index_file_name, + "INDEX DIRECTORY"))) return 1; } } else { - if (error_if_data_home_dir(part_elem->data_file_name, "DATA DIRECTORY") || - error_if_data_home_dir(part_elem->index_file_name, "INDEX DIRECTORY")) + if (unlikely(error_if_data_home_dir(part_elem->data_file_name, + "DATA DIRECTORY")) || + unlikely(error_if_data_home_dir(part_elem->index_file_name, + "INDEX DIRECTORY"))) return 1; } } @@ -1827,9 +1800,11 @@ part_column_list_val *partition_info::add_column_value(THD *thd) into the structure used for 1 column. After this we call ourselves recursively which should always succeed. */ + num_columns= curr_list_object; if (!reorganize_into_single_field_col_val(thd)) { - DBUG_RETURN(add_column_value(thd)); + if (!init_column_part(thd)) + DBUG_RETURN(add_column_value(thd)); } DBUG_RETURN(NULL); } @@ -1970,10 +1945,8 @@ bool partition_info::init_column_part(THD *thd) if (!(list_val= (part_elem_value*) thd->calloc(sizeof(part_elem_value))) || p_elem->list_val_list.push_back(list_val, thd->mem_root)) - { - mem_alloc_error(sizeof(part_elem_value)); DBUG_RETURN(TRUE); - } + if (num_columns) loc_num_columns= num_columns; else @@ -1981,10 +1954,8 @@ bool partition_info::init_column_part(THD *thd) if (!(col_val_array= (part_column_list_val*) thd->calloc(loc_num_columns * sizeof(part_column_list_val)))) - { - mem_alloc_error(loc_num_columns * sizeof(part_elem_value)); DBUG_RETURN(TRUE); - } + list_val->col_val_array= col_val_array; list_val->added_items= 0; curr_list_val= list_val; @@ -2200,7 +2171,6 @@ bool partition_info::fix_column_value_functions(THD *thd, thd->variables.sql_mode= save_sql_mode; if (!(val_ptr= (uchar*) thd->memdup(field->ptr, len))) { - mem_alloc_error(len); result= TRUE; goto end; } @@ -2304,7 +2274,7 @@ bool partition_info::fix_parser_data(THD *thd) part_elem= it++; List_iterator<part_elem_value> list_val_it(part_elem->list_val_list); num_elements= part_elem->list_val_list.elements; - if (!num_elements && error_if_requires_values()) + if (unlikely(!num_elements && error_if_requires_values())) DBUG_RETURN(true); DBUG_ASSERT(part_type == RANGE_PARTITION ? num_elements == 1U : TRUE); @@ -2715,11 +2685,9 @@ bool partition_info::vers_init_info(THD * thd) column_list= TRUE; num_columns= 1; vers_info= new (thd->mem_root) Vers_part_info; - if (!vers_info) - { - mem_alloc_error(sizeof(Vers_part_info)); + if (unlikely(!vers_info)) return true; - } + return false; } diff --git a/sql/password.c b/sql/password.c index 5e9684acb25..75ac210acd3 100644 --- a/sql/password.c +++ b/sql/password.c @@ -90,7 +90,7 @@ void hash_password(ulong *result, const char *password, uint password_len) { - register ulong nr=1345345333L, add=7, nr2=0x12345671L; + ulong nr=1345345333L, add=7, nr2=0x12345671L; ulong tmp; const char *password_end= password + password_len; for (; password < password_end; password++) @@ -325,7 +325,7 @@ hex2octet(uint8 *to, const char *str, uint len) const char *str_end= str + len; while (str < str_end) { - register char tmp= char_val(*str++); + char tmp= char_val(*str++); *to++= (tmp << 4) | char_val(*str++); } } diff --git a/sql/plistsort.c b/sql/plistsort.c index 99657410fe0..e66bd7c7276 100644 --- a/sql/plistsort.c +++ b/sql/plistsort.c @@ -91,7 +91,7 @@ recursion_point: } { - register struct LS_STRUCT_NAME *sp0= sp++; + struct LS_STRUCT_NAME *sp0= sp++; sp->list_len= sp0->list_len >> 1; sp0->list_len-= sp->list_len; sp->return_point= 0; @@ -100,7 +100,7 @@ recursion_point: return_point0: sp->list1= sorted_list; { - register struct LS_STRUCT_NAME *sp0= sp++; + struct LS_STRUCT_NAME *sp0= sp++; list= list_end; sp->list_len= sp0->list_len; sp->return_point= 1; @@ -108,9 +108,9 @@ return_point0: goto recursion_point; return_point1: { - register LS_LIST_ITEM **hook= &sorted_list; - register LS_LIST_ITEM *list1= sp->list1; - register LS_LIST_ITEM *list2= sorted_list; + LS_LIST_ITEM **hook= &sorted_list; + LS_LIST_ITEM *list1= sp->list1; + LS_LIST_ITEM *list2= sorted_list; if (LS_COMPARE_FUNC_CALL(list1, list2)) { diff --git a/sql/protocol.cc b/sql/protocol.cc index 771fade489b..d29d2fe853d 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -285,7 +285,7 @@ net_send_ok(THD *thd, DBUG_ASSERT(store.length() <= MAX_PACKET_LENGTH); error= my_net_write(net, (const unsigned char*)store.ptr(), store.length()); - if (!error && (!skip_flush || is_eof)) + if (likely(!error) && (!skip_flush || is_eof)) error= net_flush(net); thd->server_status&= ~SERVER_SESSION_STATE_CHANGED; @@ -349,7 +349,7 @@ net_send_eof(THD *thd, uint server_status, uint statement_warn_count) { thd->get_stmt_da()->set_overwrite_status(true); error= write_eof_packet(thd, net, server_status, statement_warn_count); - if (!error) + if (likely(!error)) error= net_flush(net); thd->get_stmt_da()->set_overwrite_status(false); DBUG_PRINT("info", ("EOF sent, so no more error sending allowed")); @@ -393,7 +393,7 @@ static bool write_eof_packet(THD *thd, NET *net, because if 'is_fatal_error' is set the server is not going to execute other queries (see the if test in dispatch_command / COM_QUERY) */ - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) server_status&= ~SERVER_MORE_RESULTS_EXISTS; int2store(buff + 3, server_status); error= my_net_write(net, buff, 5); @@ -590,7 +590,7 @@ void Protocol::end_statement() thd->get_stmt_da()->skip_flush()); break; } - if (!error) + if (likely(!error)) thd->get_stmt_da()->set_is_sent(true); DBUG_VOID_RETURN; } @@ -990,7 +990,7 @@ bool Protocol::send_result_set_row(List<Item> *row_items) DBUG_RETURN(TRUE); } /* Item::send() may generate an error. If so, abort the loop. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(TRUE); } diff --git a/sql/records.cc b/sql/records.cc index ac84ca84ab6..59601ae99f3 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -83,7 +83,7 @@ bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, table->status=0; /* And it's always found */ if (!table->file->inited && - (error= table->file->ha_index_init(idx, 1))) + unlikely(error= table->file->ha_index_init(idx, 1))) { if (print_error) table->file->print_error(error, MYF(0)); @@ -217,7 +217,6 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, info->select=select; info->print_error=print_error; info->unlock_row= rr_unlock_row; - info->ignore_not_found_rows= 0; table->status= 0; /* Rows are always found */ tempfile= 0; @@ -235,7 +234,7 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0); info->ref_pos=table->file->ref; if (!table->file->inited) - if (table->file->ha_rnd_init_with_error(0)) + if (unlikely(table->file->ha_rnd_init_with_error(0))) DBUG_RETURN(1); /* @@ -272,7 +271,7 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, else if (filesort && filesort->record_pointers) { DBUG_PRINT("info",("using record_pointers")); - if (table->file->ha_rnd_init_with_error(0)) + if (unlikely(table->file->ha_rnd_init_with_error(0))) DBUG_RETURN(1); info->cache_pos= filesort->record_pointers; info->cache_end= (info->cache_pos+ @@ -285,7 +284,7 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, int error; info->read_record_func= rr_index_first; if (!table->file->inited && - (error= table->file->ha_index_init(table->file->keyread, 1))) + unlikely((error= table->file->ha_index_init(table->file->keyread, 1)))) { if (print_error) table->file->print_error(error, MYF(0)); @@ -296,7 +295,7 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, { DBUG_PRINT("info",("using rr_sequential")); info->read_record_func= rr_sequential; - if (table->file->ha_rnd_init_with_error(1)) + if (unlikely(table->file->ha_rnd_init_with_error(1))) DBUG_RETURN(1); /* We can use record cache if we don't update dynamic length tables */ if (!table->no_cache && @@ -365,11 +364,8 @@ static int rr_quick(READ_RECORD *info) int tmp; while ((tmp= info->select->quick->get_next())) { - if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED)) - { - tmp= rr_handle_error(info, tmp); - break; - } + tmp= rr_handle_error(info, tmp); + break; } return tmp; } @@ -484,15 +480,8 @@ int rr_sequential(READ_RECORD *info) int tmp; while ((tmp= info->table->file->ha_rnd_next(info->record))) { - /* - rnd_next can return RECORD_DELETED for MyISAM when one thread is - reading and another deleting without locks. - */ - if (info->thd->killed || (tmp != HA_ERR_RECORD_DELETED)) - { - tmp= rr_handle_error(info, tmp); - break; - } + tmp= rr_handle_error(info, tmp); + break; } return tmp; } @@ -508,8 +497,7 @@ static int rr_from_tempfile(READ_RECORD *info) if (!(tmp= info->table->file->ha_rnd_pos(info->record,info->ref_pos))) break; /* The following is extremely unlikely to happen */ - if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + if (tmp == HA_ERR_KEY_NOT_FOUND) continue; tmp= rr_handle_error(info, tmp); break; @@ -560,8 +548,7 @@ int rr_from_pointers(READ_RECORD *info) break; /* The following is extremely unlikely to happen */ - if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + if (tmp == HA_ERR_KEY_NOT_FOUND) continue; tmp= rr_handle_error(info, tmp); break; @@ -631,7 +618,7 @@ static int init_rr_cache(THD *thd, READ_RECORD *info) static int rr_from_cache(READ_RECORD *info) { - reg1 uint i; + uint i; ulong length; my_off_t rest_of_file; int16 error; @@ -642,7 +629,7 @@ static int rr_from_cache(READ_RECORD *info) { if (info->cache_pos != info->cache_end) { - if (info->cache_pos[info->error_offset]) + if (unlikely(info->cache_pos[info->error_offset])) { shortget(error,info->cache_pos); if (info->print_error) @@ -688,7 +675,8 @@ static int rr_from_cache(READ_RECORD *info) record=uint3korr(position); position+=3; record_pos=info->cache+record*info->reclength; - if ((error=(int16) info->table->file->ha_rnd_pos(record_pos,info->ref_pos))) + if (unlikely((error= (int16) info->table->file-> + ha_rnd_pos(record_pos,info->ref_pos)))) { record_pos[info->error_offset]=1; shortstore(record_pos,error); diff --git a/sql/records.h b/sql/records.h index 940c88ca0c7..f6a5069840d 100644 --- a/sql/records.h +++ b/sql/records.h @@ -67,7 +67,7 @@ struct READ_RECORD uchar *cache,*cache_pos,*cache_end,*read_positions; struct st_sort_addon_field *addon_field; /* Pointer to the fields info */ struct st_io_cache *io_cache; - bool print_error, ignore_not_found_rows; + bool print_error; void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *); int read_record() { return read_record_func(this); } diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc index d7e43a8fb39..ad885c925d9 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -167,9 +167,8 @@ rpl_slave_state::check_duplicate_gtid(rpl_gtid *gtid, rpl_group_info *rgi) break; } thd= rgi->thd; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); res= -1; break; } @@ -2602,7 +2601,7 @@ gtid_waiting::wait_for_gtid(THD *thd, rpl_gtid *wait_gtid, &stage_master_gtid_wait_primary, &old_stage); do { - if (thd->check_killed()) + if (unlikely(thd->check_killed(1))) break; else if (wait_until) { @@ -2654,7 +2653,7 @@ gtid_waiting::wait_for_gtid(THD *thd, rpl_gtid *wait_gtid, &stage_master_gtid_wait, &old_stage); did_enter_cond= true; } - while (!elem.done && !thd->check_killed()) + while (!elem.done && likely(!thd->check_killed(1))) { thd_wait_begin(thd, THD_WAIT_BINLOG); if (wait_until) diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index b855dec35f9..3c0ec34f352 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -105,7 +105,7 @@ int injector::transaction::use_table(server_id_type sid, table tbl) int error; - if ((error= check_state(TABLE_STATE))) + if (unlikely((error= check_state(TABLE_STATE)))) DBUG_RETURN(error); server_id_type save_id= m_thd->variables.server_id; @@ -180,7 +180,8 @@ void injector::new_trans(THD *thd, injector::transaction *ptr) int injector::record_incident(THD *thd, Incident incident) { Incident_log_event ev(thd, incident); - if (int error= mysql_bin_log.write(&ev)) + int error; + if (unlikely((error= mysql_bin_log.write(&ev)))) return error; return mysql_bin_log.rotate_and_purge(true); } @@ -189,7 +190,8 @@ int injector::record_incident(THD *thd, Incident incident, const LEX_CSTRING *message) { Incident_log_event ev(thd, incident, message); - if (int error= mysql_bin_log.write(&ev)) + int error; + if (unlikely((error= mysql_bin_log.write(&ev)))) return error; return mysql_bin_log.rotate_and_purge(true); } diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 55a66719e56..6f659aa12ad 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -42,7 +42,8 @@ Master_info::Master_info(LEX_CSTRING *connection_name_arg, using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0), gtid_reconnect_event_skip_count(0), gtid_event_seen(false), in_start_all_slaves(0), in_stop_all_slaves(0), in_flush_all_relay_logs(0), - users(0), killed(0) + users(0), killed(0), + total_ddl_groups(0), total_non_trans_groups(0), total_trans_groups(0) { char *tmp; host[0] = 0; user[0] = 0; password[0] = 0; @@ -677,7 +678,7 @@ file '%s')", fname); mi->rli.is_relay_log_recovery= FALSE; // now change cache READ -> WRITE - must do this before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1); - if ((error= MY_TEST(flush_master_info(mi, TRUE, TRUE)))) + if (unlikely((error= MY_TEST(flush_master_info(mi, TRUE, TRUE))))) sql_print_error("Failed to flush master info file"); mysql_mutex_unlock(&mi->data_lock); DBUG_RETURN(error); @@ -1648,7 +1649,7 @@ bool Master_info_index::start_all_slaves(THD *thd) error= start_slave(thd, mi, 1); mi->release(); mysql_mutex_lock(&LOCK_active_mi); - if (error) + if (unlikely(error)) { my_error(ER_CANT_START_STOP_SLAVE, MYF(0), "START", @@ -1721,7 +1722,7 @@ bool Master_info_index::stop_all_slaves(THD *thd) error= stop_slave(thd, mi, 1); mi->release(); mysql_mutex_lock(&LOCK_active_mi); - if (error) + if (unlikely(error)) { my_error(ER_CANT_START_STOP_SLAVE, MYF(0), "STOP", @@ -2020,7 +2021,7 @@ bool Master_info_index::flush_all_relay_logs() mi->release(); mysql_mutex_lock(&LOCK_active_mi); - if (error) + if (unlikely(error)) { result= true; break; diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 260c35e8c04..54d6b5be592 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -327,6 +327,16 @@ class Master_info : public Slave_reporting_capability uint users; /* Active user for object */ uint killed; + + /* No of DDL event group */ + volatile uint64 total_ddl_groups; + + /* No of non-transactional event group*/ + volatile uint64 total_non_trans_groups; + + /* No of transactional event group*/ + volatile uint64 total_trans_groups; + /* domain-id based filter */ Domain_id_filter domain_id_filter; diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 9f8a3450716..a12bbba5a1f 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -337,7 +337,7 @@ do_gco_wait(rpl_group_info *rgi, group_commit_orderer *gco, thd->set_time_for_next_stage(); do { - if (thd->check_killed() && !rgi->worker_error) + if (!rgi->worker_error && unlikely(thd->check_killed(1))) { DEBUG_SYNC(thd, "rpl_parallel_start_waiting_for_prior_killed"); thd->clear_error(); @@ -402,9 +402,8 @@ do_ftwrl_wait(rpl_group_info *rgi, { if (entry->force_abort || rgi->worker_error) break; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); slave_output_error_info(rgi, thd); signal_error_to_sql_driver_thread(thd, rgi, 1); break; @@ -453,9 +452,8 @@ pool_mark_busy(rpl_parallel_thread_pool *pool, THD *thd) } while (pool->busy) { - if (thd && thd->check_killed()) + if (thd && unlikely(thd->check_killed())) { - thd->send_kill_message(); res= 1; break; } @@ -571,9 +569,8 @@ rpl_pause_for_ftwrl(THD *thd) e->last_committed_sub_id < e->pause_sub_id && !err) { - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); err= 1; break; } @@ -838,8 +835,8 @@ do_retry: } DBUG_EXECUTE_IF("inject_mdev8031", { /* Simulate pending KILL caught in read_relay_log_description_event(). */ - if (thd->check_killed()) { - thd->send_kill_message(); + if (unlikely(thd->check_killed())) + { err= 1; goto err; } @@ -862,13 +859,13 @@ do_retry: if (ev) break; - if (rlog.error < 0) + if (unlikely(rlog.error < 0)) { errmsg= "slave SQL thread aborted because of I/O error"; err= 1; goto check_retry; } - if (rlog.error > 0) + if (unlikely(rlog.error > 0)) { sql_print_error("Slave SQL thread: I/O error reading " "event(errno: %d cur_log->error: %d)", @@ -1036,6 +1033,8 @@ handle_rpl_parallel_thread(void *arg) thd->system_thread= SYSTEM_THREAD_SLAVE_SQL; thd->security_ctx->skip_grants(); thd->variables.max_allowed_packet= slave_max_allowed_packet; + /* Ensure that slave can exeute any alter table it gets from master */ + thd->variables.alter_algorithm= (ulong) Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT; thd->slave_thread= 1; set_slave_thread_options(thd); @@ -1288,7 +1287,7 @@ handle_rpl_parallel_thread(void *arg) if (!err) #endif { - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { thd->clear_error(); thd->get_stmt_da()->reset_diagnostics_area(); @@ -1301,7 +1300,7 @@ handle_rpl_parallel_thread(void *arg) delete_or_keep_event_post_apply(rgi, event_type, qev->ev); DBUG_EXECUTE_IF("rpl_parallel_simulate_temp_err_gtid_0_x_100", err= dbug_simulate_tmp_error(rgi, thd);); - if (err) + if (unlikely(err)) { convert_kill_to_deadlock_error(rgi); if (has_temporary_error(thd) && slave_trans_retries > 0) @@ -2075,7 +2074,7 @@ rpl_parallel_entry::choose_thread(rpl_group_info *rgi, bool *did_enter_cond, /* The thread is ready to queue into. */ break; } - else if (rli->sql_driver_thd->check_killed()) + else if (unlikely(rli->sql_driver_thd->check_killed(1))) { unlock_or_exit_cond(rli->sql_driver_thd, &thr->LOCK_rpl_thread, did_enter_cond, old_stage); @@ -2401,9 +2400,8 @@ rpl_parallel::wait_for_workers_idle(THD *thd) &stage_waiting_for_workers_idle, &old_stage); while (e->current_sub_id > e->last_committed_sub_id) { - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); err= 1; break; } diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 6da3f15cfb9..db579a63ce0 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -196,6 +196,7 @@ unpack_row(rpl_group_info *rgi, uchar const **const current_row_end, ulong *const master_reclength, uchar const *const row_end) { + int error; DBUG_ENTER("unpack_row"); DBUG_ASSERT(row_data); DBUG_ASSERT(table); @@ -419,7 +420,7 @@ unpack_row(rpl_group_info *rgi, /* Add Extra slave persistent columns */ - if (int error= fill_extra_persistent_columns(table, cols->n_bits)) + if (unlikely(error= fill_extra_persistent_columns(table, cols->n_bits))) DBUG_RETURN(error); /* diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 04109ddadb4..9e09a5cf067 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -142,7 +142,7 @@ int Relay_log_info::init(const char* info_fname) log_space_limit= relay_log_space_limit; log_space_total= 0; - if (error_on_rli_init_info) + if (unlikely(error_on_rli_init_info)) goto err; char pattern[FN_REFLEN]; @@ -306,7 +306,7 @@ Failed to open the existing relay log info file '%s' (errno %d)", fname); error= 1; } - if (error) + if (unlikely(error)) { if (info_fd >= 0) mysql_file_close(info_fd, MYF(0)); @@ -415,7 +415,7 @@ Failed to open the existing relay log info file '%s' (errno %d)", before Relay_log_info::flush() */ reinit_io_cache(&info_file, WRITE_CACHE,0L,0,1); - if ((error= flush())) + if (unlikely((error= flush()))) { msg= "Failed to flush relay log info file"; goto err; @@ -1520,7 +1520,7 @@ scan_one_gtid_slave_pos_table(THD *thd, HASH *hash, DYNAMIC_ARRAY *array, LEX_CSTRING *tablename, void **out_hton) { TABLE_LIST tlist; - TABLE *table; + TABLE *UNINIT_VAR(table); bool table_opened= false; bool table_scanned= false; struct gtid_pos_element tmp_entry, *entry; @@ -1537,11 +1537,9 @@ scan_one_gtid_slave_pos_table(THD *thd, HASH *hash, DYNAMIC_ARRAY *array, goto end; bitmap_set_all(table->read_set); - if ((err= table->file->ha_rnd_init_with_error(1))) - { - table->file->print_error(err, MYF(0)); + if (unlikely(err= table->file->ha_rnd_init_with_error(1))) goto end; - } + table_scanned= true; for (;;) { @@ -1551,9 +1549,7 @@ scan_one_gtid_slave_pos_table(THD *thd, HASH *hash, DYNAMIC_ARRAY *array, if ((err= table->file->ha_rnd_next(table->record[0]))) { - if (err == HA_ERR_RECORD_DELETED) - continue; - else if (err == HA_ERR_END_OF_FILE) + if (err == HA_ERR_END_OF_FILE) break; else { @@ -1784,6 +1780,8 @@ gtid_pos_auto_create_tables(rpl_slave_state::gtid_pos_table **list_ptr) p= strmake(p, plugin_name(*auto_engines)->str, FN_REFLEN - (p - buf)); table_name.str= buf; table_name.length= p - buf; + table_case_convert(const_cast<char*>(table_name.str), + static_cast<uint>(table_name.length)); entry= rpl_global_gtid_slave_state->alloc_gtid_pos_table (&table_name, hton, rpl_slave_state::GTID_POS_AUTO_CREATE); if (!entry) @@ -2208,7 +2206,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error) to rollback before continuing with the next events. 4) so we need this "context cleanup" function. */ - if (error) + if (unlikely(error)) { trans_rollback_stmt(thd); // if a "statement transaction" /* trans_rollback() also resets OPTION_GTID_BEGIN */ @@ -2222,7 +2220,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error) m_table_map.clear_tables(); slave_close_thread_tables(thd); - if (error) + if (unlikely(error)) { thd->mdl_context.release_transactional_locks(); diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 58711078db6..31035fb5dcc 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -42,6 +42,12 @@ max_display_length_for_temporal2_field(uint32 int_display_length, @param sql_type Type of the field @param metadata The metadata from the master for the field. @return Maximum length of the field in bytes. + + The precise values calculated by field->max_display_length() and + calculated by max_display_length_for_field() can differ (by +1 or -1) + for integer data types (TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT). + This slight difference is not important here, because we call + this function only for two *different* integer data types. */ static uint32 max_display_length_for_field(enum_field_types sql_type, unsigned int metadata) @@ -737,6 +743,16 @@ can_convert_field_to(Field *field, case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: + /* + max_display_length_for_field() is not fully precise for the integer + data types. So its result cannot be compared to the result of + field->max_dispay_length() when the table field and the binlog field + are of the same type. + This code should eventually be rewritten not to use + compare_lengths(), to detect subtype/supetype relations + just using the type codes. + */ + DBUG_ASSERT(source_type != field->real_type()); *order_var= compare_lengths(field, source_type, metadata); DBUG_ASSERT(*order_var != 0); DBUG_RETURN(is_conversion_ok(*order_var, rli)); diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index 3c88bdddad4..8a82fd9085c 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -779,7 +779,6 @@ void Repl_semi_sync_master::dump_end(THD* thd) int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, my_off_t trx_wait_binlog_pos) { - DBUG_ENTER("Repl_semi_sync_master::commit_trx"); if (get_master_enabled() && trx_wait_binlog_name) @@ -788,15 +787,16 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, struct timespec abstime; int wait_result; PSI_stage_info old_stage; + THD *thd= current_thd; set_timespec(start_ts, 0); - DEBUG_SYNC(current_thd, "rpl_semisync_master_commit_trx_before_lock"); + DEBUG_SYNC(thd, "rpl_semisync_master_commit_trx_before_lock"); /* Acquire the mutex. */ lock(); /* This must be called after acquired the lock */ - THD_ENTER_COND(NULL, &COND_binlog_send, &LOCK_binlog, + THD_ENTER_COND(thd, &COND_binlog_send, &LOCK_binlog, & stage_waiting_for_semi_sync_ack_from_slave, & old_stage); @@ -809,7 +809,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, trx_wait_binlog_name, (ulong)trx_wait_binlog_pos, (int)is_on())); - while (is_on() && !thd_killed(current_thd)) + while (is_on() && !thd_killed(thd)) { if (m_reply_file_name_inited) { @@ -924,7 +924,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, m_active_tranxs may be NULL if someone disabled semi sync during cond_timewait() */ - assert(thd_killed(current_thd) || !m_active_tranxs || + assert(thd_killed(thd) || !m_active_tranxs || !m_active_tranxs->is_tranx_end_pos(trx_wait_binlog_name, trx_wait_binlog_pos)); @@ -937,7 +937,7 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name, /* The lock held will be released by thd_exit_cond, so no need to call unlock() here */ - THD_EXIT_COND(NULL, & old_stage); + THD_EXIT_COND(thd, &old_stage); } DBUG_RETURN(0); diff --git a/sql/set_var.cc b/sql/set_var.cc index bf373dde905..7bf6b9f928d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -245,10 +245,10 @@ uchar *sys_var::global_value_ptr(THD *thd, const LEX_CSTRING *base) bool sys_var::check(THD *thd, set_var *var) { - if ((var->value && do_check(thd, var)) - || (on_check && on_check(this, thd, var))) + if (unlikely((var->value && do_check(thd, var)) || + (on_check && on_check(this, thd, var)))) { - if (!thd->is_error()) + if (likely(!thd->is_error())) { char buff[STRING_BUFFER_USUAL_SIZE]; String str(buff, sizeof(buff), system_charset_info), *res; @@ -718,10 +718,10 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free) set_var_base *var; while ((var=it++)) { - if ((error= var->check(thd))) + if (unlikely((error= var->check(thd)))) goto err; } - if (was_error || !(error= MY_TEST(thd->is_error()))) + if (unlikely(was_error) || likely(!(error= MY_TEST(thd->is_error())))) { it.rewind(); while ((var= it++)) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 17192663381..77347472521 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7089,7 +7089,7 @@ ER_IDENT_CAUSES_TOO_LONG_PATH eng "Long database name and identifier for object resulted in path length exceeding %d characters. Path: '%s'" ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL - eng "cannot silently convert NULL values, as required in this SQL_MODE" + eng "cannot convert NULL to non-constant DEFAULT" ER_MUST_CHANGE_PASSWORD_LOGIN eng "Your password has expired. To log in you must change it using a client that supports expired passwords" @@ -7859,8 +7859,8 @@ ER_VERS_ALTER_ENGINE_PROHIBITED ER_VERS_RANGE_PROHIBITED eng "SYSTEM_TIME range selector is not allowed" -ER_UNUSED_26 - eng "You should never see it" +ER_CONFLICTING_FOR_SYSTEM_TIME + eng "Conflicting FOR SYSTEM_TIME clauses in WITH RECURSIVE" ER_VERS_TABLE_MUST_HAVE_COLUMNS eng "Table %`s must have at least one versioned column" @@ -7913,3 +7913,9 @@ ER_INDEX_FILE_FULL eng "The index file for table '%-.192s' is full" ER_UPDATED_COLUMN_ONLY_ONCE eng "The column %`s.%`s cannot be changed more than once in a single UPDATE statement" +ER_EMPTY_ROW_IN_TVC + eng "Row with no elements is not allowed in table value constructor in this context" +ER_VERS_QUERY_IN_PARTITION + eng "SYSTEM_TIME partitions in table %`s does not support historical query" +ER_KEY_DOESNT_SUPPORT + eng "%s index %`s does not support this operation" diff --git a/sql/slave.cc b/sql/slave.cc index bf70db66f35..275db6165e9 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -223,7 +223,7 @@ static void set_slave_max_allowed_packet(THD *thd, MYSQL *mysql) void init_thread_mask(int* mask,Master_info* mi,bool inverse) { bool set_io = mi->slave_running, set_sql = mi->rli.slave_running; - register int tmp_mask=0; + int tmp_mask=0; DBUG_ENTER("init_thread_mask"); if (set_io) @@ -344,8 +344,15 @@ gtid_pos_table_creation(THD *thd, plugin_ref engine, LEX_CSTRING *table_name) goto end; mysql_parse(thd, thd->query(), thd->query_length(), &parser_state, FALSE, FALSE); - if (thd->is_error()) + if (unlikely(thd->is_error())) err= 1; + /* The warning is relevant to 10.3 and earlier. */ + sql_print_warning("The automatically created table '%s' name may not be " + "entirely in lowercase. The table name will be converted " + "to lowercase to any future upgrade to 10.4.0 and later " + "version where it will be auto-created at once " + "in lowercase.", + table_name->str); end: thd->variables.option_bits= thd_saved_option; thd->reset_query(); @@ -356,7 +363,7 @@ end: static void handle_gtid_pos_auto_create_request(THD *thd, void *hton) { - int err; + int UNINIT_VAR(err); plugin_ref engine= NULL, *auto_engines; rpl_slave_state::gtid_pos_table *entry; StringBuffer<FN_REFLEN> loc_table_name; @@ -739,7 +746,7 @@ int init_slave() thd->reset_globals(); delete thd; - if (error) + if (unlikely(error)) { sql_print_error("Failed to create slave threads"); goto err; @@ -885,7 +892,7 @@ bool init_slave_skip_errors(const char* arg) if (!arg || !*arg) // No errors defined goto end; - if (my_bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0)) + if (unlikely(my_bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))) DBUG_RETURN(1); use_slave_mask= 1; @@ -978,10 +985,10 @@ bool init_slave_transaction_retry_errors(const char* arg) p++; } - if (!(slave_transaction_retry_errors= - (uint *) my_once_alloc(sizeof(int) * - slave_transaction_retry_error_length, - MYF(MY_WME)))) + if (unlikely(!(slave_transaction_retry_errors= + (uint *) my_once_alloc(sizeof(int) * + slave_transaction_retry_error_length, + MYF(MY_WME))))) DBUG_RETURN(1); /* @@ -1030,11 +1037,12 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) } else mi->rli.abort_slave=1; - if ((error=terminate_slave_thread(mi->rli.sql_driver_thd, sql_lock, - &mi->rli.stop_cond, - &mi->rli.slave_running, - skip_lock)) && - !force_all) + if (unlikely((error= terminate_slave_thread(mi->rli.sql_driver_thd, + sql_lock, + &mi->rli.stop_cond, + &mi->rli.slave_running, + skip_lock))) && + !force_all) DBUG_RETURN(error); retval= error; @@ -1052,11 +1060,11 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock) { DBUG_PRINT("info",("Terminating IO thread")); mi->abort_slave=1; - if ((error=terminate_slave_thread(mi->io_thd, io_lock, - &mi->stop_cond, - &mi->slave_running, - skip_lock)) && - !force_all) + if (unlikely((error= terminate_slave_thread(mi->io_thd, io_lock, + &mi->stop_cond, + &mi->slave_running, + skip_lock))) && + !force_all) DBUG_RETURN(error); if (!retval) retval= error; @@ -1232,8 +1240,9 @@ int start_slave_thread( } start_id= *slave_run_id; DBUG_PRINT("info",("Creating new slave thread")); - if ((error = mysql_thread_create(thread_key, - &th, &connection_attrib, h_func, (void*)mi))) + if (unlikely((error= mysql_thread_create(thread_key, + &th, &connection_attrib, h_func, + (void*)mi)))) { sql_print_error("Can't create slave thread (errno= %d).", error); if (start_lock) @@ -1346,7 +1355,7 @@ int start_slave_threads(THD *thd, mi->rli.restart_gtid_pos.reset(); } - if (!error && (thread_mask & SLAVE_IO)) + if (likely(!error) && likely((thread_mask & SLAVE_IO))) error= start_slave_thread( #ifdef HAVE_PSI_INTERFACE key_thread_slave_io, @@ -1355,7 +1364,7 @@ int start_slave_threads(THD *thd, cond_io, &mi->slave_running, &mi->slave_run_id, mi); - if (!error && (thread_mask & SLAVE_SQL)) + if (likely(!error) && likely(thread_mask & SLAVE_SQL)) { error= start_slave_thread( #ifdef HAVE_PSI_INTERFACE @@ -1365,7 +1374,7 @@ int start_slave_threads(THD *thd, cond_sql, &mi->rli.slave_running, &mi->rli.slave_run_id, mi); - if (error) + if (unlikely(error)) terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex); } DBUG_RETURN(error); @@ -2337,7 +2346,8 @@ past_checksum: */ if (opt_replicate_events_marked_for_skip == RPL_SKIP_FILTER_ON_MASTER) { - if (mysql_real_query(mysql, STRING_WITH_LEN("SET skip_replication=1"))) + if (unlikely(mysql_real_query(mysql, + STRING_WITH_LEN("SET skip_replication=1")))) { err_code= mysql_errno(mysql); if (is_network_error(err_code)) @@ -2381,7 +2391,7 @@ past_checksum: STRINGIFY_ARG(MARIA_SLAVE_CAPABILITY_ANNOTATE))), mysql_real_query(mysql, STRING_WITH_LEN("SET @mariadb_slave_capability=" STRINGIFY_ARG(MARIA_SLAVE_CAPABILITY_MINE)))); - if (rc) + if (unlikely(rc)) { err_code= mysql_errno(mysql); if (is_network_error(err_code)) @@ -2457,7 +2467,7 @@ after_set_capability: query_str.append(STRING_WITH_LEN("'"), system_charset_info); rc= mysql_real_query(mysql, query_str.ptr(), query_str.length()); - if (rc) + if (unlikely(rc)) { err_code= mysql_errno(mysql); if (is_network_error(err_code)) @@ -2490,7 +2500,7 @@ after_set_capability: } rc= mysql_real_query(mysql, query_str.ptr(), query_str.length()); - if (rc) + if (unlikely(rc)) { err_code= mysql_errno(mysql); if (is_network_error(err_code)) @@ -2523,7 +2533,7 @@ after_set_capability: } rc= mysql_real_query(mysql, query_str.ptr(), query_str.length()); - if (rc) + if (unlikely(rc)) { err_code= mysql_errno(mysql); if (is_network_error(err_code)) @@ -2559,7 +2569,7 @@ after_set_capability: query_str.append(STRING_WITH_LEN("'"), system_charset_info); rc= mysql_real_query(mysql, query_str.ptr(), query_str.length()); - if (rc) + if (unlikely(rc)) { err_code= mysql_errno(mysql); if (is_network_error(err_code)) @@ -3121,6 +3131,19 @@ void show_master_info_get_fields(THD *thd, List<Item> *field_list, field_list->push_back(new (mem_root) Item_empty_string(thd, "Slave_SQL_Running_State", 20)); + field_list->push_back(new (mem_root) + Item_return_int(thd, "Slave_DDL_Groups", 20, + MYSQL_TYPE_LONGLONG), + mem_root); + field_list->push_back(new (mem_root) + Item_return_int(thd, "Slave_Non_Transactional_Groups", 20, + MYSQL_TYPE_LONGLONG), + mem_root); + field_list->push_back(new (mem_root) + Item_return_int(thd, "Slave_Transactional_Groups", 20, + MYSQL_TYPE_LONGLONG), + mem_root); + if (full) { field_list->push_back(new (mem_root) @@ -3351,6 +3374,17 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full, // Slave_SQL_Running_State protocol->store(slave_sql_running_state, &my_charset_bin); + uint64 events; + events= (uint64)my_atomic_load64_explicit((volatile int64 *) + &mi->total_ddl_groups, MY_MEMORY_ORDER_RELAXED); + protocol->store(events); + events= (uint64)my_atomic_load64_explicit((volatile int64 *) + &mi->total_non_trans_groups, MY_MEMORY_ORDER_RELAXED); + protocol->store(events); + events= (uint64)my_atomic_load64_explicit((volatile int64 *) + &mi->total_trans_groups, MY_MEMORY_ORDER_RELAXED); + protocol->store(events); + if (full) { protocol->store((uint32) mi->rli.retried_trans); @@ -3650,7 +3684,7 @@ static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings, #endif len = cli_safe_read_reallen(mysql, network_read_len); - if (len == packet_error || (long) len < 1) + if (unlikely(len == packet_error || (long) len < 1)) { if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED) { @@ -3715,7 +3749,7 @@ has_temporary_error(THD *thd) error or not. This is currently the case for Incident_log_event, which sets no message. Return FALSE. */ - if (!thd->is_error()) + if (!likely(thd->is_error())) DBUG_RETURN(0); current_errno= thd->get_stmt_da()->sql_errno(); @@ -3936,7 +3970,7 @@ apply_event_and_update_pos_apply(Log_event* ev, THD* thd, rpl_group_info *rgi, TODO: Replace this with a decent error message when merged with BUG#24954 (which adds several new error message). */ - if (error) + if (unlikely(error)) { rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR, rgi->gtid_info(), "It was not possible to update the positions" @@ -4327,19 +4361,19 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, update_log_pos failed: this should not happen, so we don't retry. */ - if (exec_res == 2) + if (unlikely(exec_res == 2)) DBUG_RETURN(1); #ifdef WITH_WSREP - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state == NO_CONFLICT) { - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); #endif /* WITH_WSREP */ if (slave_trans_retries) { int UNINIT_VAR(temp_err); - if (exec_res && (temp_err= has_temporary_error(thd))) + if (unlikely(exec_res) && (temp_err= has_temporary_error(thd))) { const char *errmsg; rli->clear_error(); @@ -4412,7 +4446,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli, #ifdef WITH_WSREP } else - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); #endif /* WITH_WSREP */ thread_safe_increment64(&rli->executed_entries); @@ -4776,7 +4810,7 @@ connected: if (check_io_slave_killed(mi, NullS)) goto err; - if (event_len == packet_error) + if (unlikely(event_len == packet_error)) { uint mysql_error_number= mysql_errno(mysql); switch (mysql_error_number) { @@ -5079,7 +5113,7 @@ slave_output_error_info(rpl_group_info *rgi, THD *thd) Relay_log_info *rli= rgi->rli; uint32 const last_errno= rli->last_error().number; - if (thd->is_error()) + if (unlikely(thd->is_error())) { char const *const errmsg= thd->get_stmt_da()->message(); @@ -5123,7 +5157,7 @@ slave_output_error_info(rpl_group_info *rgi, THD *thd) udf_error = true; sql_print_warning("Slave: %s Error_code: %d", err->get_message_text(), err->get_sql_errno()); } - if (udf_error) + if (unlikely(udf_error)) { StringBuffer<100> tmp; if (rli->mi->using_gtid != Master_info::USE_GTID_NO) @@ -5251,6 +5285,10 @@ pthread_handler_t handle_slave_sql(void *arg) applied. In all other cases it must be FALSE. */ thd->variables.binlog_annotate_row_events= 0; + + /* Ensure that slave can exeute any alter table it gets from master */ + thd->variables.alter_algorithm= (ulong) Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT; + add_to_active_threads(thd); /* We are going to set slave_running to 1. Assuming slave I/O thread is @@ -5403,7 +5441,7 @@ pthread_handler_t handle_slave_sql(void *arg) if (opt_init_slave.length) { execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave); - if (thd->is_slave_error) + if (unlikely(thd->is_slave_error)) { rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Slave SQL thread aborted. Can't execute init_slave query"); @@ -6069,7 +6107,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) { int error= 0; StringBuffer<1024> error_msg; - ulonglong inc_pos; + ulonglong inc_pos= 0; ulonglong event_pos; Relay_log_info *rli= &mi->rli; mysql_mutex_t *log_lock= rli->relay_log.get_log_lock(); @@ -6908,7 +6946,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) } mysql_mutex_unlock(log_lock); - if (!error && + if (likely(!error) && mi->using_gtid != Master_info::USE_GTID_NO && mi->events_queued_since_last_gtid > 0 && ( (mi->last_queued_gtid_standalone && @@ -6957,11 +6995,11 @@ err: Do not print ER_SLAVE_RELAY_LOG_WRITE_FAILURE error here, as the caller handle_slave_io() prints it on return. */ - if (error && error != ER_SLAVE_RELAY_LOG_WRITE_FAILURE) + if (unlikely(error) && error != ER_SLAVE_RELAY_LOG_WRITE_FAILURE) mi->report(ERROR_LEVEL, error, NULL, ER_DEFAULT(error), error_msg.ptr()); - if(is_malloc) + if (unlikely(is_malloc)) my_free((void *)new_buf); DBUG_RETURN(error); @@ -7428,7 +7466,7 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size) } if (opt_reckless_slave) // For mysql-test cur_log->error = 0; - if (cur_log->error < 0) + if (unlikely(cur_log->error < 0)) { errmsg = "slave SQL thread aborted because of I/O error"; if (hot_log) diff --git a/sql/sp.cc b/sql/sp.cc index cb05108a5bc..af86737ebb9 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2002, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2002, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -423,7 +423,7 @@ private: bool m_print_once; public: - Proc_table_intact() : m_print_once(TRUE) {} + Proc_table_intact() : m_print_once(TRUE) { has_keys= TRUE; } protected: void report_error(uint code, const char *fmt, ...); @@ -780,6 +780,7 @@ Sp_handler::db_find_and_cache_routine(THD *thd, Silence DEPRECATED SYNTAX warnings when loading a stored procedure into the cache. */ + struct Silence_deprecated_warning : public Internal_error_handler { public: @@ -1002,7 +1003,7 @@ Sp_handler::db_load_routine(THD *thd, const Database_qualified_name *name, if (type() == TYPE_ENUM_PACKAGE_BODY) { - sp_package *package= sphp[0]->get_package(); + sp_package *package= (*sphp)->get_package(); List_iterator<LEX> it(package->m_routine_implementations); for (LEX *lex; (lex= it++); ) { @@ -1078,6 +1079,7 @@ sp_returns_type(THD *thd, String &result, const sp_head *sp) @return SP_OK on success, or SP_DELETE_ROW_FAILED on error. used to indicate about errors. */ + int Sp_handler::sp_drop_routine_internal(THD *thd, const Database_qualified_name *name, @@ -1111,7 +1113,7 @@ Sp_handler::sp_find_and_drop_routine(THD *thd, TABLE *table, const Database_qualified_name *name) const { int ret; - if (SP_OK != (ret= db_find_routine_aux(thd, name, table))) + if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK) return ret; return sp_drop_routine_internal(thd, name, table); } @@ -1123,11 +1125,23 @@ Sp_handler_package_spec:: const Database_qualified_name *name) const { int ret; - if (SP_OK != (ret= db_find_routine_aux(thd, name, table))) + if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK) return ret; + /* + When we do "DROP PACKAGE pkg", we should also perform + "DROP PACKAGE BODY pkg" automatically. + */ ret= sp_handler_package_body.sp_find_and_drop_routine(thd, table, name); if (ret != SP_KEY_NOT_FOUND && ret != SP_OK) - return ret; + { + /* + - SP_KEY_NOT_FOUND means that "CREATE PACKAGE pkg" did not + have a correspoinding "CREATE PACKAGE BODY pkg" yet. + - SP_OK means that "CREATE PACKAGE pkg" had a correspoinding + "CREATE PACKAGE BODY pkg", which was successfully dropped. + */ + return ret; // Other codes mean an unexpecte error + } return Sp_handler::sp_find_and_drop_routine(thd, table, name); } @@ -1231,7 +1245,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const DBUG_ASSERT(0); ret= SP_OK; } - if (ret) + if (ret != SP_OK) goto done; } else if (lex->create_info.if_not_exists()) @@ -1565,7 +1579,7 @@ Sp_handler::sp_drop_routine(THD *thd, if (!(table= open_proc_table_for_update(thd))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); - if (SP_OK == (ret= sp_find_and_drop_routine(thd, table, name)) && + if ((ret= sp_find_and_drop_routine(thd, table, name)) == SP_OK && write_bin_log(thd, TRUE, thd->query(), thd->query_length())) ret= SP_INTERNAL_ERROR; /* @@ -1916,6 +1930,7 @@ Sp_handler::sp_show_create_routine(THD *thd, and return it as a 0-terminated string 'pkg.name' -> 'pkg\0' */ + class Prefix_name_buf: public LEX_CSTRING { char m_buf[SAFE_NAME_LEN + 1]; @@ -1948,6 +1963,7 @@ public: - either returns the original SP, - or makes and returns a new clone of SP */ + sp_head * Sp_handler::sp_clone_and_link_routine(THD *thd, const Database_qualified_name *name, @@ -2015,7 +2031,7 @@ Sp_handler::sp_clone_and_link_routine(THD *thd, 1. Cut the package name prefix from the routine name: 'pkg1.p1' -> 'p1', to have db_load_routine() generate and parse a query like this: CREATE PROCEDURE p1 ...; - rether than: + rather than: CREATE PROCEDURE pkg1.p1 ...; The latter would be misinterpreted by the parser as a standalone routine 'p1' in the database 'pkg1', which is not what we need. @@ -2126,6 +2142,7 @@ Sp_handler::sp_find_routine(THD *thd, const Database_qualified_name *name, @retval non-NULL - a pointer to an sp_head object @retval NULL - an error happened. */ + sp_head * Sp_handler::sp_find_package_routine(THD *thd, const LEX_CSTRING pkgname_str, @@ -2168,6 +2185,7 @@ Sp_handler::sp_find_package_routine(THD *thd, @retval non-NULL - a pointer to an sp_head object @retval NULL - an error happened */ + sp_head * Sp_handler::sp_find_package_routine(THD *thd, const Database_qualified_name *name, @@ -2275,7 +2293,7 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena, { Sroutine_hash_entry *rn= (Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry)); - if (!rn) // OOM. Error will be reported using fatal_error(). + if (unlikely(!rn)) // OOM. Error will be reported using fatal_error(). return FALSE; rn->mdl_request.init(key, MDL_SHARED, MDL_TRANSACTION); if (my_hash_insert(&prelocking_ctx->sroutines, (uchar *)rn)) @@ -2301,6 +2319,7 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena, It's used during parsing of CREATE PACKAGE BODY, to load the corresponding CREATE PACKAGE. */ + int Sp_handler::sp_cache_routine_reentrant(THD *thd, const Database_qualified_name *name, @@ -2315,7 +2334,7 @@ Sp_handler::sp_cache_routine_reentrant(THD *thd, } -/* +/** Check if a routine has a declaration in the CREATE PACKAGE statement, by looking up in thd->sp_package_spec_cache, and by loading from mysql.proc if needed. @@ -2340,6 +2359,7 @@ Sp_handler::sp_cache_routine_reentrant(THD *thd, After the call of this function, the package specification is always cached, unless a fatal error happens. */ + static bool is_package_public_routine(THD *thd, const LEX_CSTRING &db, @@ -2356,7 +2376,7 @@ is_package_public_routine(THD *thd, } -/* +/** Check if a routine has a declaration in the CREATE PACKAGE statement by looking up in sp_package_spec_cache. @@ -2373,6 +2393,7 @@ is_package_public_routine(THD *thd, The package specification (i.e. the CREATE PACKAGE statement) for the current package body must already be loaded and cached at this point. */ + static bool is_package_public_routine_quick(THD *thd, const LEX_CSTRING &db, @@ -2388,10 +2409,11 @@ is_package_public_routine_quick(THD *thd, } -/* +/** Check if a qualified name, e.g. "CALL name1.name2", refers to a known routine in the package body "pkg". */ + static bool is_package_body_routine(THD *thd, sp_package *pkg, const LEX_CSTRING &name1, @@ -2404,11 +2426,12 @@ is_package_body_routine(THD *thd, sp_package *pkg, } -/* +/** Resolve a qualified routine reference xxx.yyy(), between: - A standalone routine: xxx.yyy - A package routine: current_database.xxx.yyy */ + bool Sp_handler:: sp_resolve_package_routine_explicit(THD *thd, sp_head *caller, @@ -2444,11 +2467,12 @@ bool Sp_handler:: } -/* +/** Resolve a non-qualified routine reference yyy(), between: - A standalone routine: current_database.yyy - A package routine: current_database.current_package.yyy */ + bool Sp_handler:: sp_resolve_package_routine_implicit(THD *thd, sp_head *caller, @@ -2534,6 +2558,7 @@ bool Sp_handler:: @retval false on success @retval true on error (e.g. EOM, could not read CREATE PACKAGE) */ + bool Sp_handler::sp_resolve_package_routine(THD *thd, sp_head *caller, @@ -2787,7 +2812,7 @@ int Sp_handler::sp_cache_routine(THD *thd, an error with it's return value without calling my_error(), we set the generic "mysql.proc table corrupt" error here. */ - if (! thd->is_error()) + if (!thd->is_error()) { my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), ErrConvDQName(name).ptr(), ret); @@ -2813,6 +2838,7 @@ int Sp_handler::sp_cache_routine(THD *thd, @retval false - loaded or does not exists @retval true - error while loading mysql.proc */ + int Sp_handler::sp_cache_package_routine(THD *thd, const LEX_CSTRING &pkgname_cstr, @@ -2831,7 +2857,7 @@ Sp_handler::sp_cache_package_routine(THD *thd, sp_package *pkg= ph ? ph->get_package() : NULL; LEX_CSTRING tmp= name->m_name; const char *dot= strrchr(tmp.str, '.'); - size_t prefix_length= dot ? dot - tmp.str + 1 : NULL; + size_t prefix_length= dot ? dot - tmp.str + 1 : 0; tmp.str+= prefix_length; tmp.length-= prefix_length; LEX *rlex= pkg ? pkg->m_routine_implementations.find(tmp, type()) : NULL; @@ -2856,6 +2882,7 @@ Sp_handler::sp_cache_package_routine(THD *thd, @retval false - loaded or does not exists @retval true - error while loading mysql.proc */ + int Sp_handler::sp_cache_package_routine(THD *thd, const Database_qualified_name *name, bool lookup_only, sp_head **sp) const @@ -2873,6 +2900,7 @@ int Sp_handler::sp_cache_package_routine(THD *thd, @return Returns false on success, true on (alloc) failure. */ + bool Sp_handler::show_create_sp(THD *thd, String *buf, const LEX_CSTRING &db, @@ -3015,15 +3043,15 @@ Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table, LEX_CSTRING Sp_handler_procedure::empty_body_lex_cstring(sql_mode_t mode) const { - static LEX_CSTRING m_empty_body_std= {C_STRING_WITH_LEN("BEGIN END")}; - static LEX_CSTRING m_empty_body_ora= {C_STRING_WITH_LEN("AS BEGIN NULL; END")}; + static LEX_CSTRING m_empty_body_std= {STRING_WITH_LEN("BEGIN END")}; + static LEX_CSTRING m_empty_body_ora= {STRING_WITH_LEN("AS BEGIN NULL; END")}; return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std; } LEX_CSTRING Sp_handler_function::empty_body_lex_cstring(sql_mode_t mode) const { - static LEX_CSTRING m_empty_body_std= {C_STRING_WITH_LEN("RETURN NULL")}; - static LEX_CSTRING m_empty_body_ora= {C_STRING_WITH_LEN("AS BEGIN RETURN NULL; END")}; + static LEX_CSTRING m_empty_body_std= {STRING_WITH_LEN("RETURN NULL")}; + static LEX_CSTRING m_empty_body_ora= {STRING_WITH_LEN("AS BEGIN RETURN NULL; END")}; return mode & MODE_ORACLE ? m_empty_body_ora : m_empty_body_std; } @@ -371,12 +371,12 @@ public: stored_procedure_type type() const { return TYPE_ENUM_PACKAGE; } LEX_CSTRING type_lex_cstring() const { - static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("PACKAGE")}; + static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE")}; return m_type_str; } LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const { - static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("BEGIN END")}; + static LEX_CSTRING m_empty_body= {STRING_WITH_LEN("BEGIN END")}; return m_empty_body; } const char *show_create_routine_col1_caption() const @@ -404,12 +404,12 @@ public: stored_procedure_type type() const { return TYPE_ENUM_PACKAGE_BODY; } LEX_CSTRING type_lex_cstring() const { - static LEX_CSTRING m_type_str= {C_STRING_WITH_LEN("PACKAGE BODY")}; + static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE BODY")}; return m_type_str; } LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const { - static LEX_CSTRING m_empty_body= {C_STRING_WITH_LEN("BEGIN END")}; + static LEX_CSTRING m_empty_body= {STRING_WITH_LEN("BEGIN END")}; return m_empty_body; } const char *show_create_routine_col1_caption() const diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a9056553080..d86a1f38953 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -368,6 +368,7 @@ Item *THD::sp_prepare_func_item(Item **it_addr, uint cols) /** Fix an Item for evaluation for SP. */ + Item *THD::sp_fix_func_item(Item **it_addr) { DBUG_ENTER("THD::sp_fix_func_item"); @@ -593,6 +594,7 @@ sp_package::~sp_package() /* Test if two routines have equal specifications */ + bool sp_head::eq_routine_spec(const sp_head *sp) const { // TODO: Add tests for equal return data types (in case of FUNCTION) @@ -835,7 +837,7 @@ sp_head::~sp_head() thd->lex->sphead= NULL; lex_end(thd->lex); delete thd->lex; - thd->lex= thd->stmt_lex= lex; + thd->lex= lex; } my_hash_free(&m_sptabs); @@ -904,8 +906,13 @@ sp_head::create_result_field(uint field_max_length, const LEX_CSTRING *field_nam Perhaps we should refactor prepare_create_field() to set Create_field::length to maximum octet length for BLOBs, instead of packed length). + + Note, for integer data types, field_max_length can be bigger + than the user specified length, e.g. a field of the INT(1) data type + is translated to the item with max_length=11. */ DBUG_ASSERT(field_max_length <= m_return_field_def.length || + m_return_field_def.type_handler()->cmp_type() == INT_RESULT || (current_thd->stmt_arena->is_stmt_execute() && m_return_field_def.length == 8 && (m_return_field_def.pack_flag & @@ -1147,7 +1154,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) backup_arena; query_id_t old_query_id; TABLE *old_derived_tables; - LEX *old_lex, *old_stmt_lex; + LEX *old_lex; Item_change_list old_change_list; String old_packet; uint old_server_status; @@ -1254,7 +1261,6 @@ sp_head::execute(THD *thd, bool merge_da_on_success) do it in each instruction */ old_lex= thd->lex; - old_stmt_lex= thd->stmt_lex; /* We should also save Item tree change list to avoid rollback something too early in the calling query. @@ -1371,7 +1377,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) errors are not catchable by SQL handlers) or the connection has been killed during execution. */ - if (!thd->is_fatal_error && !thd->killed_errno() && + if (likely(!thd->is_fatal_error) && likely(!thd->killed_errno()) && ctx->handle_sql_condition(thd, &ip, i)) { err_status= FALSE; @@ -1380,7 +1386,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success) /* Reset sp_rcontext::end_partial_result_set flag. */ ctx->end_partial_result_set= FALSE; - } while (!err_status && !thd->killed && !thd->is_fatal_error && + } while (!err_status && likely(!thd->killed) && + likely(!thd->is_fatal_error) && !thd->spcont->pause_state); #if defined(ENABLED_PROFILING) @@ -1410,7 +1417,6 @@ sp_head::execute(THD *thd, bool merge_da_on_success) DBUG_ASSERT(thd->Item_change_list::is_empty()); old_change_list.move_elements_to(thd); thd->lex= old_lex; - thd->stmt_lex= old_stmt_lex; thd->set_query_id(old_query_id); DBUG_ASSERT(!thd->derived_tables); thd->derived_tables= old_derived_tables; @@ -1600,6 +1606,7 @@ bool sp_head::check_execute_access(THD *thd) const @retval NULL - error (access denided or EOM) @retval !NULL - success (the invoker has rights to all %TYPE tables) */ + sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value, Row_definition_list *defs, bool switch_security_ctx) @@ -1777,6 +1784,7 @@ err_with_cleanup: /* Execute the package initialization section. */ + bool sp_package::instantiate_if_needed(THD *thd) { List<Item> args; @@ -2452,6 +2460,7 @@ sp_head::merge_lex(THD *thd, LEX *oldlex, LEX *sublex) /** Put the instruction on the backpatch list, associated with the label. */ + int sp_head::push_backpatch(THD *thd, sp_instr *i, sp_label *lab, List<bp_t> *list, backpatch_instr_type itype) @@ -2507,6 +2516,7 @@ sp_head::push_backpatch_goto(THD *thd, sp_pcontext *ctx, sp_label *lab) Update all instruction with this label in the backpatch list to the current position. */ + void sp_head::backpatch(sp_label *lab) { @@ -3034,6 +3044,7 @@ bool sp_head::add_instr_preturn(THD *thd, sp_pcontext *spcont) QQ: Perhaps we need a dedicated sp_instr_nop for this purpose. */ + bool sp_head::replace_instr_to_nop(THD *thd, uint ip) { sp_instr *instr= get_instr(ip); @@ -3158,6 +3169,7 @@ sp_head::opt_mark() @return 0 if ok, !=0 on error. */ + int sp_head::show_routine_code(THD *thd) { @@ -3265,7 +3277,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, We should not save old value since it is saved/restored in sp_head::execute() when we are entering/leaving routine. */ - thd->lex= thd->stmt_lex= m_lex; + thd->lex= m_lex; thd->set_query_id(next_query_id()); @@ -3305,7 +3317,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, if (open_tables) res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables); - if (!res) + if (likely(!res)) { res= instr->exec_core(thd, nextp); DBUG_PRINT("info",("exec_core returned: %d", res)); @@ -3365,7 +3377,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, Update the state of the active arena if no errors on open_tables stage. */ - if (!res || !thd->is_error() || + if (likely(!res) || likely(!thd->is_error()) || (thd->get_stmt_da()->sql_errno() != ER_CANT_REOPEN_TABLE && thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE && thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE && @@ -3460,7 +3472,6 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) int res; bool save_enable_slow_log; const CSET_STRING query_backup= thd->query_string; - QUERY_START_TIME_INFO time_info; Sub_statement_state backup_state; DBUG_ENTER("sp_instr_stmt::execute"); DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command())); @@ -3470,15 +3481,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->profiling.set_query_source(m_query.str, m_query.length); #endif - if ((save_enable_slow_log= thd->enable_slow_log)) - { - /* - Save start time info for the CALL statement and overwrite it with the - current time for log_slow_statement() to log the individual query timing. - */ - thd->backup_query_start_time(&time_info); - thd->set_time(); - } + save_enable_slow_log= thd->enable_slow_log; thd->store_slow_query_state(&backup_state); if (!(res= alloc_query(thd, m_query.str, m_query.length)) && @@ -3536,15 +3539,12 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->set_query(query_backup); thd->query_name_consts= 0; - if (!thd->is_error()) + if (likely(!thd->is_error())) { res= 0; thd->get_stmt_da()->reset_diagnostics_area(); } } - /* Restore the original query start time */ - if (thd->enable_slow_log) - thd->restore_query_start_time(&time_info); DBUG_RETURN(res || thd->is_error()); } @@ -4402,7 +4402,7 @@ sp_instr_cfetch::print(String *str) int sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) { - DBUG_ENTER("sp_instr_cfetch::execute"); + DBUG_ENTER("sp_instr_agg_cfetch::execute"); int res= 0; if (!thd->spcont->instr_ptr) { @@ -4427,7 +4427,16 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +void +sp_instr_agg_cfetch::print(String *str) +{ + uint rsrv= SP_INSTR_UINT_MAXLEN+11; + + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("agg_cfetch")); +} /* sp_instr_cursor_copy_struct class functions @@ -4441,6 +4450,7 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) - opens the cursor without copying data (materialization). - copies the cursor structure to the associated %ROWTYPE variable. */ + int sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) { @@ -4917,6 +4927,7 @@ sp_head::set_local_variable(THD *thd, sp_pcontext *spcont, /** Similar to set_local_variable(), but for ROW variable fields. */ + bool sp_head::set_local_variable_row_field(THD *thd, sp_pcontext *spcont, const Sp_rcontext_handler *rh, @@ -5111,6 +5122,7 @@ bool sp_head::spvar_fill_table_rowtype_reference(THD *thd, END p1; Check that the first p1 and the last p1 match. */ + bool sp_head::check_package_routine_end_name(const LEX_CSTRING &end_name) const { LEX_CSTRING non_qualified_name= m_name; @@ -5137,7 +5149,5 @@ err: ulong sp_head::sp_cache_version() const { - return m_parent ? m_parent->sp_cache_version() : - m_sp_cache_version; - + return m_parent ? m_parent->sp_cache_version() : m_sp_cache_version; } diff --git a/sql/sp_head.h b/sql/sp_head.h index f588f79b599..c0c0c83b77e 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1957,7 +1957,7 @@ public: virtual int execute(THD *thd, uint *nextp); - virtual void print(String *str){}; + virtual void print(String *str); }; // class sp_instr_agg_cfetch : public sp_instr diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 2e9ae23d7f9..6166d1d9615 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -52,7 +52,7 @@ const LEX_CSTRING *Sp_rcontext_handler_local::get_name_prefix() const const LEX_CSTRING *Sp_rcontext_handler_package_body::get_name_prefix() const { static const LEX_CSTRING sp_package_body_variable_prefix_clex_str= - {C_STRING_WITH_LEN("PACKAGE_BODY.")}; + {STRING_WITH_LEN("PACKAGE_BODY.")}; return &sp_package_body_variable_prefix_clex_str; } @@ -196,11 +196,12 @@ bool sp_rcontext::init_var_table(THD *thd, */ static inline bool check_column_grant_for_type_ref(THD *thd, TABLE_LIST *table_list, - const char *str, size_t length) + const char *str, size_t length, + Field *fld) { #ifndef NO_EMBEDDED_ACCESS_CHECKS table_list->table->grant.want_privilege= SELECT_ACL; - return check_column_grant_in_table_ref(thd, table_list, str, length); + return check_column_grant_in_table_ref(thd, table_list, str, length, fld); #else return false; #endif @@ -234,11 +235,11 @@ bool Qualified_column_ident::resolve_type_ref(THD *thd, Column_definition *def) !open_tables_only_view_structure(thd, table_list, thd->mdl_context.has_locks())) { - if ((src= lex.query_tables->table->find_field_by_name(&m_column))) + if (likely((src= lex.query_tables->table->find_field_by_name(&m_column)))) { if (!(rc= check_column_grant_for_type_ref(thd, table_list, m_column.str, - m_column.length))) + m_column.length, src))) { *def= Column_definition(thd, src, NULL/*No defaults,no constraints*/); def->flags&= (uint) ~NOT_NULL_FLAG; @@ -302,7 +303,7 @@ bool Table_ident::resolve_table_rowtype_ref(THD *thd, LEX_CSTRING tmp= src[0]->field_name; Spvar_definition *def; if ((rc= check_column_grant_for_type_ref(thd, table_list, - tmp.str, tmp.length)) || + tmp.str, tmp.length,src[0])) || (rc= !(src[0]->field_name.str= thd->strmake(tmp.str, tmp.length))) || (rc= !(def= new (thd->mem_root) Spvar_definition(thd, *src)))) break; @@ -486,14 +487,14 @@ bool sp_rcontext::handle_sql_condition(THD *thd, handlers from this context are applicable: try to locate one in the outer scope. */ - if (thd->is_fatal_sub_stmt_error && m_in_sub_stmt) + if (unlikely(thd->is_fatal_sub_stmt_error) && m_in_sub_stmt) DBUG_RETURN(false); Diagnostics_area *da= thd->get_stmt_da(); const sp_handler *found_handler= NULL; const Sql_condition *found_condition= NULL; - if (thd->is_error()) + if (unlikely(thd->is_error())) { found_handler= cur_spi->m_ctx->find_handler(da->get_error_condition_identity()); diff --git a/sql/spatial.cc b/sql/spatial.cc index 255ba3f0647..a8a70d0763b 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -406,7 +406,7 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, key_buf[key_len++]= (uchar)je->s.c_next | 0x20; /* make it lowercase. */ } - if (je->s.error) + if (unlikely(je->s.error)) goto err_return; if (key_len == type_keyname_len && @@ -1956,6 +1956,7 @@ bool Gis_multi_point::init_from_json(json_engine_t *je, bool er_on_3D, if (je->s.error) return TRUE; + if (n_points == 0) { je->s.error= Geometry::GEOJ_EMPTY_COORDINATES; @@ -2231,6 +2232,7 @@ bool Gis_multi_line_string::init_from_json(json_engine_t *je, bool er_on_3D, n_line_strings++; } + if (je->s.error) return TRUE; @@ -2629,8 +2631,10 @@ bool Gis_multi_polygon::init_from_json(json_engine_t *je, bool er_on_3D, n_polygons++; } + if (je->s.error) return TRUE; + if (n_polygons == 0) { je->s.error= Geometry::GEOJ_EMPTY_COORDINATES; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ec195f82069..aec15d38847 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2224,7 +2224,7 @@ bool acl_reload(THD *thd) To avoid deadlocks we should obtain table locks before obtaining acl_cache->lock mutex. */ - if ((result= tables.open_and_lock(thd))) + if (unlikely((result= tables.open_and_lock(thd)))) { DBUG_ASSERT(result <= 0); /* @@ -3470,7 +3470,8 @@ int acl_set_default_role(THD *thd, const char *host, const char *user, user_table.default_role()->store(acl_user->default_rolename.str, acl_user->default_rolename.length, system_charset_info); - if ((error=table->file->ha_update_row(table->record[1],table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) { mysql_mutex_unlock(&acl_cache->lock); @@ -3829,7 +3830,8 @@ static bool update_user_table(THD *thd, const User_table& user_table, new_password_len); - if ((error=table->file->ha_update_row(table->record[1],table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -4121,8 +4123,8 @@ static int replace_user_table(THD *thd, const User_table &user_table, */ if (cmp_record(table, record[1])) { - if ((error= - table->file->ha_update_row(table->record[1],table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) { // This should never happen table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -4133,8 +4135,9 @@ static int replace_user_table(THD *thd, const User_table &user_table, error= 0; } } - else if ((error=table->file->ha_write_row(table->record[0]))) // insert - { // This should never happen + else if (unlikely(error=table->file->ha_write_row(table->record[0]))) + { + // This should never happen if (table->file->is_fatal_error(error, HA_CHECK_DUP)) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -4145,7 +4148,7 @@ static int replace_user_table(THD *thd, const User_table &user_table, error=0; // Privileges granted / revoked end: - if (!error) + if (likely(!error)) { acl_cache->clear(1); // Clear privilege cache if (old_row_exists) @@ -4259,18 +4262,19 @@ static int replace_db_table(TABLE *table, const char *db, /* update old existing row */ if (rights) { - if ((error= table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely((error= table->file->ha_update_row(table->record[1], + table->record[0]))) && error != HA_ERR_RECORD_IS_THE_SAME) goto table_error; /* purecov: deadcode */ } else /* must have been a revoke of all privileges */ { - if ((error= table->file->ha_delete_row(table->record[1]))) + if (unlikely((error= table->file->ha_delete_row(table->record[1])))) goto table_error; /* purecov: deadcode */ } } - else if (rights && (error= table->file->ha_write_row(table->record[0]))) + else if (rights && + (unlikely(error= table->file->ha_write_row(table->record[0])))) { if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) goto table_error; /* purecov: deadcode */ @@ -4347,7 +4351,7 @@ replace_roles_mapping_table(TABLE *table, LEX_CSTRING *user, LEX_CSTRING *host, } if (revoke_grant && !with_admin) { - if ((error= table->file->ha_delete_row(table->record[1]))) + if (unlikely((error= table->file->ha_delete_row(table->record[1])))) { DBUG_PRINT("info", ("error deleting row '%s' '%s' '%s'", host->str, user->str, role->str)); @@ -4358,7 +4362,8 @@ replace_roles_mapping_table(TABLE *table, LEX_CSTRING *user, LEX_CSTRING *host, { table->field[3]->store(!revoke_grant + 1); - if ((error= table->file->ha_update_row(table->record[1], table->record[0]))) + if (unlikely((error= table->file->ha_update_row(table->record[1], + table->record[0])))) { DBUG_PRINT("info", ("error updating row '%s' '%s' '%s'", host->str, user->str, role->str)); @@ -4370,7 +4375,7 @@ replace_roles_mapping_table(TABLE *table, LEX_CSTRING *user, LEX_CSTRING *host, table->field[3]->store(with_admin + 1); - if ((error= table->file->ha_write_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_row(table->record[0])))) { DBUG_PRINT("info", ("error inserting row '%s' '%s' '%s'", host->str, user->str, role->str)); @@ -4501,7 +4506,7 @@ replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, get_grantor(thd, grantor); - if ((error= table->file->ha_index_init(0, 1))) + if (unlikely((error= table->file->ha_index_init(0, 1)))) { table->file->print_error(error, MYF(0)); DBUG_PRINT("info", ("ha_index_init error")); @@ -4538,18 +4543,18 @@ replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, /* update old existing row */ if (!revoke_grant) { - if ((error= table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) goto table_error; /* purecov: inspected */ } else { - if ((error= table->file->ha_delete_row(table->record[1]))) + if (unlikely((error= table->file->ha_delete_row(table->record[1])))) goto table_error; /* purecov: inspected */ } } - else if ((error= table->file->ha_write_row(table->record[0]))) + else if (unlikely((error= table->file->ha_write_row(table->record[0])))) { DBUG_PRINT("info", ("error inserting the row")); if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) @@ -4952,7 +4957,7 @@ static int replace_column_table(GRANT_TABLE *g_t, List_iterator <LEX_COLUMN> iter(columns); class LEX_COLUMN *column; int error= table->file->ha_index_init(0, 1); - if (error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); DBUG_RETURN(-1); @@ -5012,7 +5017,7 @@ static int replace_column_table(GRANT_TABLE *g_t, error=table->file->ha_update_row(table->record[1],table->record[0]); else error=table->file->ha_delete_row(table->record[1]); - if (error && error != HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error) && error != HA_ERR_RECORD_IS_THE_SAME) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ result= -1; /* purecov: inspected */ @@ -5028,7 +5033,7 @@ static int replace_column_table(GRANT_TABLE *g_t, else // new grant { GRANT_COLUMN *grant_column; - if ((error=table->file->ha_write_row(table->record[0]))) + if (unlikely((error=table->file->ha_write_row(table->record[0])))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ result= -1; /* purecov: inspected */ @@ -5083,8 +5088,9 @@ static int replace_column_table(GRANT_TABLE *g_t, if (privileges) { int tmp_error; - if ((tmp_error=table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(tmp_error= + table->file->ha_update_row(table->record[1], + table->record[0])) && tmp_error != HA_ERR_RECORD_IS_THE_SAME) { /* purecov: deadcode */ table->file->print_error(tmp_error,MYF(0)); /* purecov: deadcode */ @@ -5100,7 +5106,8 @@ static int replace_column_table(GRANT_TABLE *g_t, else { int tmp_error; - if ((tmp_error = table->file->ha_delete_row(table->record[1]))) + if (unlikely((tmp_error= + table->file->ha_delete_row(table->record[1])))) { /* purecov: deadcode */ table->file->print_error(tmp_error,MYF(0)); /* purecov: deadcode */ result= -1; /* purecov: deadcode */ @@ -5226,18 +5233,18 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, { if (store_table_rights || store_col_rights) { - if ((error=table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(error=table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) goto table_error; /* purecov: deadcode */ } - else if ((error = table->file->ha_delete_row(table->record[1]))) + else if (unlikely((error = table->file->ha_delete_row(table->record[1])))) goto table_error; /* purecov: deadcode */ } else { error=table->file->ha_write_row(table->record[0]); - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + if (unlikely(table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))) goto table_error; /* purecov: deadcode */ } @@ -5352,18 +5359,18 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, { if (store_proc_rights) { - if ((error=table->file->ha_update_row(table->record[1], - table->record[0])) && - error != HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error=table->file->ha_update_row(table->record[1], + table->record[0])) && + error != HA_ERR_RECORD_IS_THE_SAME) goto table_error; } - else if ((error= table->file->ha_delete_row(table->record[1]))) + else if (unlikely((error= table->file->ha_delete_row(table->record[1])))) goto table_error; } else { error=table->file->ha_write_row(table->record[0]); - if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY)) + if (unlikely(table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))) goto table_error; } @@ -6375,13 +6382,13 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, column->column.ptr(), NULL, NULL, NULL, TRUE, FALSE, &unused_field_idx, FALSE, &dummy); - if (f == (Field*)0) + if (unlikely(f == (Field*)0)) { my_error(ER_BAD_FIELD_ERROR, MYF(0), column->column.c_ptr(), table_list->alias.str); DBUG_RETURN(TRUE); } - if (f == (Field *)-1) + if (unlikely(f == (Field *)-1)) DBUG_RETURN(TRUE); column_priv|= column->rights; } @@ -6464,7 +6471,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, 0, revoke_grant, create_new_users, MY_TEST(thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER)); - if (error) + if (unlikely(error)) { result= TRUE; // Remember error continue; // Add next user @@ -7775,6 +7782,8 @@ err: table_ref table reference where to check the field name name of field to check length length of name + fld use fld object to check invisibility when it is + not 0, not_found_field, view_ref_found DESCRIPTION Check the access rights to a column depending on the type of table @@ -7789,13 +7798,17 @@ err: */ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, - const char *name, size_t length) + const char *name, size_t length, + Field *fld) { GRANT_INFO *grant; const char *db_name; const char *table_name; Security_context *sctx= table_ref->security_ctx ? table_ref->security_ctx : thd->security_ctx; + if (fld && fld != not_found_field && fld != view_ref_found + && fld->invisible >= INVISIBLE_SYSTEM) + return false; if (table_ref->view || table_ref->field_translation) { @@ -7871,6 +7884,9 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, for (; !fields->end_of_fields(); fields->next()) { + if (fields->field() && + fields->field()->invisible >= INVISIBLE_SYSTEM) + continue; LEX_CSTRING *field_name= fields->name(); if (table_name != fields->get_table_name()) @@ -9244,8 +9260,8 @@ static int modify_grant_table(TABLE *table, Field *host_field, system_charset_info); user_field->store(user_to->user.str, user_to->user.length, system_charset_info); - if ((error= table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) table->file->print_error(error, MYF(0)); else @@ -9254,7 +9270,7 @@ static int modify_grant_table(TABLE *table, Field *host_field, else { /* delete */ - if ((error=table->file->ha_delete_row(table->record[0]))) + if (unlikely((error=table->file->ha_delete_row(table->record[0])))) table->file->print_error(error, MYF(0)); } @@ -9286,11 +9302,9 @@ static int handle_roles_mappings_table(TABLE *table, bool drop, DBUG_PRINT("info", ("Rewriting entry in roles_mapping table: %s@%s", user_from->user.str, user_from->host.str)); table->use_all_columns(); - if ((error= table->file->ha_rnd_init(1))) - { - table->file->print_error(error, MYF(0)); + + if (unlikely(table->file->ha_rnd_init_with_error(1))) result= -1; - } else { while((error= table->file->ha_rnd_next(table->record[0])) != @@ -9321,7 +9335,7 @@ static int handle_roles_mappings_table(TABLE *table, bool drop, if (drop) /* drop if requested */ { - if ((error= table->file->ha_delete_row(table->record[0]))) + if (unlikely((error= table->file->ha_delete_row(table->record[0])))) table->file->print_error(error, MYF(0)); } else if (user_to) @@ -9329,8 +9343,8 @@ static int handle_roles_mappings_table(TABLE *table, bool drop, store_record(table, record[1]); role_field->store(user_to->user.str, user_to->user.length, system_charset_info); - if ((error= table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) table->file->print_error(error, MYF(0)); } @@ -9421,13 +9435,14 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, error= table->file->ha_index_read_idx_map(table->record[0], 0, user_key, (key_part_map)3, HA_READ_KEY_EXACT); - if (!error && !*host_str) - { // verify that we got a role or a user, as needed + if (!unlikely(error) && !*host_str) + { + // verify that we got a role or a user, as needed if (static_cast<const User_table&>(grant_table).check_is_role() != user_from->is_role()) error= HA_ERR_KEY_NOT_FOUND; } - if (error) + if (unlikely(error)) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { @@ -9451,11 +9466,8 @@ static int handle_grant_table(THD *thd, const Grant_table_base& grant_table, And their host- and user fields are not consecutive. Thus, we need to do a table scan to find all matching records. */ - if ((error= table->file->ha_rnd_init(1))) - { - table->file->print_error(error, MYF(0)); + if (unlikely(table->file->ha_rnd_init_with_error(1))) result= -1; - } else { #ifdef EXTRA_DEBUG @@ -11385,7 +11397,7 @@ int fill_schema_applicable_roles(THD *thd, TABLE_LIST *tables, COND *cond) int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) { - reg3 int flag; + int flag; DBUG_ENTER("wild_case_compare"); DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr)); while (*wildstr) @@ -12273,6 +12285,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio, const char *client_auth_plugin= ((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin; + DBUG_EXECUTE_IF("auth_disconnect", { vio_close(net->vio); DBUG_RETURN(1); }); DBUG_ASSERT(client_auth_plugin); /* @@ -12645,7 +12658,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, DBUG_PRINT("info", ("Reading user information over SSL layer")); pkt_len= my_net_read(net); - if (pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE) + if (unlikely(pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE)) { DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", pkt_len)); @@ -12734,8 +12747,9 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, Since 4.1 all database names are stored in utf8 The cast is ok as copy_with_error will create a new area for db */ - if (thd->copy_with_error(system_charset_info, (LEX_STRING*) &mpvio->db, - thd->charset(), db, db_len)) + if (unlikely(thd->copy_with_error(system_charset_info, + (LEX_STRING*) &mpvio->db, + thd->charset(), db, db_len))) return packet_error; user_len= copy_and_convert(user_buff, sizeof(user_buff) - 1, @@ -12972,7 +12986,7 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) else pkt_len= my_net_read(&mpvio->auth_info.thd->net); - if (pkt_len == packet_error) + if (unlikely(pkt_len == packet_error)) goto err; mpvio->packets_read++; @@ -12984,7 +12998,7 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf) if (mpvio->packets_read == 1) { pkt_len= parse_client_handshake_packet(mpvio, buf, pkt_len); - if (pkt_len == packet_error) + if (unlikely(pkt_len == packet_error)) goto err; } else diff --git a/sql/sql_acl.h b/sql/sql_acl.h index a608ef0dd77..6da7d4d5db4 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -239,7 +239,7 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *name, size_t length, Security_context *sctx); bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, - const char *name, size_t length); + const char *name, size_t length, Field *fld); bool check_grant_all_columns(THD *thd, ulong want_access, Field_iterator_table_ref *fields); bool check_grant_routine(THD *thd, ulong want_access, diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 82fc1cbfff7..21bb086f013 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2016, MariaDB + Copyright (c) 2011, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -240,7 +240,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, if (thd->locked_tables_list.locked_tables()) { - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) goto end; /* Restore the table in the table list with the new opened table */ table_list->table= pos_in_locked_tables->table; @@ -267,7 +267,7 @@ end: tdc_release_share(table->s); } /* In case of a temporary table there will be no metadata lock. */ - if (error && has_mdl_lock) + if (unlikely(error) && has_mdl_lock) thd->mdl_context.release_transactional_locks(); DBUG_RETURN(error); @@ -430,7 +430,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt, const char *operator_name, thr_lock_type lock_type, - bool open_for_modify, + bool org_open_for_modify, bool repair_table_use_frm, uint extra_open_options, int (*prepare_func)(THD *, TABLE_LIST *, @@ -497,6 +497,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, bool fatal_error=0; bool open_error; bool collect_eis= FALSE; + bool open_for_modify= org_open_for_modify; DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str)); strxmov(table_name, db, ".", table->table_name.str, NullS); @@ -525,7 +526,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, If open_and_lock_tables() failed, close_thread_tables() will close the table and table->table can therefore be invalid. */ - if (open_error) + if (unlikely(open_error)) table->table= NULL; /* @@ -533,7 +534,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, so any errors opening the table are logical errors. In these cases it does not make sense to try to repair. */ - if (open_error && thd->locked_tables_mode) + if (unlikely(open_error) && thd->locked_tables_mode) { result_code= HA_ADMIN_FAILED; goto send_result; @@ -828,7 +829,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, repair_table_use_frm, FALSE); thd->open_options&= ~extra_open_options; - if (!open_error) + if (unlikely(!open_error)) { TABLE *tab= table->table; Field **field_ptr= tab->field; @@ -1164,7 +1165,7 @@ send_result_message: } } /* Error path, a admin command failed. */ - if (thd->transaction_rollback_request) + if (thd->transaction_rollback_request || fatal_error) { /* Unlikely, but transaction rollback was requested by one of storage @@ -1175,7 +1176,9 @@ send_result_message: } else { - if (trans_commit_stmt(thd) || trans_commit_implicit(thd)) + if (trans_commit_stmt(thd) || + (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END) && + trans_commit_implicit(thd))) goto err; } close_thread_tables(thd); @@ -1209,7 +1212,8 @@ send_result_message: err: /* Make sure this table instance is not reused after the failure. */ trans_rollback_stmt(thd); - trans_rollback(thd); + if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END)) + trans_rollback(thd); if (table && table->table) { table->table->m_needs_reopen= true; @@ -1217,7 +1221,9 @@ err: } close_thread_tables(thd); // Shouldn't be needed thd->mdl_context.release_transactional_locks(); +#ifdef WITH_PARTITION_STORAGE_ENGINE err2: +#endif thd->resume_subsequent_commits(suspended_wfc); DBUG_RETURN(TRUE); } diff --git a/sql/sql_alloc.h b/sql/sql_alloc.h index c3bee260817..153b0401e29 100644 --- a/sql/sql_alloc.h +++ b/sql/sql_alloc.h @@ -39,7 +39,7 @@ public: { return alloc_root(mem_root, size); } static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); } static void operator delete(void *, MEM_ROOT *){} - static void operator delete[](void *ptr, MEM_ROOT *mem_root) + static void operator delete[](void *, MEM_ROOT *) { /* never called */ } static void operator delete[](void *ptr, size_t size) { TRASH_FREE(ptr, size); } #ifdef HAVE_valgrind diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 77e0c9d5298..bf78bd12192 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -54,12 +54,16 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) bool Alter_info::set_requested_algorithm(const LEX_CSTRING *str) { // To avoid adding new keywords to the grammar, we match strings here. - if (!my_strcasecmp(system_charset_info, str->str, "INPLACE")) + if (lex_string_eq(str, STRING_WITH_LEN("INPLACE"))) requested_algorithm= ALTER_TABLE_ALGORITHM_INPLACE; - else if (!my_strcasecmp(system_charset_info, str->str, "COPY")) + else if (lex_string_eq(str, STRING_WITH_LEN("COPY"))) requested_algorithm= ALTER_TABLE_ALGORITHM_COPY; - else if (!my_strcasecmp(system_charset_info, str->str, "DEFAULT")) + else if (lex_string_eq(str, STRING_WITH_LEN("DEFAULT"))) requested_algorithm= ALTER_TABLE_ALGORITHM_DEFAULT; + else if (lex_string_eq(str, STRING_WITH_LEN("NOCOPY"))) + requested_algorithm= ALTER_TABLE_ALGORITHM_NOCOPY; + else if (lex_string_eq(str, STRING_WITH_LEN("INSTANT"))) + requested_algorithm= ALTER_TABLE_ALGORITHM_INSTANT; else return true; return false; @@ -69,19 +73,141 @@ bool Alter_info::set_requested_algorithm(const LEX_CSTRING *str) bool Alter_info::set_requested_lock(const LEX_CSTRING *str) { // To avoid adding new keywords to the grammar, we match strings here. - if (!my_strcasecmp(system_charset_info, str->str, "NONE")) + if (lex_string_eq(str, STRING_WITH_LEN("NONE"))) requested_lock= ALTER_TABLE_LOCK_NONE; - else if (!my_strcasecmp(system_charset_info, str->str, "SHARED")) + else if (lex_string_eq(str, STRING_WITH_LEN("SHARED"))) requested_lock= ALTER_TABLE_LOCK_SHARED; - else if (!my_strcasecmp(system_charset_info, str->str, "EXCLUSIVE")) + else if (lex_string_eq(str, STRING_WITH_LEN("EXCLUSIVE"))) requested_lock= ALTER_TABLE_LOCK_EXCLUSIVE; - else if (!my_strcasecmp(system_charset_info, str->str, "DEFAULT")) + else if (lex_string_eq(str, STRING_WITH_LEN("DEFAULT"))) requested_lock= ALTER_TABLE_LOCK_DEFAULT; else return true; return false; } +const char* Alter_info::algorithm() const +{ + switch (requested_algorithm) { + case ALTER_TABLE_ALGORITHM_INPLACE: + return "ALGORITHM=INPLACE"; + case ALTER_TABLE_ALGORITHM_COPY: + return "ALGORITHM=COPY"; + case ALTER_TABLE_ALGORITHM_DEFAULT: + return "ALGORITHM=DEFAULT"; + case ALTER_TABLE_ALGORITHM_NOCOPY: + return "ALGORITHM=NOCOPY"; + case ALTER_TABLE_ALGORITHM_INSTANT: + return "ALGORITHM=INSTANT"; + } + + return NULL; /* purecov: begin deadcode */ +} + +const char* Alter_info::lock() const +{ + switch (requested_lock) { + case ALTER_TABLE_LOCK_SHARED: + return "LOCK=SHARED"; + case ALTER_TABLE_LOCK_NONE: + return "LOCK=NONE"; + case ALTER_TABLE_LOCK_DEFAULT: + return "LOCK=DEFAULT"; + case ALTER_TABLE_LOCK_EXCLUSIVE: + return "LOCK=EXCLUSIVE"; + } + return NULL; /* purecov: begin deadcode */ +} + + +bool Alter_info::supports_algorithm(THD *thd, enum_alter_inplace_result result, + const Alter_inplace_info *ha_alter_info) +{ + if (requested_algorithm == Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT) + requested_algorithm = (Alter_info::enum_alter_table_algorithm) thd->variables.alter_algorithm; + + switch (result) { + case HA_ALTER_INPLACE_EXCLUSIVE_LOCK: + case HA_ALTER_INPLACE_SHARED_LOCK: + case HA_ALTER_INPLACE_NO_LOCK: + case HA_ALTER_INPLACE_INSTANT: + return false; + case HA_ALTER_INPLACE_COPY_NO_LOCK: + case HA_ALTER_INPLACE_COPY_LOCK: + if (requested_algorithm >= Alter_info::ALTER_TABLE_ALGORITHM_NOCOPY) + { + ha_alter_info->report_unsupported_error(algorithm(), + "ALGORITHM=INPLACE"); + return true; + } + return false; + case HA_ALTER_INPLACE_NOCOPY_NO_LOCK: + case HA_ALTER_INPLACE_NOCOPY_LOCK: + if (requested_algorithm == Alter_info::ALTER_TABLE_ALGORITHM_INSTANT) + { + ha_alter_info->report_unsupported_error("ALGORITHM=INSTANT", + "ALGORITHM=NOCOPY"); + return true; + } + return false; + case HA_ALTER_INPLACE_NOT_SUPPORTED: + if (requested_algorithm >= Alter_info::ALTER_TABLE_ALGORITHM_INPLACE) + { + ha_alter_info->report_unsupported_error(algorithm(), + "ALGORITHM=COPY"); + return true; + } + return false; + case HA_ALTER_ERROR: + return true; + } + /* purecov: begin deadcode */ + DBUG_ASSERT(0); + return false; +} + + +bool Alter_info::supports_lock(THD *thd, enum_alter_inplace_result result, + const Alter_inplace_info *ha_alter_info) +{ + switch (result) { + case HA_ALTER_INPLACE_EXCLUSIVE_LOCK: + // If SHARED lock and no particular algorithm was requested, use COPY. + if (requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED && + requested_algorithm == Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT && + thd->variables.alter_algorithm == + Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT) + return false; + + if (requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED || + requested_lock == Alter_info::ALTER_TABLE_LOCK_NONE) + { + ha_alter_info->report_unsupported_error(lock(), "LOCK=EXCLUSIVE"); + return true; + } + return false; + case HA_ALTER_INPLACE_NO_LOCK: + case HA_ALTER_INPLACE_INSTANT: + case HA_ALTER_INPLACE_COPY_NO_LOCK: + case HA_ALTER_INPLACE_NOCOPY_NO_LOCK: + return false; + case HA_ALTER_INPLACE_COPY_LOCK: + case HA_ALTER_INPLACE_NOCOPY_LOCK: + case HA_ALTER_INPLACE_NOT_SUPPORTED: + case HA_ALTER_INPLACE_SHARED_LOCK: + if (requested_lock == Alter_info::ALTER_TABLE_LOCK_NONE) + { + ha_alter_info->report_unsupported_error("LOCK=NONE", "LOCK=SHARED"); + return true; + } + return false; + case HA_ALTER_ERROR: + return true; + } + /* purecov: begin deadcode */ + DBUG_ASSERT(0); + return false; +} Alter_table_ctx::Alter_table_ctx() : datetime_field(NULL), error_if_not_empty(false), @@ -219,8 +345,11 @@ bool Sql_cmd_alter_table::execute(THD *thd) DBUG_ENTER("Sql_cmd_alter_table::execute"); - if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */ + if (unlikely(thd->is_fatal_error)) + { + /* out of memory creating a copy of alter_info */ DBUG_RETURN(TRUE); + } /* We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well as for RENAME TO, as being done by SQLCOM_RENAME_TABLE @@ -273,8 +402,8 @@ bool Sql_cmd_alter_table::execute(THD *thd) - For temporary MERGE tables we do not track if their child tables are base or temporary. As result we can't guarantee that privilege check - which was done in presence of temporary child will stay relevant later - as this temporary table might be removed. + which was done in presence of temporary child will stay relevant + later as this temporary table might be removed. If SELECT_ACL | UPDATE_ACL | DELETE_ACL privileges were not checked for the underlying *base* tables, it would create a security breach as in @@ -314,6 +443,9 @@ bool Sql_cmd_alter_table::execute(THD *thd) create_info.data_file_name= create_info.index_file_name= NULL; thd->prepare_logs_for_admin_command(); +#ifdef WITH_PARTITION_STORAGE_ENGINE + thd->work_part_info= 0; +#endif #ifdef WITH_WSREP if ((!thd->is_current_stmt_binlog_format_row() || diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 85a7b993e12..268dbc43abd 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -47,14 +47,24 @@ public: */ enum enum_alter_table_algorithm { - // In-place if supported, copy otherwise. +/* + Use thd->variables.alter_algorithm for alter method. If this is also + default then use the fastest possible ALTER TABLE method + (INSTANT, NOCOPY, INPLACE, COPY) +*/ ALTER_TABLE_ALGORITHM_DEFAULT, + // Copy if supported, error otherwise. + ALTER_TABLE_ALGORITHM_COPY, + // In-place if supported, error otherwise. ALTER_TABLE_ALGORITHM_INPLACE, - // Copy if supported, error otherwise. - ALTER_TABLE_ALGORITHM_COPY + // No Copy will refuse any operation which does rebuild. + ALTER_TABLE_ALGORITHM_NOCOPY, + + // Instant should allow any operation that changes metadata only. + ALTER_TABLE_ALGORITHM_INSTANT }; @@ -67,7 +77,7 @@ public: // Maximum supported level of concurency for the given operation. ALTER_TABLE_LOCK_DEFAULT, - // Allow concurrent reads & writes. If not supported, give erorr. + // Allow concurrent reads & writes. If not supported, give error. ALTER_TABLE_LOCK_NONE, // Allow concurrent reads only. If not supported, give error. @@ -174,6 +184,45 @@ public: bool set_requested_lock(const LEX_CSTRING *str); + /** + Returns the algorithm value in the format "algorithm=value" + */ + const char* algorithm() const; + + /** + Returns the lock value in the format "lock=value" + */ + const char* lock() const; + + /** + Check whether the given result can be supported + with the specified user alter algorithm. + + @param thd Thread handle + @param result Operation supported for inplace alter + @param ha_alter_info Structure describing changes to be done + by ALTER TABLE and holding data during + in-place alter + @retval false Supported operation + @retval true Not supported value + */ + bool supports_algorithm(THD *thd, enum_alter_inplace_result result, + const Alter_inplace_info *ha_alter_info); + + /** + Check whether the given result can be supported + with the specified user lock type. + + @param result Operation supported for inplace alter + @param ha_alter_info Structure describing changes to be done + by ALTER TABLE and holding data during + in-place alter + @retval false Supported lock type + @retval true Not supported value + */ + bool supports_lock(THD *thd, enum_alter_inplace_result result, + const Alter_inplace_info *ha_alter_info); + private: Alter_info &operator=(const Alter_info &rhs); // not implemented Alter_info(const Alter_info &rhs); // not implemented diff --git a/sql/sql_array.h b/sql/sql_array.h index cad7b0e1c48..0e5246b7e2a 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -221,7 +221,7 @@ public: bool resize(size_t new_size, Elem default_val) { size_t old_size= elements(); - if (allocate_dynamic(&array, (uint)new_size)) + if (unlikely(allocate_dynamic(&array, (uint)new_size))) return true; if (new_size > old_size) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5ce6a6b001c..64427af6319 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -199,8 +199,8 @@ uint get_table_def_key(const TABLE_LIST *table_list, const char **key) from key used by MDL subsystem. */ DBUG_ASSERT(!strcmp(table_list->get_db_name(), - table_list->mdl_request.key.db_name()) && - !strcmp(table_list->get_table_name(), + table_list->mdl_request.key.db_name())); + DBUG_ASSERT(!strcmp(table_list->get_table_name(), table_list->mdl_request.key.name())); *key= (const char*)table_list->mdl_request.key.ptr() + 1; @@ -484,7 +484,7 @@ err_with_reopen: old locks. This should always succeed (unless some external process has removed the tables) */ - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) result= true; /* Since downgrade_lock() won't do anything with shared @@ -951,7 +951,8 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, @param thd thread handle @param table table which should be checked @param table_list list of tables - @param check_alias whether to check tables' aliases + @param check_flag whether to check tables' aliases + Currently this is only used by INSERT NOTE: to exclude derived tables from check we use following mechanism: a) during derived table processing set THD::derived_tables_processing @@ -980,9 +981,9 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, static TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias) + uint check_flag) { - TABLE_LIST *res; + TABLE_LIST *res= 0; LEX_CSTRING *d_name, *t_name, *t_alias; DBUG_ENTER("find_dup_table"); DBUG_PRINT("enter", ("table alias: %s", table->alias.str)); @@ -1015,17 +1016,15 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, retry: DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str)); - for (TABLE_LIST *tl= table_list;;) + for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0) { - if (tl && - tl->select_lex && tl->select_lex->master_unit() && + if (tl->select_lex && tl->select_lex->master_unit() && tl->select_lex->master_unit()->executed) { /* There is no sense to check tables of already executed parts of the query */ - tl= tl->next_global; continue; } /* @@ -1034,21 +1033,29 @@ retry: */ if (! (res= find_table_in_global_list(tl, d_name, t_name))) break; + tl= res; // We can continue search after this table /* Skip if same underlying table. */ if (res->table && (res->table == table->table)) - goto next; + continue; + + if (check_flag & CHECK_DUP_FOR_CREATE) + DBUG_RETURN(res); /* Skip if table alias does not match. */ - if (check_alias) + if (check_flag & CHECK_DUP_ALLOW_DIFFERENT_ALIAS) { if (my_strcasecmp(table_alias_charset, t_alias->str, res->alias.str)) - goto next; + continue; } /* - Skip if marked to be excluded (could be a derived table) or if - entry is a prelocking placeholder. + If table is not excluded (could be a derived table) and table is not + a prelocking placeholder then we found either a duplicate entry + or a table that is part of a derived table (handled below). + Examples are: + INSERT INTO t1 SELECT * FROM t1; + INSERT INTO t1 SELECT * FROM view_containing_t1; */ if (res->select_lex && !res->select_lex->exclude_from_table_unique_test && @@ -1060,14 +1067,17 @@ retry: processed in derived table or top select of multi-update/multi-delete (exclude_from_table_unique_test) or prelocking placeholder. */ -next: - tl= res->next_global; DBUG_PRINT("info", ("found same copy of table or table which we should skip")); } if (res && res->belong_to_derived) { - /* Try to fix */ + /* + We come here for queries of type: + INSERT INTO t1 (SELECT tmp.a FROM (select * FROM t1) as tmp); + + Try to fix by materializing the derived table + */ TABLE_LIST *derived= res->belong_to_derived; if (derived->is_merged_derived() && !derived->derived->is_excluded()) { @@ -1099,7 +1109,7 @@ next: TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias) + uint check_flag) { TABLE_LIST *dup; @@ -1131,12 +1141,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, if (!tmp_parent) break; - if ((dup= find_dup_table(thd, child, child->next_global, check_alias))) + if ((dup= find_dup_table(thd, child, child->next_global, check_flag))) break; } } else - dup= find_dup_table(thd, table, table_list, check_alias); + dup= find_dup_table(thd, table, table_list, check_flag); return dup; } @@ -1471,15 +1481,15 @@ open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx, return FALSE; } +#ifdef WITH_PARTITION_STORAGE_ENGINE /* Set all [named] partitions as used. */ static int set_partitions_as_used(TABLE_LIST *tl, TABLE *t) { -#ifdef WITH_PARTITION_STORAGE_ENGINE if (t->part_info) return t->file->change_partitions_to_open(tl->partition_names); -#endif return 0; } +#endif /** @@ -1525,7 +1535,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) MDL_ticket *mdl_ticket; TABLE_SHARE *share; uint gts_flags; +#ifdef WITH_PARTITION_STORAGE_ENGINE int part_names_error=0; +#endif DBUG_ENTER("open_table"); /* @@ -1623,7 +1635,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) table= best_table; table->query_id= thd->query_id; DBUG_PRINT("info",("Using locked table")); +#ifdef WITH_PARTITION_STORAGE_ENGINE part_names_error= set_partitions_as_used(table_list, table); +#endif goto reset; } /* @@ -1782,7 +1796,7 @@ retry_share: share= tdc_acquire_share(thd, table_list, gts_flags, &table); - if (!share) + if (unlikely(!share)) { /* Hide "Table doesn't exist" errors if the table belongs to a view. @@ -1908,7 +1922,9 @@ retry_share: { DBUG_ASSERT(table->file != NULL); MYSQL_REBIND_TABLE(table->file); +#ifdef WITH_PARTITION_STORAGE_ENGINE part_names_error= set_partitions_as_used(table_list, table); +#endif } else { @@ -1924,7 +1940,7 @@ retry_share: thd->open_options, table, FALSE, IF_PARTITIONING(table_list->partition_names,0)); - if (error) + if (unlikely(error)) { my_free(table); @@ -1969,7 +1985,7 @@ retry_share: table_list->table= table; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (table->part_info) + if (unlikely(table->part_info)) { /* Partitions specified were incorrect.*/ if (part_names_error) @@ -2054,7 +2070,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, { TABLE *tab= find_locked_table(thd->open_tables, db, table_name); - if (!tab) + if (unlikely(!tab)) { if (!no_error) my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_name); @@ -2067,8 +2083,8 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, cases don't take a global IX lock in order to be compatible with global read lock. */ - if (!thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", - MDL_INTENTION_EXCLUSIVE)) + if (unlikely(!thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", + MDL_INTENTION_EXCLUSIVE))) { if (!no_error) my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); @@ -2080,7 +2096,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, (tab= find_locked_table(tab->next, db, table_name))) continue; - if (!tab && !no_error) + if (unlikely(!tab && !no_error)) my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name); return tab; @@ -2298,7 +2314,8 @@ void Locked_tables_list::unlink_from_list(THD *thd, If mode is not LTM_LOCK_TABLES, we needn't do anything. Moreover, outside this mode pos_in_locked_tables value is not trustworthy. */ - if (thd->locked_tables_mode != LTM_LOCK_TABLES) + if (thd->locked_tables_mode != LTM_LOCK_TABLES && + thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES) return; /* @@ -2402,7 +2419,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count) */ bool -Locked_tables_list::reopen_tables(THD *thd) +Locked_tables_list::reopen_tables(THD *thd, bool need_reopen) { Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); uint reopen_count= 0; @@ -2413,8 +2430,20 @@ Locked_tables_list::reopen_tables(THD *thd) for (TABLE_LIST *table_list= m_locked_tables; table_list; table_list= table_list->next_global) { - if (table_list->table) /* The table was not closed */ - continue; + if (need_reopen) + { + if (!table_list->table || !table_list->table->needs_reopen()) + continue; + /* no need to remove the table from the TDC here, thus (TABLE*)1 */ + close_all_tables_for_name(thd, table_list->table->s, + HA_EXTRA_NOT_USED, (TABLE*)1); + DBUG_ASSERT(table_list->table == NULL); + } + else + { + if (table_list->table) /* The table was not closed */ + continue; + } /* Links into thd->open_tables upon success */ if (open_table(thd, table_list, &ot_ctx)) @@ -3513,7 +3542,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, error= open_table(thd, tables, ot_ctx); } - if (error) + if (unlikely(error)) { if (! ot_ctx->can_recover_from_failed_open() && safe_to_ignore_table) { @@ -3593,7 +3622,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, if (need_prelocking && ! lex->requires_prelocking()) lex->mark_as_requiring_prelocking(save_query_tables_last); - if (error) + if (unlikely(error)) goto end; } @@ -3603,7 +3632,7 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables, /* Check and update metadata version of a base table. */ error= check_and_update_table_version(thd, tables, tables->table->s); - if (error) + if (unlikely(error)) goto end; /* After opening a MERGE table add the children to the query list of @@ -3663,7 +3692,7 @@ process_view_routines: if (need_prelocking && ! lex->requires_prelocking()) lex->mark_as_requiring_prelocking(save_query_tables_last); - if (error) + if (unlikely(error)) goto end; } @@ -4032,7 +4061,7 @@ restart: flags, prelocking_strategy, has_prelocking_list, &ot_ctx); - if (error) + if (unlikely(error)) { if (ot_ctx.can_recover_from_failed_open()) { @@ -4114,7 +4143,7 @@ restart: if (need_prelocking && ! *start) *start= thd->lex->query_tables; - if (error) + if (unlikely(error)) { if (ot_ctx.can_recover_from_failed_open()) { @@ -4210,7 +4239,7 @@ error: THD_STAGE_INFO(thd, stage_after_opening_tables); thd_proc_info(thd, 0); - if (error && *table_to_open) + if (unlikely(error) && *table_to_open) { (*table_to_open)->table= NULL; } @@ -4388,7 +4417,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, arena= thd->activate_stmt_arena_if_needed(&backup); table->file->get_parent_foreign_key_list(thd, &fk_list); - if (thd->is_error()) + if (unlikely(thd->is_error())) { if (arena) thd->restore_active_arena(arena, &backup); @@ -4439,7 +4468,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, table->internal_tables); if (arena) thd->restore_active_arena(arena, &backup); - if (error) + if (unlikely(error)) { *need_prelocking= TRUE; return TRUE; @@ -4680,7 +4709,7 @@ static bool check_lock_and_start_stmt(THD *thd, table_list->table->alias.c_ptr()); DBUG_RETURN(1); } - if ((error= table_list->table->file->start_stmt(thd, lock_type))) + if (unlikely((error= table_list->table->file->start_stmt(thd, lock_type)))) { table_list->table->file->print_error(error, MYF(0)); DBUG_RETURN(1); @@ -4820,7 +4849,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, break; } - if (!error) + if (likely(!error)) { /* We can't have a view or some special "open_strategy" in this function @@ -5864,7 +5893,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ if (check_privileges && - check_column_grant_in_table_ref(thd, *actual_table, name, length)) + check_column_grant_in_table_ref(thd, *actual_table, name, length, fld)) fld= WRONG_GRANT; else #endif @@ -6041,7 +6070,7 @@ find_field_in_tables(THD *thd, Item_ident *item, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if there are sufficient access rights to the found field. */ if (found && check_privileges && - check_column_grant_in_table_ref(thd, table_ref, name, length)) + check_column_grant_in_table_ref(thd, table_ref, name, length, found)) found= WRONG_GRANT; #endif } @@ -6162,7 +6191,7 @@ find_field_in_tables(THD *thd, Item_ident *item, if (db) return cur_field; - if (found) + if (unlikely(found)) { if (report_error == REPORT_ALL_ERRORS || report_error == IGNORE_EXCEPT_NON_UNIQUE) @@ -6174,7 +6203,7 @@ find_field_in_tables(THD *thd, Item_ident *item, } } - if (found) + if (likely(found)) return found; /* @@ -6293,7 +6322,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, (if this field created from expression argument of group_concat()), => we have to check presence of name before compare */ - if (!item_field->name.str) + if (unlikely(!item_field->name.str)) continue; if (table_name) @@ -6411,24 +6440,27 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter, } } } - if (!found) + + if (likely(found)) + return found; + + if (unlikely(found_unaliased_non_uniq)) { - if (found_unaliased_non_uniq) - { - if (report_error != IGNORE_ERRORS) - my_error(ER_NON_UNIQ_ERROR, MYF(0), - find->full_name(), current_thd->where); - return (Item **) 0; - } - if (found_unaliased) - { - found= found_unaliased; - *counter= unaliased_counter; - *resolution= RESOLVED_BEHIND_ALIAS; - } + if (report_error != IGNORE_ERRORS) + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); + return (Item **) 0; + } + if (found_unaliased) + { + found= found_unaliased; + *counter= unaliased_counter; + *resolution= RESOLVED_BEHIND_ALIAS; } + if (found) return found; + if (report_error != REPORT_EXCEPT_NOT_FOUND) { if (report_error == REPORT_ALL_ERRORS) @@ -6548,7 +6580,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, Query_arena *arena, backup; bool result= TRUE; bool first_outer_loop= TRUE; - Field *field_1, *field_2; + Field *field_1; field_visibility_t field_1_invisible, field_2_invisible; /* Leaf table references to which new natural join columns are added @@ -6572,6 +6604,8 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, { bool found= FALSE; const LEX_CSTRING *field_name_1; + Field *field_2= 0; + /* true if field_name_1 is a member of using_fields */ bool is_using_column_1; if (!(nj_col_1= it_1.get_or_create_column_ref(thd, leaf_1))) @@ -7160,7 +7194,7 @@ static bool setup_natural_join_row_types(THD *thd, int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, - uint wild_num) + uint wild_num, uint *hidden_bit_fields) { if (!wild_num) return(0); @@ -7200,7 +7234,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, else if (insert_fields(thd, ((Item_field*) item)->context, ((Item_field*) item)->db_name, ((Item_field*) item)->table_name, &it, - any_privileges)) + any_privileges, hidden_bit_fields)) { if (arena) thd->restore_active_arena(arena, &backup); @@ -7251,7 +7285,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, List<Item> *sum_func_list, List<Item> *pre_fix, bool allow_sum_func) { - reg2 Item *item; + Item *item; enum_column_usage saved_column_usage= thd->column_usage; nesting_map save_allow_sum_func= thd->lex->allow_sum_func; List_iterator<Item> it(fields); @@ -7665,7 +7699,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, List_iterator<Item> *it, - bool any_privileges) + bool any_privileges, uint *hidden_bit_fields) { Field_iterator_table_ref field_iterator; bool found; @@ -7793,6 +7827,9 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, else it->after(item); /* Add 'item' to the SELECT list. */ + if (item->type() == Item::FIELD_ITEM && item->field_type() == MYSQL_TYPE_BIT) + (*hidden_bit_fields)++; + #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Set privilege information for the fields of newly created views. @@ -8169,7 +8206,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, if (rfield->stored_in_db()) { - if (value->save_in_field(rfield, 0) < 0 && !ignore_errors) + if (unlikely(value->save_in_field(rfield, 0) < 0) && !ignore_errors) { my_message(ER_UNKNOWN_ERROR, ER_THD(thd, ER_UNKNOWN_ERROR), MYF(0)); goto err; @@ -8424,7 +8461,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, /* Ensure that all fields are from the same table */ DBUG_ASSERT(field->table == table); - if (field->invisible) + if (unlikely(field->invisible)) { all_fields_have_values= false; continue; @@ -8436,7 +8473,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, if (field->field_index == autoinc_index) table->auto_increment_field_not_null= TRUE; - if (field->vcol_info || (vers_sys_field && !ignore_errors)) + if (unlikely(field->vcol_info) || (vers_sys_field && !ignore_errors)) { Item::Type type= value->type(); if (type != Item::DEFAULT_VALUE_ITEM && @@ -8621,6 +8658,19 @@ int setup_ftfuncs(SELECT_LEX *select_lex) } +void cleanup_ftfuncs(SELECT_LEX *select_lex) +{ + List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)), + lj(*(select_lex->ftfunc_list)); + Item_func_match *ftf; + + while ((ftf=li++)) + { + ftf->cleanup(); + } +} + + int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) { if (select_lex->ftfunc_list->elements) diff --git a/sql/sql_base.h b/sql/sql_base.h index a6a85d47dc9..01892c0b938 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -1,4 +1,6 @@ /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 2018, MariaDB + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -59,6 +61,10 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE, IGNORE_EXCEPT_NON_UNIQUE}; +/* Flag bits for unique_table() */ +#define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1 +#define CHECK_DUP_FOR_CREATE 2 + uint get_table_def_key(const TABLE_LIST *table_list, const char **key); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update, uint lock_flags); @@ -153,11 +159,12 @@ bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, enum trg_event_type event); bool insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, const char *table_name, - List_iterator<Item> *it, bool any_privileges); + List_iterator<Item> *it, bool any_privileges, + uint *hidden_bit_fields); void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables, bool full_table_list, TABLE_LIST *boundary); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, - List<Item> *sum_func_list, uint wild_num); + List<Item> *sum_func_list, uint wild_num, uint * hidden_bit_fields); bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, List<Item> &item, enum_column_usage column_usage, List<Item> *sum_func_list, List<Item> *pre_fix, @@ -214,6 +221,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, COND **conds); void wrap_ident(THD *thd, Item **conds); int setup_ftfuncs(SELECT_LEX* select); +void cleanup_ftfuncs(SELECT_LEX *select_lex); int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); bool lock_table_names(THD *thd, const DDL_options_st &options, TABLE_LIST *table_list, @@ -263,7 +271,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags); int decide_logging_format(THD *thd, TABLE_LIST *tables); void close_thread_table(THD *thd, TABLE **table_ptr); TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list, - bool check_alias); + uint check_flag); bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b); class Open_tables_backup; diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 5a2caf89fe2..705a8d169e1 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -141,16 +141,16 @@ public: }; }; -/* An iterator to quickly walk over bits in unlonglong bitmap. */ +/* An iterator to quickly walk over bits in ulonglong bitmap. */ class Table_map_iterator { ulonglong bmp; uint no; public: Table_map_iterator(ulonglong t) : bmp(t), no(0) {} - int next_bit() + uint next_bit() { - static const char last_bit[16]= {32, 0, 1, 0, + static const uchar last_bit[16]= {32, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; @@ -162,10 +162,10 @@ public: if (!bmp) return BITMAP_END; } - bmp &= ~(1LL << bit); + bmp &= ~(1ULL << bit); return no + bit; } - int operator++(int) { return next_bit(); } + uint operator++(int) { return next_bit(); } enum { BITMAP_END= 64 }; }; @@ -201,7 +201,10 @@ public: bool is_subset(const Bitmap<64>& map2) const { return !(map & ~map2.map); } bool is_overlapping(const Bitmap<64>& map2) const { return (map & map2.map)!= 0; } bool operator==(const Bitmap<64>& map2) const { return map == map2.map; } - char *print(char *buf) const { longlong2str(map,buf,16); return buf; } + char *print(char *buf) const { + longlong2str(longlong(map), buf, 16); + return buf; + } ulonglong to_ulonglong() const { return map; } class Iterator : public Table_map_iterator { diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index c8f18556d50..aa4c77d0939 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -329,6 +329,9 @@ TODO list: */ #include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */ +#if defined(DBUG_OFF) && defined(HAVE_MADVISE) +#include <sys/mman.h> +#endif #include "sql_priv.h" #include "sql_basic_types.h" #include "sql_cache.h" @@ -1049,7 +1052,7 @@ void query_cache_insert(void *thd_arg, const char *packet, size_t length, called for this thread. */ - if (!thd) + if (unlikely(!thd)) return; query_cache.insert(thd, &thd->query_cache_tls, @@ -2591,7 +2594,7 @@ size_t Query_cache::init_cache() { size_t mem_bin_count, num, step; size_t mem_bin_size, prev_size, inc; - size_t additional_data_size, max_mem_bin_size, approx_additional_data_size; + size_t max_mem_bin_size, approx_additional_data_size; int align; DBUG_ENTER("Query_cache::init_cache"); @@ -2656,6 +2659,13 @@ size_t Query_cache::init_cache() if (!(cache= (uchar *) my_malloc_lock(query_cache_size+additional_data_size, MYF(0)))) goto err; +#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DONTDUMP) + if (madvise(cache, query_cache_size+additional_data_size, MADV_DONTDUMP)) + { + DBUG_PRINT("warning", ("coudn't mark query cache memory as MADV_DONTDUMP: %s", + strerror(errno))); + } +#endif DBUG_PRINT("qcache", ("cache length %zu, min unit %zu, %zu bins", query_cache_size, min_allocation_unit, mem_bin_num)); @@ -2818,6 +2828,13 @@ void Query_cache::free_cache() } while (block != queries_blocks); } +#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DODUMP) + if (madvise(cache, query_cache_size+additional_data_size, MADV_DODUMP)) + { + DBUG_PRINT("warning", ("coudn't mark query cache memory as MADV_DODUMP: %s", + strerror(errno))); + } +#endif my_free(cache); make_disabled(); my_hash_free(&queries); diff --git a/sql/sql_cache.h b/sql/sql_cache.h index eb046b4d167..0ed45a9ed81 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -337,6 +337,7 @@ protected: till the end of a flush operation. */ mysql_mutex_t structure_guard_mutex; + size_t additional_data_size; uchar *cache; // cache memory Query_cache_block *first_block; // physical location block list Query_cache_block *queries_blocks; // query list (LIFO) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7b7d34c6bc0..d2e4f66dd59 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -336,24 +336,9 @@ ulong get_max_connections(void) extern "C" int mysql_tmpfile(const char *prefix) { char filename[FN_REFLEN]; - File fd = create_temp_file(filename, mysql_tmpdir, prefix, -#ifdef __WIN__ - O_BINARY | O_TRUNC | O_SEQUENTIAL | - O_SHORT_LIVED | -#endif /* __WIN__ */ - O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY, - MYF(MY_WME)); - if (fd >= 0) { -#ifndef __WIN__ - /* - This can be removed once the following bug is fixed: - Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option - (file not removed) (Unix) - */ - unlink(filename); -#endif /* !__WIN__ */ - } - + File fd= create_temp_file(filename, mysql_tmpdir, prefix, + O_BINARY | O_SEQUENTIAL, + MYF(MY_WME | MY_TEMPORARY)); return fd; } @@ -770,6 +755,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock) THD *old_THR_THD= current_thd; set_current_thd(this); status_var.local_memory_used= sizeof(THD); + status_var.max_local_memory_used= status_var.local_memory_used; status_var.global_memory_used= 0; variables.pseudo_thread_id= thread_id; variables.max_mem_used= global_system_variables.max_mem_used; @@ -819,7 +805,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock) statement_id_counter= 0UL; // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; - stmt_lex= 0; start_utime= utime_after_query= 0; system_time.start.val= system_time.sec= system_time.sec_part= 0; utime_after_lock= 0L; @@ -880,7 +865,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock) *scramble= '\0'; #ifdef WITH_WSREP - mysql_mutex_init(key_LOCK_wsrep_thd, &LOCK_wsrep_thd, MY_MUTEX_INIT_FAST); wsrep_ws_handle.trx_id = WSREP_UNDEFINED_TRX_ID; wsrep_ws_handle.opaque = NULL; wsrep_retry_counter = 0; @@ -1173,8 +1157,8 @@ Sql_condition* THD::raise_condition(uint sql_errno, require memory allocation and therefore might fail. Non fatal out of memory errors can occur if raised by SIGNAL/RESIGNAL statement. */ - if (!(is_fatal_error && (sql_errno == EE_OUTOFMEMORY || - sql_errno == ER_OUTOFMEMORY))) + if (likely(!(is_fatal_error && (sql_errno == EE_OUTOFMEMORY || + sql_errno == ER_OUTOFMEMORY)))) { cond= da->push_warning(this, sql_errno, sqlstate, level, ucid, msg); } @@ -1317,6 +1301,7 @@ void THD::init(bool skip_lock) reset_current_stmt_binlog_format_row(); reset_binlog_local_stmt_filter(); set_status_var_init(); + status_var.max_local_memory_used= status_var.local_memory_used; bzero((char *) &org_status_var, sizeof(org_status_var)); status_in_global= 0; start_bytes_received= 0; @@ -1716,9 +1701,6 @@ THD::~THD() mysql_mutex_unlock(&LOCK_thd_kill); #ifdef WITH_WSREP - mysql_mutex_lock(&LOCK_wsrep_thd); - mysql_mutex_unlock(&LOCK_wsrep_thd); - mysql_mutex_destroy(&LOCK_wsrep_thd); delete wsrep_rgi; #endif if (!free_connection_done) @@ -2376,12 +2358,12 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, DBUG_ENTER("THD::convert_string"); size_t new_length= to_cs->mbmaxlen * from_length; uint errors; - if (alloc_lex_string(to, new_length + 1)) + if (unlikely(alloc_lex_string(to, new_length + 1))) DBUG_RETURN(true); // EOM to->length= copy_and_convert((char*) to->str, new_length, to_cs, from, from_length, from_cs, &errors); to->str[to->length]= 0; // Safety - if (errors && lex->parse_vcol_expr) + if (unlikely(errors) && lex->parse_vcol_expr) { my_error(ER_BAD_DATA, MYF(0), ErrConvString(from, from_length, from_cs).ptr(), @@ -2483,7 +2465,8 @@ bool THD::copy_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst, bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) { uint dummy_errors; - if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors)) + if (unlikely(convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, + &dummy_errors))) return TRUE; /* If convert_buffer >> s copying is more efficient long term */ if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 || @@ -2496,6 +2479,39 @@ bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) } +bool THD::check_string_for_wellformedness(const char *str, + size_t length, + CHARSET_INFO *cs) const +{ + DBUG_ASSERT(charset_is_system_charset); + size_t wlen= Well_formed_prefix(cs, str, length).length(); + if (wlen < length) + { + ErrConvString err(str, length, &my_charset_bin); + my_error(ER_INVALID_CHARACTER_STRING, MYF(0), cs->csname, err.ptr()); + return true; + } + return false; +} + + +bool THD::to_ident_sys_alloc(Lex_ident_sys_st *to, const Lex_ident_cli_st *ident) +{ + if (ident->is_quoted()) + { + LEX_CSTRING unquoted; + if (quote_unescape(&unquoted, ident, ident->quote())) + return true; + return charset_is_system_charset ? + to->copy_sys(this, &unquoted) : + to->convert(this, &unquoted, charset()); + } + return charset_is_system_charset ? + to->copy_sys(this, ident) : + to->copy_or_convert(this, ident, charset()); +} + + Item_basic_constant * THD::make_string_literal(const char *str, size_t length, uint repertoire) { @@ -2657,18 +2673,31 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, size_t key_length) } -int THD::send_explain_fields(select_result *result, uint8 explain_flags, bool is_analyze) +void THD::prepare_explain_fields(select_result *result, + List<Item> *field_list, + uint8 explain_flags, + bool is_analyze) { - List<Item> field_list; if (lex->explain_json) - make_explain_json_field_list(field_list, is_analyze); + make_explain_json_field_list(*field_list, is_analyze); else - make_explain_field_list(field_list, explain_flags, is_analyze); + make_explain_field_list(*field_list, explain_flags, is_analyze); + + result->prepare(*field_list, NULL); +} + - result->prepare(field_list, NULL); - return (result->send_result_set_metadata(field_list, - Protocol::SEND_NUM_ROWS | - Protocol::SEND_EOF)); +int THD::send_explain_fields(select_result *result, + uint8 explain_flags, + bool is_analyze) +{ + List<Item> field_list; + int rc; + prepare_explain_fields(result, &field_list, explain_flags, is_analyze); + rc= result->send_result_set_metadata(field_list, + Protocol::SEND_NUM_ROWS | + Protocol::SEND_EOF); + return(rc); } @@ -3015,7 +3044,7 @@ bool select_send::send_eof() Don't send EOF if we're in error condition (which implies we've already sent or are sending an error) */ - if (thd->is_error()) + if (unlikely(thd->is_error())) return TRUE; ::my_eof(thd); is_result_set_started= 0; @@ -3030,10 +3059,11 @@ bool select_send::send_eof() bool select_to_file::send_eof() { int error= MY_TEST(end_io_cache(&cache)); - if (mysql_file_close(file, MYF(MY_WME)) || thd->is_error()) + if (unlikely(mysql_file_close(file, MYF(MY_WME))) || + unlikely(thd->is_error())) error= true; - if (!error && !suppress_my_ok) + if (likely(!error) && !suppress_my_ok) { ::my_ok(thd,row_count); } @@ -3295,7 +3325,7 @@ int select_export::send_data(List<Item> &items) res->charset(), res->ptr(), res->length()); error_pos= copier.most_important_error_pos(); - if (error_pos) + if (unlikely(error_pos)) { char printable_buff[32]; convert_to_printable(printable_buff, sizeof(printable_buff), @@ -3814,7 +3844,7 @@ void Statement::set_statement(Statement *stmt) { id= stmt->id; column_usage= stmt->column_usage; - stmt_lex= lex= stmt->lex; + lex= stmt->lex; query_string= stmt->query_string; } @@ -4131,7 +4161,7 @@ bool select_dumpvar::send_eof() Don't send EOF if we're in error condition (which implies we've already sent or are sending an error) */ - if (thd->is_error()) + if (unlikely(thd->is_error())) return true; if (!suppress_my_ok) @@ -4267,9 +4297,8 @@ void thd_increment_bytes_sent(void *thd, size_t length) } } -my_bool thd_net_is_killed() +my_bool thd_net_is_killed(THD *thd) { - THD *thd= current_thd; return thd && thd->killed ? 1 : 0; } @@ -4737,7 +4766,7 @@ TABLE *open_purge_table(THD *thd, const char *db, size_t dblen, /* we don't recover here */ DBUG_ASSERT(!error || !ot_ctx.can_recover_from_failed_open()); - if (error) + if (unlikely(error)) close_thread_tables(thd); DBUG_RETURN(error ? NULL : tl->table); @@ -6359,7 +6388,8 @@ int THD::decide_logging_format(TABLE_LIST *tables) clear_binlog_local_stmt_filter(); } - if (error) { + if (unlikely(error)) + { DBUG_PRINT("info", ("decision: no logging since an error was generated")); DBUG_RETURN(-1); } @@ -6656,7 +6686,8 @@ int THD::binlog_write_row(TABLE* table, bool is_trans, Pack records into format for transfer. We are allocating more memory than needed, but that doesn't matter. */ - Row_data_memory memory(table, max_row_length(table, record)); + Row_data_memory memory(table, max_row_length(table, table->rpl_write_set, + record)); if (!memory.has_memory()) return HA_ERR_OUT_OF_MEM; @@ -6693,8 +6724,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans, DBUG_ASSERT(is_current_stmt_binlog_format_row() && ((WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open())); - size_t const before_maxlen = max_row_length(table, before_record); - size_t const after_maxlen = max_row_length(table, after_record); + size_t const before_maxlen= max_row_length(table, table->read_set, + before_record); + size_t const after_maxlen= max_row_length(table, table->rpl_write_set, + after_record); Row_data_memory row_data(table, before_maxlen, after_maxlen); if (!row_data.has_memory()) @@ -6770,7 +6803,8 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans, Pack records into format for transfer. We are allocating more memory than needed, but that doesn't matter. */ - Row_data_memory memory(table, max_row_length(table, record)); + Row_data_memory memory(table, max_row_length(table, table->read_set, + record)); if (unlikely(!memory.has_memory())) return HA_ERR_OUT_OF_MEM; @@ -6809,15 +6843,17 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans, } +/** + Remove from read_set spurious columns. The write_set has been + handled before in table->mark_columns_needed_for_update. +*/ + void THD::binlog_prepare_row_images(TABLE *table) { DBUG_ENTER("THD::binlog_prepare_row_images"); - /** - Remove from read_set spurious columns. The write_set has been - handled before in table->mark_columns_needed_for_update. - */ - DBUG_PRINT_BITSET("debug", "table->read_set (before preparing): %s", table->read_set); + DBUG_PRINT_BITSET("debug", "table->read_set (before preparing): %s", + table->read_set); THD *thd= table->in_use; /** @@ -6835,7 +6871,7 @@ void THD::binlog_prepare_row_images(TABLE *table) */ DBUG_ASSERT(table->read_set != &table->tmp_set); - switch(thd->variables.binlog_row_image) + switch (thd->variables.binlog_row_image) { case BINLOG_ROW_IMAGE_MINIMAL: /* MINIMAL: Mark only PK */ @@ -6865,7 +6901,8 @@ void THD::binlog_prepare_row_images(TABLE *table) table->write_set); } - DBUG_PRINT_BITSET("debug", "table->read_set (after preparing): %s", table->read_set); + DBUG_PRINT_BITSET("debug", "table->read_set (after preparing): %s", + table->read_set); DBUG_VOID_RETURN; } @@ -7201,8 +7238,11 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, top-most close_thread_tables(). */ if (this->locked_tables_mode <= LTM_LOCK_TABLES) - if (int error= binlog_flush_pending_rows_event(TRUE, is_trans)) + { + int error; + if (unlikely(error= binlog_flush_pending_rows_event(TRUE, is_trans))) DBUG_RETURN(error); + } /* Warnings for unsafe statements logged in statement format are @@ -7470,7 +7510,7 @@ wait_for_commit::wait_for_prior_commit2(THD *thd) thd->ENTER_COND(&COND_wait_commit, &LOCK_wait_commit, &stage_waiting_for_prior_transaction_to_commit, &old_stage); - while ((loc_waitee= this->waitee) && !thd->check_killed()) + while ((loc_waitee= this->waitee) && likely(!thd->check_killed(1))) mysql_cond_wait(&COND_wait_commit, &LOCK_wait_commit); if (!loc_waitee) { diff --git a/sql/sql_class.h b/sql/sql_class.h index a7c33cbc504..64b75dbe7be 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -632,6 +632,7 @@ typedef struct system_variables ulong query_cache_type; ulong tx_isolation; ulong updatable_views_with_limit; + ulong alter_algorithm; int max_user_connections; ulong server_id; /** @@ -655,7 +656,6 @@ typedef struct system_variables my_bool keep_files_on_create; my_bool old_mode; - my_bool old_alter_table; my_bool old_passwords; my_bool big_tables; my_bool only_standard_compliant_cte; @@ -820,8 +820,10 @@ typedef struct system_status_var ulong feature_fulltext; /* +1 when MATCH is used */ ulong feature_gis; /* +1 opening a table with GIS features */ ulong feature_invisible_columns; /* +1 opening a table with invisible column */ + ulong feature_json; /* +1 when JSON function appears in the statement */ ulong feature_locale; /* +1 when LOCALE is set */ ulong feature_subquery; /* +1 when subqueries are used */ + ulong feature_system_versioning; /* +1 opening a table WITH SYSTEM VERSIONING */ ulong feature_timezone; /* +1 when XPATH is used */ ulong feature_trigger; /* +1 opening a table with triggers */ ulong feature_xml; /* +1 when XPATH is used */ @@ -1012,7 +1014,7 @@ public: inline void* calloc(size_t size) { void *ptr; - if ((ptr=alloc_root(mem_root,size))) + if (likely((ptr=alloc_root(mem_root,size)))) bzero(ptr, size); return ptr; } @@ -1025,7 +1027,7 @@ public: inline void *memdup_w_gap(const void *str, size_t size, size_t gap) { void *ptr; - if ((ptr= alloc_root(mem_root,size+gap))) + if (likely((ptr= alloc_root(mem_root,size+gap)))) memcpy(ptr,str,size); return ptr; } @@ -1101,21 +1103,6 @@ public: LEX_CSTRING name; /* name for named prepared statements */ LEX *lex; // parse tree descriptor /* - LEX which represents current statement (conventional, SP or PS) - - For example during view parsing THD::lex will point to the views LEX and - THD::stmt_lex will point to LEX of the statement where the view will be - included - - Currently it is used to have always correct select numbering inside - statement (LEX::current_select_number) without storing and restoring a - global counter which was THD::select_number. - - TODO: make some unified statement representation (now SP has different) - to store such data like LEX::current_select_number. - */ - LEX *stmt_lex; - /* Points to the query associated with this statement. It's const, but we need to declare it char * because all table handlers are written in C and need to point to it. @@ -1910,7 +1897,7 @@ public: void unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count); - bool reopen_tables(THD *thd); + bool reopen_tables(THD *thd, bool need_reopen); bool restore_lock(THD *thd, TABLE_LIST *dst_table_list, TABLE *table, MYSQL_LOCK *lock); void add_back_last_deleted_lock(TABLE_LIST *dst_table_list); @@ -2152,26 +2139,6 @@ struct wait_for_commit void reinit(); }; -/* - Structure to store the start time for a query -*/ - -struct QUERY_START_TIME_INFO -{ - my_time_t start_time; - ulong start_time_sec_part; - ulonglong start_utime, utime_after_lock; - - void backup_query_start_time(QUERY_START_TIME_INFO *backup) - { - *backup= *this; - } - void restore_query_start_time(QUERY_START_TIME_INFO *backup) - { - *this= *backup; - } -}; - extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); /** @@ -2190,8 +2157,7 @@ class THD :public Statement, */ public Item_change_list, public MDL_context_owner, - public Open_tables_state, - public QUERY_START_TIME_INFO + public Open_tables_state { private: inline bool is_stmt_prepare() const @@ -2416,10 +2382,12 @@ public: uint32 file_id; // for LOAD DATA INFILE /* remote (peer) port */ uint16 peer_port; + my_time_t start_time; // start_time and its sec_part + ulong start_time_sec_part; // are almost always used separately my_hrtime_t user_time; // track down slow pthread_create ulonglong prior_thr_create_utime, thr_create_utime; - ulonglong utime_after_query; + ulonglong start_utime, utime_after_lock, utime_after_query; // Process indicator struct { @@ -2625,6 +2593,15 @@ public: WT_THD wt; ///< for deadlock detection Rows_log_event *m_pending_rows_event; + struct st_trans_time : public timeval + { + void reset(THD *thd) + { + tv_sec= thd->query_start(); + tv_usec= (long) thd->query_start_sec_part(); + } + } start_time; + /* Tables changed in transaction (that must be invalidated in query cache). List contain only transactional tables, that not invalidated in query @@ -3066,10 +3043,14 @@ public: } *killed_err; /* See also thd_killed() */ - inline bool check_killed() + inline bool check_killed(bool dont_send_error_message= 0) { - if (killed) + if (unlikely(killed)) + { + if (!dont_send_error_message) + send_kill_message(); return TRUE; + } if (apc_target.have_apc_requests()) apc_target.process_apc_requests(); return FALSE; @@ -3129,8 +3110,10 @@ public: is set if a statement accesses a temporary table created through CREATE TEMPORARY TABLE. */ - bool charset_is_system_charset, charset_is_collation_connection; +private: + bool charset_is_system_charset, charset_is_collation_connection; bool charset_is_character_set_filesystem; +public: bool enable_slow_log; /* Enable slow log for current statement */ bool abort_on_warning; bool got_warning; /* Set on call to push_warning() */ @@ -3434,16 +3417,13 @@ public: { query_start_sec_part_used=1; return start_time_sec_part; } MYSQL_TIME query_start_TIME(); +private: struct { my_hrtime_t start; my_time_t sec; ulong sec_part; } system_time; - ulong systime_sec_part() { query_start_sec_part_used=1; return system_time.sec_part; } - my_time_t systime() { return system_time.sec; } - -private: void set_system_time() { my_hrtime_t hrtime= my_hrtime(); @@ -3468,29 +3448,16 @@ private: } } - void set_system_time_from_user_time(bool with_sec_part) +public: + timeval transaction_time() { - if (with_sec_part) - { - system_time.sec= start_time; - system_time.sec_part= start_time_sec_part; - } - else - { - if (system_time.sec == start_time) - system_time.sec_part++; - else - { - system_time.sec= start_time; - system_time.sec_part= 0; - } - } + if (!in_multi_stmt_transaction_mode()) + transaction.start_time.reset(this); + return transaction.start_time; } -public: inline void set_start_time() { - set_system_time(); if (user_time.val) { start_time= hrtime_to_my_time(user_time); @@ -3498,6 +3465,7 @@ public: } else { + set_system_time(); start_time= system_time.sec; start_time_sec_part= system_time.sec_part; } @@ -3508,6 +3476,7 @@ public: set_start_time(); start_utime= utime_after_lock= microsecond_interval_timer(); } + /* only used in SET @@timestamp=... */ inline void set_time(my_hrtime_t t) { user_time= t; @@ -3519,15 +3488,29 @@ public: */ inline void set_time(my_time_t t, ulong sec_part) { - start_time= t; - start_time_sec_part= sec_part > TIME_MAX_SECOND_PART ? 0 : sec_part; - user_time.val= hrtime_from_time(start_time) + start_time_sec_part; - if (slave_thread) - set_system_time_from_user_time(sec_part <= TIME_MAX_SECOND_PART); - else // BINLOG command - set_system_time(); - PSI_CALL_set_thread_start_time(start_time); - start_utime= utime_after_lock= microsecond_interval_timer(); + if (opt_secure_timestamp > (slave_thread ? SECTIME_REPL : SECTIME_SUPER)) + set_time(); // note that BINLOG itself requires SUPER + else + { + if (sec_part <= TIME_MAX_SECOND_PART) + { + start_time= system_time.sec= t; + start_time_sec_part= system_time.sec_part= sec_part; + } + else if (t != system_time.sec) + { + start_time= system_time.sec= t; + start_time_sec_part= system_time.sec_part= 0; + } + else + { + start_time= t; + start_time_sec_part= ++system_time.sec_part; + } + user_time.val= hrtime_from_time(start_time) + start_time_sec_part; + PSI_CALL_set_thread_start_time(start_time); + start_utime= utime_after_lock= microsecond_interval_timer(); + } } void set_time_after_lock() { @@ -3657,13 +3640,34 @@ public: lex_str->length= length; return lex_str; } + // Remove double quotes: aaa""bbb -> aaa"bbb + bool quote_unescape(LEX_CSTRING *dst, const LEX_CSTRING *src, char quote) + { + const char *tmp= src->str; + const char *tmpend= src->str + src->length; + char *to; + if (!(dst->str= to= (char *) alloc(src->length + 1))) + { + dst->length= 0; // Safety + return true; + } + for ( ; tmp < tmpend; ) + { + if ((*to++= *tmp++) == quote) + tmp++; // Skip double quotes + } + *to= 0; // End null for safety + dst->length= to - dst->str; + return false; + } LEX_CSTRING *make_clex_string(const char* str, size_t length) { LEX_CSTRING *lex_str; char *tmp; - if (!(lex_str= (LEX_CSTRING *)alloc_root(mem_root, sizeof(LEX_CSTRING) + - length+1))) + if (unlikely(!(lex_str= (LEX_CSTRING *)alloc_root(mem_root, + sizeof(LEX_CSTRING) + + length+1)))) return 0; tmp= (char*) (lex_str+1); lex_str->str= tmp; @@ -3676,7 +3680,7 @@ public: // Allocate LEX_STRING for character set conversion bool alloc_lex_string(LEX_STRING *dst, size_t length) { - if ((dst->str= (char*) alloc(length))) + if (likely((dst->str= (char*) alloc(length)))) return false; dst->length= 0; // Safety return true; // EOM @@ -3684,6 +3688,25 @@ public: bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, const char *from, size_t from_length, CHARSET_INFO *from_cs); + bool convert_string(LEX_CSTRING *to, CHARSET_INFO *to_cs, + const char *from, size_t from_length, + CHARSET_INFO *from_cs) + { + LEX_STRING tmp; + bool rc= convert_string(&tmp, to_cs, from, from_length, from_cs); + to->str= tmp.str; + to->length= tmp.length; + return rc; + } + bool convert_string(LEX_CSTRING *to, CHARSET_INFO *tocs, + const LEX_CSTRING *from, CHARSET_INFO *fromcs, + bool simple_copy_is_possible) + { + if (!simple_copy_is_possible) + return unlikely(convert_string(to, tocs, from->str, from->length, fromcs)); + *to= *from; + return false; + } /* Convert a strings between character sets. Uses my_convert_fix(), which uses an mb_wc .. mc_mb loop internally. @@ -3700,7 +3723,6 @@ public: bool convert_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst, CHARSET_INFO *srccs, const char *src, size_t src_length); - /* If either "dstcs" or "srccs" is &my_charset_bin, then performs native copying using cs->cset->copy_fix(). @@ -3720,6 +3742,17 @@ public: bool convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs); /* + Check if the string is wellformed, raise an error if not wellformed. + @param str - The string to check. + @param length - the string length. + */ + bool check_string_for_wellformedness(const char *str, + size_t length, + CHARSET_INFO *cs) const; + + bool to_ident_sys_alloc(Lex_ident_sys_st *to, const Lex_ident_cli_st *from); + + /* Create a string literal with optional client->connection conversion. @param str - the string in the client character set @param length - length of the string @@ -3735,9 +3768,29 @@ public: Item_basic_constant *make_string_literal_nchar(const Lex_string_with_metadata_st &str); Item_basic_constant *make_string_literal_charset(const Lex_string_with_metadata_st &str, CHARSET_INFO *cs); + bool make_text_string_sys(LEX_CSTRING *to, + const Lex_string_with_metadata_st *from) + { + return convert_string(to, system_charset_info, + from, charset(), charset_is_system_charset); + } + bool make_text_string_connection(LEX_CSTRING *to, + const Lex_string_with_metadata_st *from) + { + return convert_string(to, variables.collation_connection, + from, charset(), charset_is_collation_connection); + } + bool make_text_string_filesystem(LEX_CSTRING *to, + const Lex_string_with_metadata_st *from) + { + return convert_string(to, variables.character_set_filesystem, + from, charset(), charset_is_character_set_filesystem); + } void add_changed_table(TABLE *table); void add_changed_table(const char *key, size_t key_length); CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length); + void prepare_explain_fields(select_result *result, List<Item> *field_list, + uint8 explain_flags, bool is_analyze); int send_explain_fields(select_result *result, uint8 explain_flags, bool is_analyze); void make_explain_field_list(List<Item> &field_list, uint8 explain_flags, @@ -3824,7 +3877,7 @@ public: void set_stmt_da(Diagnostics_area *da) { m_stmt_da= da; } - inline CHARSET_INFO *charset() { return variables.character_set_client; } + inline CHARSET_INFO *charset() const { return variables.character_set_client; } void update_charset(); void update_charset(CHARSET_INFO *character_set_client, CHARSET_INFO *collation_connection) @@ -3932,7 +3985,7 @@ public: The worst things that can happen is that we get a suboptimal error message. */ - if ((killed_err= (err_info*) alloc(sizeof(*killed_err)))) + if (likely((killed_err= (err_info*) alloc(sizeof(*killed_err))))) { killed_err->no= killed_errno_arg; ::strmake((char*) killed_err->msg, killed_err_msg_arg, @@ -4029,6 +4082,16 @@ public: DBUG_VOID_RETURN; } + inline enum_binlog_format get_current_stmt_binlog_format() + { + return current_stmt_binlog_format; + } + + inline void set_current_stmt_binlog_format(enum_binlog_format format) + { + current_stmt_binlog_format= format; + } + inline void set_current_stmt_binlog_format_row() { DBUG_ENTER("set_current_stmt_binlog_format_row"); @@ -4214,16 +4277,8 @@ public: void parse_error(const char *err_text, const char *yytext) { Lex_input_stream *lip= &m_parser_state->m_lip; - if (!yytext) - { - if (lip->lookahead_token >= 0) - yytext= lip->get_tok_start_prev(); - else - yytext= lip->get_tok_start(); - - if (!yytext) + if (!yytext && !(yytext= lip->get_tok_start())) yytext= ""; - } /* Push an error into the error stack */ ErrConvString err(yytext, strlen(yytext), variables.character_set_client); my_printf_error(ER_PARSE_ERROR, ER_THD(this, ER_PARSE_ERROR), MYF(0), @@ -4513,6 +4568,12 @@ public: /* Members related to temporary tables. */ public: + /* Opened table states. */ + enum Temporary_table_state { + TMP_TABLE_IN_USE, + TMP_TABLE_NOT_IN_USE, + TMP_TABLE_ANY + }; bool has_thd_temporary_tables(); TABLE *create_and_open_tmp_table(handlerton *hton, @@ -4523,8 +4584,10 @@ public: bool open_in_engine, bool open_internal_tables); - TABLE *find_temporary_table(const char *db, const char *table_name); - TABLE *find_temporary_table(const TABLE_LIST *tl); + TABLE *find_temporary_table(const char *db, const char *table_name, + Temporary_table_state state= TMP_TABLE_IN_USE); + TABLE *find_temporary_table(const TABLE_LIST *tl, + Temporary_table_state state= TMP_TABLE_IN_USE); TMP_TABLE_SHARE *find_tmp_table_share_w_base_key(const char *key, uint key_length); @@ -4551,13 +4614,6 @@ private: /* Whether a lock has been acquired? */ bool m_tmp_tables_locked; - /* Opened table states. */ - enum Temporary_table_state { - TMP_TABLE_IN_USE, - TMP_TABLE_NOT_IN_USE, - TMP_TABLE_ANY - }; - bool has_temporary_tables(); uint create_tmp_table_def_key(char *key, const char *db, const char *table_name); @@ -4606,7 +4662,6 @@ public: query_id_t wsrep_last_query_id; enum wsrep_query_state wsrep_query_state; enum wsrep_conflict_state wsrep_conflict_state; - mysql_mutex_t LOCK_wsrep_thd; wsrep_trx_meta_t wsrep_trx_meta; uint32 wsrep_rand; Relay_log_info *wsrep_rli; @@ -4727,7 +4782,7 @@ public: void set_local_lex(sp_lex_local *sublex) { DBUG_ASSERT(lex->sphead); - lex= stmt_lex= sublex; + lex= sublex; /* Reset part of parser state which needs this. */ m_parser_state->m_yacc.reset_before_substatement(); } @@ -4907,7 +4962,7 @@ public: unit= u; return 0; } - virtual int prepare2(void) { return 0; } + virtual int prepare2(JOIN *join) { return 0; } /* Because of peculiarities of prepared statements protocol we need to know number of columns in the result set (if @@ -4916,7 +4971,7 @@ public: virtual uint field_count(List<Item> &fields) const { return fields.elements; } virtual bool send_result_set_metadata(List<Item> &list, uint flags)=0; - virtual bool initialize_tables (JOIN *join=0) { return 0; } + virtual bool initialize_tables (JOIN *join) { return 0; } virtual bool send_eof()=0; /** Check if this query returns a result set and therefore is allowed in @@ -5151,7 +5206,7 @@ class select_insert :public select_result_interceptor { enum_duplicates duplic, bool ignore); ~select_insert(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - virtual int prepare2(void); + virtual int prepare2(JOIN *join); virtual int send_data(List<Item> &items); virtual void store_values(List<Item> &values); virtual bool can_rollback_data() { return 0; } @@ -5203,7 +5258,7 @@ public: // Needed for access from local class MY_HOOKS in prepare(), since thd is proteted. const THD *get_thd(void) { return thd; } const HA_CREATE_INFO *get_create_info() { return create_info; }; - int prepare2(void) { return 0; } + int prepare2(JOIN *join) { return 0; } private: TABLE *create_table_from_items(THD *thd, @@ -5468,7 +5523,7 @@ public: bool postponed_prepare(List<Item> &types); bool send_result_set_metadata(List<Item> &list, uint flags); int send_data(List<Item> &items); - bool initialize_tables (JOIN *join= NULL); + bool initialize_tables (JOIN *join); bool send_eof(); bool flush() { return false; } bool check_simple_select() const @@ -5887,6 +5942,7 @@ public: int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int send_data(List<Item> &items); bool initialize_tables (JOIN *join); + int prepare2(JOIN *join); int do_updates(); bool send_eof(); inline ha_rows num_found() const { return found; } @@ -6364,7 +6420,8 @@ public: char *tmp; /* format: [database + dot] + name + '\0' */ dst->length= m_db.length + dot + m_name.length; - if (!(dst->str= tmp= (char*) alloc_root(mem_root, dst->length + 1))) + if (unlikely(!(dst->str= tmp= (char*) alloc_root(mem_root, + dst->length + 1)))) return true; sprintf(tmp, "%.*s%.*s%.*s", (int) m_db.length, (m_db.length ? m_db.str : ""), @@ -6380,7 +6437,7 @@ public: { char *tmp; size_t length= package.length + 1 + routine.length + 1; - if (!(tmp= (char *) alloc_root(mem_root, length))) + if (unlikely(!(tmp= (char *) alloc_root(mem_root, length)))) return true; m_name.length= my_snprintf(tmp, length, "%.*s.%.*s", (int) package.length, package.str, @@ -6394,9 +6451,9 @@ public: const LEX_CSTRING &package, const LEX_CSTRING &routine) { - if (make_package_routine_name(mem_root, package, routine)) + if (unlikely(make_package_routine_name(mem_root, package, routine))) return true; - if (!(m_db.str= strmake_root(mem_root, db.str, db.length))) + if (unlikely(!(m_db.str= strmake_root(mem_root, db.str, db.length)))) return true; m_db.length= db.length; return false; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 558d11eca8c..b48070b9c8f 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -167,7 +167,7 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) error= 0; end: - if (error) + if (unlikely(error)) { uc->connections--; // no need for decrease_user_connections() here /* @@ -178,7 +178,7 @@ end: thd->user_connect= NULL; } mysql_mutex_unlock(&LOCK_user_conn); - if (error) + if (unlikely(error)) { inc_host_errors(thd->main_security_ctx.ip, &errors); } @@ -1049,7 +1049,7 @@ static int check_connection(THD *thd) vio_keepalive(net->vio, TRUE); vio_set_keepalive_options(net->vio, &opt_vio_keepalive); - if (thd->packet.alloc(thd->variables.net_buffer_length)) + if (unlikely(thd->packet.alloc(thd->variables.net_buffer_length))) { /* Important note: @@ -1139,7 +1139,7 @@ bool login_connection(THD *thd) error= check_connection(thd); thd->protocol->end_statement(); - if (error) + if (unlikely(error)) { // Wrong permissions #ifdef _WIN32 if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE) @@ -1206,13 +1206,13 @@ void end_connection(THD *thd) thd->user_connect= NULL; } - if (thd->killed || (net->error && net->vio != 0)) + if (unlikely(thd->killed) || (net->error && net->vio != 0)) { statistic_increment(aborted_threads,&LOCK_status); status_var_increment(thd->status_var.lost_connections); } - if (!thd->killed && (net->error && net->vio != 0)) + if (likely(!thd->killed) && (net->error && net->vio != 0)) thd->print_aborted_warning(1, thd->get_stmt_da()->is_error() ? thd->get_stmt_da()->message() : ER_THD(thd, ER_UNKNOWN_ERROR)); } @@ -1241,7 +1241,7 @@ void prepare_new_connection_state(THD* thd) if (opt_init_connect.length && !(sctx->master_access & SUPER_ACL)) { execute_init_command(thd, &opt_init_connect, &LOCK_sys_init_connect); - if (thd->is_error()) + if (unlikely(thd->is_error())) { Host_errors errors; thd->set_killed(KILL_CONNECTION); @@ -1330,9 +1330,9 @@ bool thd_prepare_connection(THD *thd) bool thd_is_connection_alive(THD *thd) { NET *net= &thd->net; - if (!net->error && - net->vio != 0 && - thd->killed < KILL_CONNECTION) + if (likely(!net->error && + net->vio != 0 && + thd->killed < KILL_CONNECTION)) return TRUE; return FALSE; } @@ -1407,9 +1407,9 @@ void do_handle_one_connection(CONNECT *connect) #ifdef WITH_WSREP if (WSREP(thd)) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_query_state= QUERY_EXITING; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif end_thread: @@ -1510,7 +1510,7 @@ THD *CONNECT::create_thd(THD *thd) res= my_net_init(&thd->net, vio, thd, MYF(MY_THREAD_SPECIFIC)); vio= 0; // Vio now handled by thd - if (res || thd->is_error()) + if (unlikely(res || thd->is_error())) { if (!thd_reused) delete thd; diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index a58a9254a82..97bbf8f73bd 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -682,7 +682,6 @@ void With_element::move_anchors_ahead() { st_select_lex *next_sl; st_select_lex *new_pos= spec->first_select(); - st_select_lex *UNINIT_VAR(last_sl); new_pos->linkage= UNION_TYPE; for (st_select_lex *sl= new_pos; sl; sl= next_sl) { @@ -690,6 +689,14 @@ void With_element::move_anchors_ahead() if (is_anchor(sl)) { sl->move_node(new_pos); + if (new_pos == spec->first_select()) + { + enum sub_select_type type= new_pos->linkage; + new_pos->linkage= sl->linkage; + sl->linkage= type; + new_pos->with_all_modifier= sl->with_all_modifier; + sl->with_all_modifier= false; + } new_pos= sl->next_select(); } else if (!sq_rec_ref && no_rec_ref_on_top_level()) @@ -697,10 +704,7 @@ void With_element::move_anchors_ahead() sq_rec_ref= find_first_sq_rec_ref_in_select(sl); DBUG_ASSERT(sq_rec_ref != NULL); } - last_sl= sl; } - if (spec->union_distinct) - spec->union_distinct= last_sl; first_recursive= new_pos; } @@ -829,8 +833,9 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length)) goto err; lex_start(thd); + lex->stmt_lex= old_lex; with_select= &lex->select_lex; - with_select->select_number= ++thd->stmt_lex->current_select_number; + with_select->select_number= ++thd->lex->stmt_lex->current_select_number; parse_status= parse_sql(thd, &parser_state, 0); if (parse_status) goto err; @@ -978,7 +983,7 @@ bool With_element::prepare_unreferenced(THD *thd) thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; if (!spec->prepared && - (spec->prepare(thd, 0, 0) || + (spec->prepare(spec->derived, 0, 0) || rename_columns_of_derived_unit(thd, spec) || check_duplicate_names(thd, first_sl->item_list, 1))) rc= true; @@ -1189,7 +1194,7 @@ bool st_select_lex::check_unrestricted_recursive(bool only_standard_compliant) /* Check conditions 3-4 for restricted specification*/ - if (with_sum_func || + if ((with_sum_func && !with_elem->is_anchor(this)) || (with_elem->contains_sq_with_recursive_reference())) with_elem->get_owner()->add_unrestricted( with_elem->get_mutually_recursive()); @@ -1414,7 +1419,7 @@ bool With_element::instantiate_tmp_tables() { if (!rec_table->is_created() && instantiate_tmp_table(rec_table, - rec_result->tmp_table_param.keyinfo, + rec_table->s->key_info, rec_result->tmp_table_param.start_recinfo, &rec_result->tmp_table_param.recinfo, 0)) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 67910a3b618..5f826e37a76 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -293,7 +293,7 @@ static my_bool put_dbopt(const char *dbname, Schema_specification_st *create) strmov(opt->name, dbname); opt->name_length= length; - if ((error= my_hash_insert(&dboptions, (uchar*) opt))) + if (unlikely((error= my_hash_insert(&dboptions, (uchar*) opt)))) { my_free(opt); goto end; @@ -338,7 +338,7 @@ static void del_dbopt(const char *path) static bool write_db_opt(THD *thd, const char *path, Schema_specification_st *create) { - register File file; + File file; char buf[256]; // Should be enough for one option bool error=1; @@ -724,7 +724,7 @@ mysql_alter_db_internal(THD *thd, const LEX_CSTRING *db, "table name to file name" encoding. */ build_table_filename(path, sizeof(path) - 1, db->str, "", MY_DB_OPT_FILE, 0); - if ((error=write_db_opt(thd, path, create_info))) + if (unlikely((error=write_db_opt(thd, path, create_info)))) goto exit; /* Change options if current database is being altered. */ @@ -754,7 +754,7 @@ mysql_alter_db_internal(THD *thd, const LEX_CSTRING *db, These DDL methods and logging are protected with the exclusive metadata lock on the schema. */ - if ((error= mysql_bin_log.write(&qinfo))) + if (unlikely((error= mysql_bin_log.write(&qinfo)))) goto exit; } my_ok(thd, result); @@ -938,7 +938,7 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silen thd->pop_internal_handler(); update_binlog: - if (!silent && !error) + if (!silent && likely(!error)) { const char *query; ulong query_length; @@ -993,8 +993,7 @@ update_binlog: if (ha_table_exists(thd, &tbl->db, &tbl->table_name)) continue; - tbl_name_len= my_snprintf(quoted_name, sizeof(quoted_name), - quoted_string, + tbl_name_len= my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name.str); tbl_name_len++; /* +1 for the comma */ if (query_pos + tbl_name_len + 1 >= query_end) @@ -1036,7 +1035,7 @@ exit: SELECT DATABASE() in the future). For this we free() thd->db and set it to 0. */ - if (thd->db.str && cmp_db_names(&thd->db, db) && !error) + if (unlikely(thd->db.str && cmp_db_names(&thd->db, db) && !error)) { mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); SESSION_TRACKER_CHANGED(thd, CURRENT_SCHEMA_TRACKER, NULL); @@ -1179,9 +1178,9 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) if (pos > path && pos[-1] == FN_LIBCHAR) *--pos=0; - if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0) + if (unlikely((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)) DBUG_RETURN(1); - if (!error) + if (likely(!error)) { if (mysql_file_delete(key_file_misc, path, MYF(send_error ? MY_WME : 0))) { @@ -1196,7 +1195,7 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) if (pos > path && pos[-1] == FN_LIBCHAR) *--pos=0; - if (rmdir(path) < 0 && send_error) + if (unlikely(rmdir(path) < 0 && send_error)) { my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno); DBUG_RETURN(1); @@ -1697,15 +1696,16 @@ bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db) length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0); if (length && path[length-1] == FN_LIBCHAR) path[length-1]=0; // remove ending '\' - if ((error= my_access(path,F_OK))) + if (unlikely((error= my_access(path,F_OK)))) { my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str); goto exit; } /* Step1: Create the new database */ - if ((error= mysql_create_db_internal(thd, &new_db, - DDL_options(), &create_info, 1))) + if (unlikely((error= mysql_create_db_internal(thd, &new_db, + DDL_options(), &create_info, + 1)))) goto exit; /* Step2: Move tables to the new database */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 0a12d01596b..b6ca2e956cb 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -254,7 +254,12 @@ int TABLE::delete_row() store_record(this, record[1]); vers_update_end(); - return file->ha_update_row(record[1], record[0]); + int res; + if ((res= file->extra(HA_EXTRA_REMEMBER_POS))) + return res; + if ((res= file->ha_update_row(record[1], record[0]))) + return res; + return file->extra(HA_EXTRA_RESTORE_POS); } @@ -305,7 +310,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, THD_STAGE_INFO(thd, stage_init_update); - bool truncate_history= table_list->vers_conditions; + bool truncate_history= table_list->vers_conditions.is_set(); if (truncate_history) { if (table_list->is_view_or_derived()) @@ -324,13 +329,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, DBUG_ASSERT(!conds); conds= table_list->on_expr; table_list->on_expr= NULL; - - // trx_sees() in InnoDB reads row_start - if (!table->versioned(VERS_TIMESTAMP)) - { - DBUG_ASSERT(table_list->vers_conditions.type == SYSTEM_TIME_BEFORE); - bitmap_set_bit(table->read_set, table->vers_end_field()->field_index); - } } if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT)) @@ -401,7 +399,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } const_cond_result= const_cond && (!conds || conds->val_int()); - if (thd->is_error()) + if (unlikely(thd->is_error())) { /* Error evaluating val_int(). */ DBUG_RETURN(TRUE); @@ -439,7 +437,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (thd->lex->describe) goto produce_explain_and_leave; - if (!(error=table->file->ha_delete_all_rows())) + if (likely(!(error=table->file->ha_delete_all_rows()))) { /* If delete_all_rows() is used, it is not possible to log the @@ -495,7 +493,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, table->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); - if (error) + if (unlikely(error)) DBUG_RETURN(TRUE); if ((select && select->check_quick(thd, safe_update, limit)) || !limit) { @@ -511,7 +509,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, Currently they rely on the user checking DA for errors when unwinding the stack after calling Item::val_xxx(). */ - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(TRUE); my_ok(thd, 0); DBUG_RETURN(0); // Nothing to delete @@ -662,10 +660,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, else error= init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); - if (error) + if (unlikely(error)) goto got_error; - if (init_ftfuncs(thd, select_lex, 1)) + if (unlikely(init_ftfuncs(thd, select_lex, 1))) goto got_error; table->mark_columns_needed_for_delete(); @@ -676,9 +674,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (with_select) { - if (result->send_result_set_metadata(select_lex->item_list, - Protocol::SEND_NUM_ROWS | - Protocol::SEND_EOF)) + if (unlikely(result->send_result_set_metadata(select_lex->item_list, + Protocol::SEND_NUM_ROWS | + Protocol::SEND_EOF))) goto cleanup; } @@ -703,7 +701,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (record_should_be_deleted(thd, table, select, explain, truncate_history)) { table->file->position(table->record[0]); - if ((error= deltempfile->unique_add((char*) table->file->ref))) + if (unlikely((error= + deltempfile->unique_add((char*) table->file->ref)))) { error= 1; goto terminate_delete; @@ -713,8 +712,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } } end_read_record(&info); - if (deltempfile->get(table) || table->file->ha_index_or_rnd_end() || - init_read_record(&info, thd, table, 0, &deltempfile->sort, 0, 1, false)) + if (unlikely(deltempfile->get(table)) || + unlikely(table->file->ha_index_or_rnd_end()) || + unlikely(init_read_record(&info, thd, table, 0, &deltempfile->sort, 0, + 1, false))) { error= 1; goto terminate_delete; @@ -723,8 +724,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } THD_STAGE_INFO(thd, stage_updating); - while (!(error=info.read_record()) && !thd->killed && - ! thd->is_error()) + while (likely(!(error=info.read_record())) && likely(!thd->killed) && + likely(!thd->is_error())) { if (delete_while_scanning) delete_record= record_should_be_deleted(thd, table, select, explain, @@ -746,7 +747,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } error= table->delete_row(); - if (!error) + if (likely(!error)) { deleted++; if (!truncate_history && table->triggers && @@ -777,7 +778,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, Don't try unlocking the row if skip_record reported an error since in this case the transaction might have been rolled back already. */ - else if (!thd->is_error()) + else if (likely(!thd->is_error())) table->file->unlock_row(); // Row failed selection, release lock on it else break; @@ -785,9 +786,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, terminate_delete: killed_status= thd->killed; - if (killed_status != NOT_KILLED || thd->is_error()) + if (unlikely(killed_status != NOT_KILLED || thd->is_error())) error= 1; // Aborted - if (will_batch && (loc_error= table->file->end_bulk_delete())) + if (will_batch && unlikely((loc_error= table->file->end_bulk_delete()))) { if (error != 1) table->file->print_error(loc_error,MYF(0)); @@ -826,7 +827,7 @@ cleanup: thd->transaction.all.modified_non_trans_table= TRUE; /* See similar binlogging code in sql_update.cc, for comments */ - if ((error < 0) || thd->transaction.stmt.modified_non_trans_table) + if (likely((error < 0) || thd->transaction.stmt.modified_non_trans_table)) { if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) { @@ -857,7 +858,7 @@ cleanup: } DBUG_ASSERT(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table); - if (error < 0 || + if (likely(error < 0) || (thd->lex->ignore && !thd->is_error() && !thd->is_fatal_error)) { if (thd->lex->analyze_stmt) @@ -938,7 +939,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, select_lex->leaf_tables, FALSE, DELETE_ACL, SELECT_ACL, TRUE)) DBUG_RETURN(TRUE); - if (table_list->vers_conditions) + if (table_list->vers_conditions.is_set()) { if (table_list->is_view()) { @@ -948,7 +949,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, if (select_lex->vers_setup_conds(thd, table_list)) DBUG_RETURN(true); } - if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num)) || + if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num, + &select_lex->hidden_bit_fields)) || setup_fields(thd, Ref_ptr_array(), field_list, MARK_COLUMNS_READ, NULL, NULL, 0) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || @@ -1122,7 +1124,8 @@ multi_delete::initialize_tables(JOIN *join) Unique **tempfiles_ptr; DBUG_ENTER("initialize_tables"); - if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join)) + if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) && + error_if_full_join(join))) DBUG_RETURN(1); table_map tables_to_delete_from=0; @@ -1132,7 +1135,7 @@ multi_delete::initialize_tables(JOIN *join) TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update(); tables_to_delete_from|= tbl->table->map; if (delete_while_scanning && - unique_table(thd, tbl, join->tables_list, false)) + unique_table(thd, tbl, join->tables_list, 0)) { /* If the table we are going to delete from appears @@ -1252,7 +1255,7 @@ int multi_delete::send_data(List<Item> &values) table->status|= STATUS_DELETED; error= table->delete_row(); - if (!error) + if (likely(!error)) { deleted++; if (!table->file->has_transactions()) @@ -1275,7 +1278,7 @@ int multi_delete::send_data(List<Item> &values) else { error=tempfiles[secure_counter]->unique_add((char*) table->file->ref); - if (error) + if (unlikely(error)) { error= 1; // Fatal error DBUG_RETURN(1); @@ -1371,19 +1374,19 @@ int multi_delete::do_deletes() { TABLE *table = table_being_deleted->table; int local_error; - if (tempfiles[counter]->get(table)) + if (unlikely(tempfiles[counter]->get(table))) DBUG_RETURN(1); local_error= do_table_deletes(table, &tempfiles[counter]->sort, thd->lex->ignore); - if (thd->killed && !local_error) + if (unlikely(thd->killed) && likely(!local_error)) DBUG_RETURN(1); - if (local_error == -1) // End of file - local_error = 0; + if (unlikely(local_error == -1)) // End of file + local_error= 0; - if (local_error) + if (unlikely(local_error)) DBUG_RETURN(local_error); } DBUG_RETURN(0); @@ -1413,27 +1416,23 @@ int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info, ha_rows last_deleted= deleted; DBUG_ENTER("do_deletes_for_table"); - if (init_read_record(&info, thd, table, NULL, sort_info, 0, 1, FALSE)) + if (unlikely(init_read_record(&info, thd, table, NULL, sort_info, 0, 1, + FALSE))) DBUG_RETURN(1); - /* - Ignore any rows not found in reference tables as they may already have - been deleted by foreign key handling - */ - info.ignore_not_found_rows= 1; bool will_batch= !table->file->start_bulk_delete(); - while (!(local_error= info.read_record()) && !thd->killed) + while (likely(!(local_error= info.read_record())) && likely(!thd->killed)) { if (table->triggers && - table->triggers->process_triggers(thd, TRG_EVENT_DELETE, - TRG_ACTION_BEFORE, FALSE)) + unlikely(table->triggers->process_triggers(thd, TRG_EVENT_DELETE, + TRG_ACTION_BEFORE, FALSE))) { local_error= 1; break; } local_error= table->delete_row(); - if (local_error && !ignore) + if (unlikely(local_error) && !ignore) { table->file->print_error(local_error, MYF(0)); break; @@ -1444,7 +1443,7 @@ int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info, during ha_delete_row. Also, don't execute the AFTER trigger if the row operation failed. */ - if (!local_error) + if (unlikely(!local_error)) { deleted++; if (table->triggers && @@ -1459,7 +1458,7 @@ int multi_delete::do_table_deletes(TABLE *table, SORT_INFO *sort_info, if (will_batch) { int tmp_error= table->file->end_bulk_delete(); - if (tmp_error && !local_error) + if (unlikely(tmp_error) && !local_error) { local_error= tmp_error; table->file->print_error(local_error, MYF(0)); @@ -1507,28 +1506,30 @@ bool multi_delete::send_eof() { query_cache_invalidate3(thd, delete_tables, 1); } - if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table) + if (likely((local_error == 0) || + thd->transaction.stmt.modified_non_trans_table)) { if(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) { int errcode= 0; - if (local_error == 0) + if (likely(local_error == 0)) thd->clear_error(); else errcode= query_error_code(thd, killed_status == NOT_KILLED); - if (thd->binlog_query(THD::ROW_QUERY_TYPE, - thd->query(), thd->query_length(), - transactional_tables, FALSE, FALSE, errcode) && + if (unlikely(thd->binlog_query(THD::ROW_QUERY_TYPE, + thd->query(), thd->query_length(), + transactional_tables, FALSE, FALSE, + errcode)) && !normal_tables) { local_error=1; // Log write failed: roll back the SQL statement } } } - if (local_error != 0) + if (unlikely(local_error != 0)) error_handled= TRUE; // to force early leave from ::abort_result_set() - if (!local_error && !thd->lex->analyze_stmt) + if (likely(!local_error && !thd->lex->analyze_stmt)) { ::my_ok(thd, deleted); } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 2df740b6811..944fc837572 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -674,7 +674,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) table reference from a subquery for this. */ DBUG_ASSERT(derived->with->get_sq_rec_ref()); - if (mysql_derived_prepare(lex->thd, lex, derived->with->get_sq_rec_ref())) + if (unlikely(mysql_derived_prepare(lex->thd, lex, + derived->with->get_sq_rec_ref()))) DBUG_RETURN(TRUE); } @@ -698,7 +699,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) &derived->alias, FALSE, FALSE, FALSE, 0); thd->create_tmp_table_for_derived= FALSE; - if (!res && !derived->table) + if (likely(!res) && !derived->table) { derived->derived_result->set_unit(unit); derived->table= derived->derived_result->table; @@ -747,8 +748,6 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) } } - unit->derived= derived; - /* Above cascade call of prepare is important for PS protocol, but after it is called we can check if we really need prepare for this derived @@ -766,7 +765,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; // st_select_lex_unit::prepare correctly work for single select - if ((res= unit->prepare(thd, derived->derived_result, 0))) + if ((res= unit->prepare(derived, derived->derived_result, 0))) goto exit; if (derived->with && (res= derived->with->rename_columns_of_derived_unit(thd, unit))) diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 20a7aa75590..2a4e43ab78a 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -35,7 +35,7 @@ bool mysql_do(THD *thd, List<Item> &values) (void) value->is_null(); free_underlaid_joins(thd, &thd->lex->select_lex); - if (thd->is_error()) + if (unlikely(thd->is_error())) { /* Rollback the effect of the statement, since next instruction diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 67440aeed33..d6f5b99eef6 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -337,7 +337,7 @@ Diagnostics_area::set_ok_status(ulonglong affected_rows, In production, refuse to overwrite an error or a custom response with an OK packet. */ - if (is_error() || is_disabled()) + if (unlikely(is_error() || is_disabled())) return; /* When running a bulk operation, m_status will be DA_OK for the first @@ -377,7 +377,7 @@ Diagnostics_area::set_eof_status(THD *thd) In production, refuse to overwrite an error or a custom response with an EOF packet. */ - if (is_error() || is_disabled()) + if (unlikely(is_error() || is_disabled())) return; /* diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index 15c6cc57efb..3b6b5993073 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -270,10 +270,11 @@ my_bool Expression_cache_tmptable::put_value(Item *value) *(items.head_ref())= value; fill_record(table_thd, cache_table, cache_table->field, items, TRUE, TRUE); - if (table_thd->is_error()) + if (unlikely(table_thd->is_error())) goto err;; - if ((error= cache_table->file->ha_write_tmp_row(cache_table->record[0]))) + if (unlikely((error= + cache_table->file->ha_write_tmp_row(cache_table->record[0])))) { /* create_myisam_from_heap will generate error if needed */ if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP)) diff --git a/sql/sql_get_diagnostics.cc b/sql/sql_get_diagnostics.cc index e7ab6cc3c75..6a3cec79160 100644 --- a/sql/sql_get_diagnostics.cc +++ b/sql/sql_get_diagnostics.cc @@ -69,7 +69,7 @@ Sql_cmd_get_diagnostics::execute(THD *thd) const char *sqlstate= new_stmt_da.get_sqlstate(); /* In case of a fatal error, set it into the original DA.*/ - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) { save_stmt_da->set_error_status(sql_errno, message, sqlstate, NULL); DBUG_RETURN(true); @@ -81,7 +81,7 @@ Sql_cmd_get_diagnostics::execute(THD *thd) message); /* Appending might have failed. */ - if (! (rv= thd->is_error())) + if (unlikely(!(rv= thd->is_error()))) thd->get_stmt_da()->set_ok_status(0, 0, NULL); DBUG_RETURN(rv); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index ddc9c4a99d7..faf9fcbe906 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -195,13 +195,14 @@ static void mysql_ha_close_childs(THD *thd, TABLE_LIST *current_table_list, static void mysql_ha_close_table(SQL_HANDLER *handler) { + DBUG_ENTER("mysql_ha_close_table"); THD *thd= handler->thd; TABLE *table= handler->table; TABLE_LIST *current_table_list= NULL, *next_global; /* check if table was already closed */ if (!table) - return; + DBUG_VOID_RETURN; if ((next_global= table->file->get_next_global_for_child())) current_table_list= next_global->parent_l; @@ -232,6 +233,7 @@ static void mysql_ha_close_table(SQL_HANDLER *handler) } my_free(handler->lock); handler->init(); + DBUG_VOID_RETURN; } /* @@ -345,7 +347,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) error= (thd->open_temporary_tables(tables) || open_tables(thd, &tables, &counter, 0)); - if (error) + if (unlikely(error)) goto err; table= tables->table; @@ -371,7 +373,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* The ticket returned is within a savepoint. Make a copy. */ error= thd->mdl_context.clone_ticket(&table_list->mdl_request); table_list->table->mdl_ticket= table_list->mdl_request.ticket; - if (error) + if (unlikely(error)) goto err; } } @@ -426,8 +428,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) thd->set_n_backup_active_arena(&sql_handler->arena, &backup_arena); error= table->fill_item_list(&sql_handler->fields); thd->restore_active_arena(&sql_handler->arena, &backup_arena); - - if (error) + if (unlikely(error)) goto err; /* Always read all columns */ @@ -619,7 +620,7 @@ static SQL_HANDLER *mysql_ha_find_handler(THD *thd, const LEX_CSTRING *name) static bool mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, Item *cond, bool in_prepare) { THD *thd= handler->thd; @@ -661,6 +662,18 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, Item *item; key_part_map keypart_map; uint key_len; + const KEY *c_key= table->s->key_info + handler->keyno; + + if ((c_key->flags & HA_SPATIAL) || + c_key->algorithm == HA_KEY_ALG_FULLTEXT || + (ha_rkey_mode != HA_READ_KEY_EXACT && + (table->file->index_flags(handler->keyno, 0, TRUE) & + (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), keyinfo->name); + return 1; + } if (key_expr->elements > keyinfo->user_defined_key_parts) { @@ -668,6 +681,16 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, keyinfo->user_defined_key_parts); return 1; } + + if (key_expr->elements < keyinfo->user_defined_key_parts && + (table->file->index_flags(handler->keyno, 0, TRUE) & + HA_ONLY_WHOLE_INDEX)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), keyinfo->name); + return 1; + } + for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++) { my_bitmap_map *old_map; @@ -838,11 +861,12 @@ retry: goto retry; } - if (lock_error) + if (unlikely(lock_error)) goto err0; // mysql_lock_tables() printed error message already } - if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 0)) + if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, + ha_rkey_mode, cond, 0)) goto err; mode= handler->mode; keyno= handler->keyno; @@ -880,14 +904,14 @@ retry: case RFIRST: if (keyname) { - if (!(error= table->file->ha_index_or_rnd_end()) && - !(error= table->file->ha_index_init(keyno, 1))) + if (likely(!(error= table->file->ha_index_or_rnd_end())) && + likely(!(error= table->file->ha_index_init(keyno, 1)))) error= table->file->ha_index_first(table->record[0]); } else { - if (!(error= table->file->ha_index_or_rnd_end()) && - !(error= table->file->ha_rnd_init(1))) + if (likely(!(error= table->file->ha_index_or_rnd_end())) && + likely(!(error= table->file->ha_rnd_init(1)))) error= table->file->ha_rnd_next(table->record[0]); } mode= RNEXT; @@ -906,8 +930,8 @@ retry: /* else fall through */ case RLAST: DBUG_ASSERT(keyname != 0); - if (!(error= table->file->ha_index_or_rnd_end()) && - !(error= table->file->ha_index_init(keyno, 1))) + if (likely(!(error= table->file->ha_index_or_rnd_end())) && + likely(!(error= table->file->ha_index_init(keyno, 1)))) error= table->file->ha_index_last(table->record[0]); mode=RPREV; break; @@ -921,13 +945,13 @@ retry: { DBUG_ASSERT(keyname != 0); - if (!(key= (uchar*) thd->calloc(ALIGN_SIZE(handler->key_len)))) + if (unlikely(!(key= (uchar*) thd->calloc(ALIGN_SIZE(handler->key_len))))) goto err; - if ((error= table->file->ha_index_or_rnd_end())) + if (unlikely((error= table->file->ha_index_or_rnd_end()))) break; key_copy(key, table->record[0], table->key_info + keyno, handler->key_len); - if (!(error= table->file->ha_index_init(keyno, 1))) + if (unlikely(!(error= table->file->ha_index_init(keyno, 1)))) error= table->file->ha_index_read_map(table->record[0], key, handler->keypart_map, ha_rkey_mode); @@ -940,10 +964,8 @@ retry: goto err; } - if (error) + if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { /* Don't give error in the log file for some expected problems */ @@ -1003,14 +1025,16 @@ err0: SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, Item *cond) + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, + Item *cond) { SQL_HANDLER *handler; DBUG_ENTER("mysql_ha_read_prepare"); if (!(handler= mysql_ha_find_handler(thd, &tables->alias))) DBUG_RETURN(0); tables->table= handler->table; // This is used by fix_fields - if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1)) + if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, + ha_rkey_mode, cond, 1)) DBUG_RETURN(0); DBUG_RETURN(handler); } diff --git a/sql/sql_handler.h b/sql/sql_handler.h index ffefec91fad..4c16f7e5c57 100644 --- a/sql/sql_handler.h +++ b/sql/sql_handler.h @@ -80,5 +80,6 @@ void mysql_ha_rm_temporary_tables(THD *thd); SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, Item *cond); + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, + Item *cond); #endif diff --git a/sql/sql_help.cc b/sql/sql_help.cc index da38a2caf94..085e54dbc90 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -618,8 +618,9 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, table->covering_keys.clear_all(); SQL_SELECT *res= make_select(table, 0, 0, cond, 0, 0, error); - if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) || - (res && res->quick && res->quick->reset())) + if (unlikely(*error) || + (likely(res) && unlikely(res->check_quick(thd, 0, HA_POS_ERROR))) || + (likely(res) && res->quick && unlikely(res->quick->reset()))) { delete res; res=0; @@ -658,7 +659,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, size_t mlen, pfname->charset()), new (mem_root) Item_string_ascii(thd, "\\"), FALSE); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) return 0; // OOM return prepare_simple_select(thd, cond, table, error); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 109f4124ce3..a1d7f0f907c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -89,7 +89,7 @@ static int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, LEX_STRING query, bool ignore, bool log_on); static void end_delayed_insert(THD *thd); pthread_handler_t handle_delayed_insert(void *arg); -static void unlink_blobs(register TABLE *table); +static void unlink_blobs(TABLE *table); #endif static bool check_view_insertability(THD *thd, TABLE_LIST *view); @@ -749,12 +749,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table_list->table_name.str); DBUG_RETURN(TRUE); } - /* - mark the table_list as a target for insert, to skip the DT/view prepare phase - for correct access rights checks - TODO: remove this hack - */ - table_list->skip_prepare_derived= TRUE; if (table_list->lock_type == TL_WRITE_DELAYED) { @@ -963,8 +957,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, */ restore_record(table,s->default_values); // Get empty record table->reset_default_fields(); - if (fill_record_n_invoke_before_triggers(thd, table, fields, *values, 0, - TRG_EVENT_INSERT)) + if (unlikely(fill_record_n_invoke_before_triggers(thd, table, fields, + *values, 0, + TRG_EVENT_INSERT))) { if (values_list.elements != 1 && ! thd->is_error()) { @@ -987,7 +982,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, INSERT INTO t1 VALUES (values) */ if (thd->lex->used_tables || // Column used in values() - table->s->visible_fields != table->s->fields) + table->s->visible_fields != table->s->fields) restore_record(table,s->default_values); // Get empty record else { @@ -1008,9 +1003,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } } table->reset_default_fields(); - if (fill_record_n_invoke_before_triggers(thd, table, - table->field_to_fill(), - *values, 0, TRG_EVENT_INSERT)) + if (unlikely(fill_record_n_invoke_before_triggers(thd, table, + table-> + field_to_fill(), + *values, 0, + TRG_EVENT_INSERT))) { if (values_list.elements != 1 && ! thd->is_error()) { @@ -1023,16 +1020,16 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } /* - with triggers a field can get a value *conditionally*, so we have to repeat - has_no_default_value() check for every row + with triggers a field can get a value *conditionally*, so we have to + repeat has_no_default_value() check for every row */ if (table->triggers && table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE)) { for (Field **f=table->field ; *f ; f++) { - if (!(*f)->has_explicit_value() && - has_no_default_value(thd, *f, table_list)) + if (unlikely(!(*f)->has_explicit_value() && + has_no_default_value(thd, *f, table_list))) { error= 1; goto values_loop_end; @@ -1064,7 +1061,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, else #endif error=write_record(thd, table ,&info); - if (error) + if (unlikely(error)) break; thd->get_stmt_da()->inc_current_row_for_warning(); } @@ -1081,9 +1078,9 @@ values_loop_end: user */ #ifndef EMBEDDED_LIBRARY - if (lock_type == TL_WRITE_DELAYED) + if (unlikely(lock_type == TL_WRITE_DELAYED)) { - if (!error) + if (likely(!error)) { info.copied=values_list.elements; end_delayed_insert(thd); @@ -1097,7 +1094,8 @@ values_loop_end: auto_inc values from the delayed_insert thread as they share TABLE. */ table->file->ha_release_auto_increment(); - if (using_bulk_insert && table->file->ha_end_bulk_insert() && !error) + if (using_bulk_insert && unlikely(table->file->ha_end_bulk_insert()) && + !error) { table->file->print_error(my_errno,MYF(0)); error=1; @@ -1107,7 +1105,7 @@ values_loop_end: transactional_table= table->file->has_transactions(); - if ((changed= (info.copied || info.deleted || info.updated))) + if (likely(changed= (info.copied || info.deleted || info.updated))) { /* Invalidate the table in the query cache if something changed. @@ -1212,7 +1210,7 @@ values_loop_end: (!table->triggers || !table->triggers->has_delete_triggers())) table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); - if (error) + if (unlikely(error)) goto abort; if (thd->lex->analyze_stmt) { @@ -1579,7 +1577,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, { Item *fake_conds= 0; TABLE_LIST *duplicate; - if ((duplicate= unique_table(thd, table_list, table_list->next_global, 1))) + if ((duplicate= unique_table(thd, table_list, table_list->next_global, + CHECK_DUP_ALLOW_DIFFERENT_ALIAS))) { update_non_unique_table_error(table_list, "INSERT", duplicate); DBUG_RETURN(TRUE); @@ -1692,7 +1691,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (info->handle_duplicates == DUP_REPLACE || info->handle_duplicates == DUP_UPDATE) { - while ((error=table->file->ha_write_row(table->record[0]))) + while (unlikely(error=table->file->ha_write_row(table->record[0]))) { uint key_nr; /* @@ -1725,7 +1724,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) } goto err; } - if ((int) (key_nr = table->file->get_dup_key(error)) < 0) + if (unlikely((int) (key_nr = table->file->get_dup_key(error)) < 0)) { error= HA_ERR_FOUND_DUPP_KEY; /* Database can't find key */ goto err; @@ -1836,8 +1835,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) info->touched++; if (different_records) { - if ((error=table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(error=table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) { if (info->ignore && @@ -1935,11 +1934,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) bitmap_set_bit(table->write_set, table->vers_start_field()->field_index); table->vers_start_field()->store(0, false); } - if ((error=table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely(error= table->file->ha_update_row(table->record[1], + table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME) goto err; - if (error != HA_ERR_RECORD_IS_THE_SAME) + if (likely(!error)) { info->deleted++; if (table->versioned(VERS_TIMESTAMP)) @@ -1947,12 +1946,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) store_record(table, record[2]); error= vers_insert_history_row(table); restore_record(table, record[2]); - if (error) + if (unlikely(error)) goto err; } } else - error= 0; + error= 0; // error was HA_ERR_RECORD_IS_THE_SAME thd->record_first_successful_insert_id_in_cur_stmt(table->file->insert_id_for_cur_row); /* Since we pretend that we have done insert we should call @@ -1979,7 +1978,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->record[0]); restore_record(table,insert_values); } - if (error) + if (unlikely(error)) goto err; if (!table->versioned(VERS_TIMESTAMP)) info->deleted++; @@ -2019,7 +2018,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) table->write_set != save_write_set) table->column_bitmaps_set(save_read_set, save_write_set); } - else if ((error=table->file->ha_write_row(table->record[0]))) + else if (unlikely((error=table->file->ha_write_row(table->record[0])))) { DEBUG_SYNC(thd, "write_row_noreplace"); if (!info->ignore || @@ -2606,11 +2605,12 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) share->default_fields) { bool error_reported= FALSE; - if (!(copy->def_vcol_set= (MY_BITMAP*) alloc_root(client_thd->mem_root, - sizeof(MY_BITMAP)))) + if (unlikely(!(copy->def_vcol_set= + (MY_BITMAP*) alloc_root(client_thd->mem_root, + sizeof(MY_BITMAP))))) goto error; - - if (parse_vcol_defs(client_thd, client_thd->mem_root, copy, &error_reported)) + if (unlikely(parse_vcol_defs(client_thd, client_thd->mem_root, copy, + &error_reported))) goto error; } @@ -3198,7 +3198,7 @@ pthread_handler_t handle_delayed_insert(void *arg) /* Remove all pointers to data for blob fields so that original table doesn't try to free them */ -static void unlink_blobs(register TABLE *table) +static void unlink_blobs(TABLE *table) { for (Field **ptr=table->field ; *ptr ; ptr++) { @@ -3209,7 +3209,7 @@ static void unlink_blobs(register TABLE *table) /* Free blobs stored in current row */ -static void free_delayed_insert_blobs(register TABLE *table) +static void free_delayed_insert_blobs(TABLE *table) { for (Field **ptr=table->field ; *ptr ; ptr++) { @@ -3221,7 +3221,7 @@ static void free_delayed_insert_blobs(register TABLE *table) /* set value field for blobs to point to data in record */ -static void set_delayed_insert_blobs(register TABLE *table) +static void set_delayed_insert_blobs(TABLE *table) { for (Field **ptr=table->field ; *ptr ; ptr++) { @@ -3362,7 +3362,7 @@ bool Delayed_insert::handle_inserts(void) thd.clear_error(); // reset error for binlog tmp_error= 0; - if (table->vfield) + if (unlikely(table->vfield)) { /* Virtual fields where not calculated by caller as the temporary @@ -3373,7 +3373,7 @@ bool Delayed_insert::handle_inserts(void) VCOL_UPDATE_FOR_WRITE); } - if (tmp_error || write_record(&thd, table, &info)) + if (unlikely(tmp_error) || unlikely(write_record(&thd, table, &info))) { info.error_count++; // Ignore errors thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status); @@ -3420,7 +3420,7 @@ bool Delayed_insert::handle_inserts(void) mysql_cond_broadcast(&cond_client); // If waiting clients THD_STAGE_INFO(&thd, stage_reschedule); mysql_mutex_unlock(&mutex); - if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) + if (unlikely((error=table->file->extra(HA_EXTRA_NO_CACHE)))) { /* This should never happen */ table->file->print_error(error,MYF(0)); @@ -3472,7 +3472,7 @@ bool Delayed_insert::handle_inserts(void) thd.binlog_flush_pending_rows_event(TRUE, has_trans)) goto err; - if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) + if (unlikely((error=table->file->extra(HA_EXTRA_NO_CACHE)))) { // This shouldn't happen table->file->print_error(error,MYF(0)); sql_print_error("%s", thd.get_stmt_da()->message()); @@ -3781,7 +3781,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) 0 OK */ -int select_insert::prepare2(void) +int select_insert::prepare2(JOIN *) { DBUG_ENTER("select_insert::prepare2"); if (thd->lex->current_select->options & OPTION_BUFFER_RESULT && @@ -3825,15 +3825,16 @@ int select_insert::send_data(List<Item> &values) unit->offset_limit_cnt--; DBUG_RETURN(0); } - if (thd->killed == ABORT_QUERY) + if (unlikely(thd->killed == ABORT_QUERY)) DBUG_RETURN(0); thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields store_values(values); - if (table->default_field && table->update_default_fields(0, info.ignore)) + if (table->default_field && + unlikely(table->update_default_fields(0, info.ignore))) DBUG_RETURN(1); thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; - if (thd->is_error()) + if (unlikely(thd->is_error())) { table->auto_increment_field_not_null= FALSE; DBUG_RETURN(1); @@ -3854,7 +3855,7 @@ int select_insert::send_data(List<Item> &values) table->vers_write= table->versioned(); table->auto_increment_field_not_null= FALSE; - if (!error) + if (likely(!error)) { if (table->triggers || info.handle_duplicates == DUP_UPDATE) { @@ -3913,18 +3914,18 @@ bool select_insert::prepare_eof() DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'", trans_table, table->file->table_type())); - error = IF_WSREP((thd->wsrep_conflict_state == MUST_ABORT || - thd->wsrep_conflict_state == CERT_FAILURE) ? -1 :, ) - (thd->locked_tables_mode <= LTM_LOCK_TABLES ? - table->file->ha_end_bulk_insert() : 0); + error= (IF_WSREP((thd->wsrep_conflict_state == MUST_ABORT || + thd->wsrep_conflict_state == CERT_FAILURE) ? -1 :, ) + (thd->locked_tables_mode <= LTM_LOCK_TABLES ? + table->file->ha_end_bulk_insert() : 0)); - if (!error && thd->is_error()) + if (likely(!error) && unlikely(thd->is_error())) error= thd->get_stmt_da()->sql_errno(); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); - if ((changed= (info.copied || info.deleted || info.updated))) + if (likely((changed= (info.copied || info.deleted || info.updated)))) { /* We must invalidate the table in the query cache before binlog writing @@ -3948,10 +3949,10 @@ bool select_insert::prepare_eof() ha_autocommit_or_rollback() is issued below. */ if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) && - (!error || thd->transaction.stmt.modified_non_trans_table)) + (likely(!error) || thd->transaction.stmt.modified_non_trans_table)) { int errcode= 0; - if (!error) + if (likely(!error)) thd->clear_error(); else errcode= query_error_code(thd, killed_status == NOT_KILLED); @@ -3965,7 +3966,7 @@ bool select_insert::prepare_eof() } table->file->ha_release_auto_increment(); - if (error) + if (unlikely(error)) { table->file->print_error(error,MYF(0)); DBUG_RETURN(true); @@ -4277,9 +4278,9 @@ TABLE *select_create::create_table_from_items(THD *thd, else create_table->table= 0; // Create failed - if (!(table= create_table->table)) + if (unlikely(!(table= create_table->table))) { - if (!thd->is_error()) // CREATE ... IF NOT EXISTS + if (likely(!thd->is_error())) // CREATE ... IF NOT EXISTS my_ok(thd); // succeed, but did nothing DBUG_RETURN(NULL); } @@ -4293,8 +4294,8 @@ TABLE *select_create::create_table_from_items(THD *thd, since it won't wait for the table lock (we have exclusive metadata lock on the table) and thus can't get aborted. */ - if (! ((*lock)= mysql_lock_tables(thd, &table, 1, 0)) || - hooks->postlock(&table, 1)) + if (unlikely(!((*lock)= mysql_lock_tables(thd, &table, 1, 0)) || + hooks->postlock(&table, 1))) { /* purecov: begin tested */ /* @@ -4364,14 +4365,15 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u) create_table->next_global= save_next_global; - if (error) + if (unlikely(error)) return error; TABLE const *const table = *tables; if (thd->is_current_stmt_binlog_format_row() && !table->s->tmp_table) { - if (int error= ptr->binlog_show_create_table(tables, count)) + int error; + if (unlikely((error= ptr->binlog_show_create_table(tables, count)))) return error; } return 0; @@ -4579,17 +4581,17 @@ bool select_create::send_eof() #ifdef WITH_WSREP if (WSREP_ON) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state != NO_CONFLICT) { WSREP_DEBUG("select_create commit failed, thd: %lld err: %d %s", (longlong) thd->thread_id, thd->wsrep_conflict_state, thd->query()); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); abort_result_set(); DBUG_RETURN(true); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ } diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index fb8660aa79d..53c5e992ca9 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -2248,7 +2248,7 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) goto finish2; /* Prepare to retrieve all records of the joined table */ - if ((error= join_tab_scan->open())) + if (unlikely((error= join_tab_scan->open()))) { /* TODO: if we get here, we will assert in net_send_statement(). Add test @@ -2259,10 +2259,9 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last) while (!(error= join_tab_scan->next())) { - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { /* The user has aborted the execution of the query */ - join->thd->send_kill_message(); rc= NESTED_LOOP_KILLED; goto finish; } @@ -2411,7 +2410,7 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr) DBUG_RETURN(rc); } } - else if (join->thd->is_error()) + else if (unlikely(join->thd->is_error())) rc= NESTED_LOOP_ERROR; DBUG_RETURN(rc); } @@ -2533,10 +2532,9 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last) for ( ; cnt; cnt--) { - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { /* The user has aborted the execution of the query */ - join->thd->send_kill_message(); rc= NESTED_LOOP_KILLED; goto finish; } @@ -3392,7 +3390,7 @@ int JOIN_TAB_SCAN::next() while (!err && select && (skip_rc= select->skip_record(thd)) <= 0) { - if (thd->check_killed() || skip_rc < 0) + if (unlikely(thd->check_killed()) || skip_rc < 0) return 1; /* Move to the next record if the last retrieved record does not diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 93810d2041c..779b6d9c3c1 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -31,6 +31,7 @@ #include "sql_select.h" #include "sql_cte.h" #include "sql_signal.h" +#include "sql_partition.h" void LEX::parse_error(uint err_number) @@ -39,9 +40,6 @@ void LEX::parse_error(uint err_number) } -static int lex_one_token(YYSTYPE *yylval, THD *thd); - - /** LEX_STRING constant for null-string to be used in parser and other places. */ @@ -125,7 +123,7 @@ const char * index_hint_type_name[] = inline int lex_casecmp(const char *s, const char *t, uint len) { while (len-- != 0 && - to_upper_lex[(uchar) *s++] == to_upper_lex[(uchar) *t++]) ; + to_upper_lex[(uchar) *s++] == to_upper_lex[(uchar) *t++]) ; return (int) len+1; } @@ -146,7 +144,7 @@ void lex_init(void) void lex_free(void) -{ // Call this when daemon ends +{ // Call this when daemon ends DBUG_ENTER("lex_free"); DBUG_VOID_RETURN; } @@ -189,14 +187,14 @@ init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex) thd->lex= lex; lex_start(thd); context->init(); - if ((!(table_ident= new Table_ident(thd, - &table->s->db, - &table->s->table_name, - TRUE))) || - (!(table_list= select_lex->add_table_to_list(thd, - table_ident, - NULL, - 0)))) + if (unlikely((!(table_ident= new Table_ident(thd, + &table->s->db, + &table->s->table_name, + TRUE)))) || + (unlikely(!(table_list= select_lex->add_table_to_list(thd, + table_ident, + NULL, + 0))))) return TRUE; context->resolve_in_table_list_only(table_list); lex->use_only_table_context= TRUE; @@ -251,8 +249,8 @@ st_parsing_options::reset() */ bool Lex_input_stream::init(THD *thd, - char* buff, - size_t length) + char* buff, + size_t length) { DBUG_EXECUTE_IF("bug42064_simulate_oom", DBUG_SET("+d,simulate_out_of_memory");); @@ -284,7 +282,6 @@ void Lex_input_stream::reset(char *buffer, size_t length) { yylineno= 1; - yylval= NULL; lookahead_token= -1; lookahead_yylval= NULL; m_ptr= buffer; @@ -420,32 +417,18 @@ void Lex_input_stream::body_utf8_append(const char *ptr) operation. */ -void Lex_input_stream::body_utf8_append_ident(THD *thd, - const LEX_CSTRING *txt, - const char *end_ptr) +void +Lex_input_stream::body_utf8_append_ident(THD *thd, + const Lex_string_with_metadata_st *txt, + const char *end_ptr) { if (!m_cpp_utf8_processed_ptr) return; LEX_CSTRING utf_txt; - CHARSET_INFO *txt_cs= thd->charset(); - - if (!my_charset_same(txt_cs, &my_charset_utf8_general_ci)) - { - LEX_STRING to; - thd->convert_string(&to, - &my_charset_utf8_general_ci, - txt->str, (uint) txt->length, - txt_cs); - utf_txt.str= to.str; - utf_txt.length= to.length; - - } - else - utf_txt= *txt; + thd->make_text_string_sys(&utf_txt, txt); // QQ: check return value? /* NOTE: utf_txt.length is in bytes, not in symbols. */ - memcpy(m_body_utf8_ptr, utf_txt.str, utf_txt.length); m_body_utf8_ptr += utf_txt.length; *m_body_utf8_ptr= 0; @@ -669,11 +652,11 @@ void lex_start(THD *thd) void LEX::start(THD *thd_arg) { DBUG_ENTER("LEX::start"); - DBUG_PRINT("info", ("This: %p thd_arg->lex: %p thd_arg->stmt_lex: %p", - this, thd_arg->lex, thd_arg->stmt_lex)); + DBUG_PRINT("info", ("This: %p thd_arg->lex: %p", this, thd_arg->lex)); thd= unit.thd= thd_arg; - + stmt_lex= this; // default, should be rewritten for VIEWs And CTEs + DBUG_ASSERT(!explain); context_stack.empty(); @@ -842,23 +825,27 @@ Yacc_state::~Yacc_state() } } -static int find_keyword(Lex_input_stream *lip, uint len, bool function) +int Lex_input_stream::find_keyword(Lex_ident_cli_st *kwd, + uint len, bool function) { - const char *tok= lip->get_tok_start(); + const char *tok= m_tok_start; SYMBOL *symbol= get_hash_symbol(tok, len, function); if (symbol) { - lip->yylval->symbol.symbol=symbol; - lip->yylval->symbol.str= (char*) tok; - lip->yylval->symbol.length=len; + kwd->set_keyword(tok, len); + DBUG_ASSERT(tok >= get_buf()); + DBUG_ASSERT(tok < get_end_of_query()); if ((symbol->tok == NOT_SYM) && - (lip->m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE)) + (m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE)) return NOT2_SYM; - if ((symbol->tok == OR_OR_SYM) && - !(lip->m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT)) - return OR2_SYM; + if ((symbol->tok == OR2_SYM) && + (m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT)) + { + return (m_thd->variables.sql_mode & MODE_ORACLE) ? + ORACLE_CONCAT_SYM : MYSQL_CONCAT_SYM; + } return symbol->tok; } @@ -955,54 +942,19 @@ bool is_native_function_with_warn(THD *thd, const LEX_CSTRING *name) /* make a copy of token before ptr and set yytoklen */ -static LEX_CSTRING get_token(Lex_input_stream *lip, uint skip, uint length) +LEX_CSTRING Lex_input_stream::get_token(uint skip, uint length) { LEX_CSTRING tmp; - lip->yyUnget(); // ptr points now after last token char + yyUnget(); // ptr points now after last token char tmp.length= length; - tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length); + tmp.str= m_thd->strmake(m_tok_start + skip, tmp.length); - lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip; - lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length; + m_cpp_text_start= m_cpp_tok_start + skip; + m_cpp_text_end= m_cpp_text_start + tmp.length; return tmp; } -/* - todo: - There are no dangerous charsets in mysql for function - get_quoted_token yet. But it should be fixed in the - future to operate multichar strings (like ucs2) -*/ - -static LEX_CSTRING get_quoted_token(Lex_input_stream *lip, - uint skip, - uint length, char quote) -{ - LEX_CSTRING tmp; - const char *from, *end; - char *to; - lip->yyUnget(); // ptr points now after last token char - tmp.length= length; - tmp.str= to= (char*) lip->m_thd->alloc(tmp.length+1); - from= lip->get_tok_start() + skip; - end= to+length; - - lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip; - lip->m_cpp_text_end= lip->m_cpp_text_start + length; - - for ( ; to != end; ) - { - if ((*to++= *from++) == quote) - { - from++; // Skip double quotes - lip->m_cpp_text_start++; - } - } - *to= 0; // End null for safety - return tmp; -} - static size_t my_unescape(CHARSET_INFO *cs, char *to, const char *str, const char *end, @@ -1078,16 +1030,16 @@ Lex_input_stream::unescape(CHARSET_INFO *cs, char *to, bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep, int pre_skip, int post_skip) { - reg1 uchar c; + uchar c; uint found_escape=0; CHARSET_INFO *cs= m_thd->charset(); + bool is_8bit= false; - dst->set_8bit(false); while (! eof()) { c= yyGet(); if (c & 0x80) - dst->set_8bit(true); + is_8bit= true; #ifdef USE_MB { int l; @@ -1102,10 +1054,10 @@ bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep, #endif if (c == '\\' && !(m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)) - { // Escaped character + { // Escaped character found_escape=1; if (eof()) - return true; + return true; yySkip(); } else if (c == sep) @@ -1113,7 +1065,7 @@ bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep, if (c == yyGet()) // Check if two separators in a row { found_escape=1; // duplicate. Remember for delete - continue; + continue; } else yyUnget(); @@ -1122,7 +1074,7 @@ bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep, const char *str, *end; char *to; - str= get_tok_start(); + str= m_tok_start; end= get_ptr(); /* Extract the text from the token */ str += pre_skip; @@ -1131,23 +1083,24 @@ bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep, if (!(to= (char*) m_thd->alloc((uint) (end - str) + 1))) { - dst->str= ""; // Sql_alloc has set error flag - dst->length= 0; - return true; + dst->set(&empty_clex_str, 0, '\0'); + return true; // Sql_alloc has set error flag } - dst->str= to; - m_cpp_text_start= get_cpp_tok_start() + pre_skip; + m_cpp_text_start= m_cpp_tok_start + pre_skip; m_cpp_text_end= get_cpp_ptr() - post_skip; if (!found_escape) { - memcpy(to, str, dst->length= (end - str)); - to[dst->length]= 0; + size_t len= (end - str); + memcpy(to, str, len); + to[len]= '\0'; + dst->set(to, len, is_8bit, '\0'); } else { - dst->length= unescape(cs, to, str, end, sep); + size_t len= unescape(cs, to, str, end, sep); + dst->set(to, len, is_8bit, '\0'); } return false; } @@ -1176,11 +1129,11 @@ static const uint unsigned_longlong_len=20; static inline uint int_token(const char *str,uint length) { - if (length < long_len) // quick normal case + if (length < long_len) // quick normal case return NUM; bool neg=0; - if (*str == '+') // Remove sign and pre-zeros + if (*str == '+') // Remove sign and pre-zeros { str++; length--; } @@ -1202,9 +1155,9 @@ static inline uint int_token(const char *str,uint length) { if (length == long_len) { - cmp= signed_long_str+1; - smaller=NUM; // If <= signed_long_str - bigger=LONG_NUM; // If >= signed_long_str + cmp= signed_long_str + 1; + smaller= NUM; // If <= signed_long_str + bigger= LONG_NUM; // If >= signed_long_str } else if (length < signed_longlong_len) return LONG_NUM; @@ -1212,8 +1165,8 @@ static inline uint int_token(const char *str,uint length) return DECIMAL_NUM; else { - cmp=signed_longlong_str+1; - smaller=LONG_NUM; // If <= signed_longlong_str + cmp= signed_longlong_str + 1; + smaller= LONG_NUM; // If <= signed_longlong_str bigger=DECIMAL_NUM; } } @@ -1259,34 +1212,34 @@ static inline uint int_token(const char *str,uint length) @retval Whether EOF reached before comment is closed. */ -bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted) +bool Lex_input_stream::consume_comment(int remaining_recursions_permitted) { - reg1 uchar c; - while (! lip->eof()) + uchar c; + while (!eof()) { - c= lip->yyGet(); + c= yyGet(); if (remaining_recursions_permitted > 0) { - if ((c == '/') && (lip->yyPeek() == '*')) + if ((c == '/') && (yyPeek() == '*')) { - lip->yySkip(); /* Eat asterisk */ - consume_comment(lip, remaining_recursions_permitted-1); + yySkip(); // Eat asterisk + consume_comment(remaining_recursions_permitted - 1); continue; } } if (c == '*') { - if (lip->yyPeek() == '/') + if (yyPeek() == '/') { - lip->yySkip(); /* Eat slash */ + yySkip(); // Eat slash return FALSE; } } if (c == '\n') - lip->yylineno++; + yylineno++; } return TRUE; @@ -1299,31 +1252,42 @@ bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted) @param yylval [out] semantic value of the token being parsed (yylval) @param thd THD - - MY_LEX_EOQ Found end of query - - MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number - (which can't be followed by a signed number) + - MY_LEX_EOQ Found end of query + - MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number + (which can't be followed by a signed number) */ int MYSQLlex(YYSTYPE *yylval, THD *thd) { - Lex_input_stream *lip= & thd->m_parser_state->m_lip; + return thd->m_parser_state->m_lip.lex_token(yylval, thd); +} + + +int ORAlex(YYSTYPE *yylval, THD *thd) +{ + return thd->m_parser_state->m_lip.lex_token(yylval, thd); +} + + +int Lex_input_stream::lex_token(YYSTYPE *yylval, THD *thd) +{ int token; - if (lip->lookahead_token >= 0) + if (lookahead_token >= 0) { /* The next token was already parsed in advance, return it. */ - token= lip->lookahead_token; - lip->lookahead_token= -1; - *yylval= *(lip->lookahead_yylval); - lip->lookahead_yylval= NULL; + token= lookahead_token; + lookahead_token= -1; + *yylval= *(lookahead_yylval); + lookahead_yylval= NULL; return token; } token= lex_one_token(yylval, thd); - lip->add_digest_token(token, yylval); + add_digest_token(token, yylval); switch(token) { case WITH: @@ -1335,7 +1299,7 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) which sql_yacc.yy can process. */ token= lex_one_token(yylval, thd); - lip->add_digest_token(token, yylval); + add_digest_token(token, yylval); switch(token) { case CUBE_SYM: return WITH_CUBE_SYM; @@ -1347,9 +1311,8 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) /* Save the token following 'WITH' */ - lip->lookahead_yylval= lip->yylval; - lip->yylval= NULL; - lip->lookahead_token= token; + lookahead_yylval= yylval; + lookahead_token= token; return WITH; } break; @@ -1360,7 +1323,7 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) * SELECT ... FOR SYSTEM_TIME ... . */ token= lex_one_token(yylval, thd); - lip->add_digest_token(token, yylval); + add_digest_token(token, yylval); switch(token) { case SYSTEM_TIME_SYM: return FOR_SYSTEM_TIME_SYM; @@ -1368,9 +1331,8 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) /* Save the token following 'FOR_SYM' */ - lip->lookahead_yylval= lip->yylval; - lip->yylval= NULL; - lip->lookahead_token= token; + lookahead_yylval= yylval; + lookahead_token= token; return FOR_SYM; } break; @@ -1379,16 +1341,15 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) thd->lex->current_select->parsing_place == IN_PART_FUNC) return VALUE_SYM; token= lex_one_token(yylval, thd); - lip->add_digest_token(token, yylval); + add_digest_token(token, yylval); switch(token) { case LESS_SYM: return VALUES_LESS_SYM; case IN_SYM: return VALUES_IN_SYM; default: - lip->lookahead_yylval= lip->yylval; - lip->yylval= NULL; - lip->lookahead_token= token; + lookahead_yylval= yylval; + lookahead_token= token; return VALUES; } break; @@ -1398,71 +1359,64 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd) return token; } -int ORAlex(YYSTYPE *yylval, THD *thd) -{ - return MYSQLlex(yylval, thd); -} -static int lex_one_token(YYSTYPE *yylval, THD *thd) +int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) { - reg1 uchar UNINIT_VAR(c); + uchar UNINIT_VAR(c); bool comment_closed; - int tokval, result_state; + int tokval; uint length; enum my_lex_states state; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; LEX *lex= thd->lex; CHARSET_INFO *const cs= thd->charset(); const uchar *const state_map= cs->state_map; const uchar *const ident_map= cs->ident_map; - lip->yylval=yylval; // The global state - - lip->start_token(); - state=lip->next_state; - lip->next_state=MY_LEX_OPERATOR_OR_IDENT; + start_token(); + state= next_state; + next_state= MY_LEX_OPERATOR_OR_IDENT; for (;;) { switch (state) { - case MY_LEX_OPERATOR_OR_IDENT: // Next is operator or keyword - case MY_LEX_START: // Start of token + case MY_LEX_OPERATOR_OR_IDENT: // Next is operator or keyword + case MY_LEX_START: // Start of token // Skip starting whitespace - while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP) + while(state_map[c= yyPeek()] == MY_LEX_SKIP) { - if (c == '\n') - lip->yylineno++; + if (c == '\n') + yylineno++; - lip->yySkip(); + yySkip(); } /* Start of real token */ - lip->restart_token(); - c= lip->yyGet(); + restart_token(); + c= yyGet(); state= (enum my_lex_states) state_map[c]; break; case MY_LEX_ESCAPE: - if (!lip->eof() && lip->yyGet() == 'N') - { // Allow \N as shortcut for NULL - yylval->lex_str.str=(char*) "\\N"; - yylval->lex_str.length=2; - return NULL_SYM; + if (!eof() && yyGet() == 'N') + { // Allow \N as shortcut for NULL + yylval->lex_str.str= (char*) "\\N"; + yylval->lex_str.length= 2; + return NULL_SYM; } /* Fall through */ - case MY_LEX_CHAR: // Unknown or single char token - case MY_LEX_SKIP: // This should not happen + case MY_LEX_CHAR: // Unknown or single char token + case MY_LEX_SKIP: // This should not happen if (c != ')') - lip->next_state= MY_LEX_START; // Allow signed numbers + next_state= MY_LEX_START; // Allow signed numbers return((int) c); case MY_LEX_MINUS_OR_COMMENT: - if (lip->yyPeek() == '-' && - (my_isspace(cs,lip->yyPeekn(1)) || - my_iscntrl(cs,lip->yyPeekn(1)))) + if (yyPeek() == '-' && + (my_isspace(cs,yyPeekn(1)) || + my_iscntrl(cs,yyPeekn(1)))) { state=MY_LEX_COMMENT; break; } - lip->next_state= MY_LEX_START; // Allow signed numbers + next_state= MY_LEX_START; // Allow signed numbers return((int) c); case MY_LEX_PLACEHOLDER: @@ -1472,13 +1426,13 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) its value in a query for the binlog, the query must stay grammatically correct. */ - lip->next_state= MY_LEX_START; // Allow signed numbers - if (lip->stmt_prepare_mode && !ident_map[(uchar) lip->yyPeek()]) + next_state= MY_LEX_START; // Allow signed numbers + if (stmt_prepare_mode && !ident_map[(uchar) yyPeek()]) return(PARAM_MARKER); return((int) c); case MY_LEX_COMMA: - lip->next_state= MY_LEX_START; // Allow signed numbers + next_state= MY_LEX_START; // Allow signed numbers /* Warning: This is a work around, to make the "remember_name" rule in @@ -1488,431 +1442,277 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) remember_name (see select_item) *before* actually parsing the first token of expr2. */ - lip->restart_token(); + restart_token(); return((int) c); case MY_LEX_IDENT_OR_NCHAR: { uint sep; - if (lip->yyPeek() != '\'') + if (yyPeek() != '\'') { - state= MY_LEX_IDENT; - break; + state= MY_LEX_IDENT; + break; } /* Found N'string' */ - lip->yySkip(); // Skip ' - if (lip->get_text(&yylval->lex_string_with_metadata, - (sep= lip->yyGetLast()), 2, 1)) + yySkip(); // Skip ' + if (get_text(&yylval->lex_string_with_metadata, (sep= yyGetLast()), 2, 1)) { - state= MY_LEX_CHAR; // Read char by char - break; + state= MY_LEX_CHAR; // Read char by char + break; } - lip->body_utf8_append(lip->m_cpp_text_start); - lip->body_utf8_append_escape(thd, &yylval->lex_string_with_metadata, + body_utf8_append(m_cpp_text_start); + body_utf8_append_escape(thd, &yylval->lex_string_with_metadata, national_charset_info, - lip->m_cpp_text_end, sep); + m_cpp_text_end, sep); return(NCHAR_STRING); } case MY_LEX_IDENT_OR_HEX: - if (lip->yyPeek() == '\'') - { // Found x'hex-number' - state= MY_LEX_HEX_NUMBER; - break; + if (yyPeek() == '\'') + { // Found x'hex-number' + state= MY_LEX_HEX_NUMBER; + break; } /* fall through */ case MY_LEX_IDENT_OR_BIN: - if (lip->yyPeek() == '\'') + if (yyPeek() == '\'') { // Found b'bin-number' state= MY_LEX_BIN_NUMBER; break; } /* fall through */ case MY_LEX_IDENT: - const char *start; -#if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(cs)) - { - result_state= IDENT_QUOTED; - int char_length= my_charlen(cs, lip->get_ptr() - 1, - lip->get_end_of_query()); - if (char_length <= 0) - { - state= MY_LEX_CHAR; - continue; - } - lip->skip_binary(char_length - 1); - - while (ident_map[c=lip->yyGet()]) - { - char_length= my_charlen(cs, lip->get_ptr() - 1, - lip->get_end_of_query()); - if (char_length <= 0) - break; - lip->skip_binary(char_length - 1); - } - } - else -#endif - { - for (result_state= c; - ident_map[(uchar) (c= lip->yyGet())]; - result_state|= c) - ; - /* If there were non-ASCII characters, mark that we must convert */ - result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; - } - length= lip->yyLength(); - start= lip->get_ptr(); - if (lip->ignore_space) - { - /* - If we find a space then this can't be an identifier. We notice this - below by checking start != lex->ptr. - */ - for (; state_map[(uchar) c] == MY_LEX_SKIP ; c= lip->yyGet()) - { - if (c == '\n') - lip->yylineno++; - } - } - if (start == lip->get_ptr() && c == '.' && - ident_map[(uchar) lip->yyPeek()]) - lip->next_state=MY_LEX_IDENT_SEP; - else - { // '(' must follow directly if function - lip->yyUnget(); - if ((tokval = find_keyword(lip, length, c == '('))) - { - lip->next_state= MY_LEX_START; // Allow signed numbers - return(tokval); // Was keyword - } - lip->yySkip(); // next state does a unget - } - yylval->lex_str=get_token(lip, 0, length); - - /* - Note: "SELECT _bla AS 'alias'" - _bla should be considered as a IDENT if charset haven't been found. - So we don't use MYF(MY_WME) with get_charset_by_csname to avoid - producing an error. - */ - - if (yylval->lex_str.str[0] == '_') - { - CHARSET_INFO *cs= get_charset_by_csname(yylval->lex_str.str + 1, - MY_CS_PRIMARY, MYF(0)); - if (cs) - { - yylval->charset= cs; - lip->m_underscore_cs= cs; - - lip->body_utf8_append(lip->m_cpp_text_start, - lip->get_cpp_tok_start() + length); - return(UNDERSCORE_CHARSET); - } - } - - lip->body_utf8_append(lip->m_cpp_text_start); - - lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end); - - return(result_state); // IDENT or IDENT_QUOTED + { + tokval= scan_ident_middle(thd, &yylval->ident_cli, + &yylval->charset, &state); + if (!tokval) + continue; + if (tokval == UNDERSCORE_CHARSET) + m_underscore_cs= yylval->charset; + return tokval; + } case MY_LEX_IDENT_SEP: // Found ident and now '.' - yylval->lex_str.str= (char*) lip->get_ptr(); + yylval->lex_str.str= (char*) get_ptr(); yylval->lex_str.length= 1; - c= lip->yyGet(); // should be '.' - lip->next_state= MY_LEX_IDENT_START; // Next is ident (not keyword) - if (!ident_map[(uchar) lip->yyPeek()]) // Probably ` or " - lip->next_state= MY_LEX_START; + c= yyGet(); // should be '.' + next_state= MY_LEX_IDENT_START; // Next is ident (not keyword) + if (!ident_map[(uchar) yyPeek()]) // Probably ` or " + next_state= MY_LEX_START; return((int) c); - case MY_LEX_NUMBER_IDENT: // number or ident which num-start - if (lip->yyGetLast() == '0') + case MY_LEX_NUMBER_IDENT: // number or ident which num-start + if (yyGetLast() == '0') { - c= lip->yyGet(); + c= yyGet(); if (c == 'x') { - while (my_isxdigit(cs,(c = lip->yyGet()))) ; - if ((lip->yyLength() >= 3) && !ident_map[c]) + while (my_isxdigit(cs, (c = yyGet()))) ; + if ((yyLength() >= 3) && !ident_map[c]) { /* skip '0x' */ - yylval->lex_str=get_token(lip, 2, lip->yyLength()-2); + yylval->lex_str= get_token(2, yyLength() - 2); return (HEX_NUM); } - lip->yyUnget(); + yyUnget(); state= MY_LEX_IDENT_START; break; } else if (c == 'b') { - while ((c= lip->yyGet()) == '0' || c == '1') + while ((c= yyGet()) == '0' || c == '1') ; - if ((lip->yyLength() >= 3) && !ident_map[c]) + if ((yyLength() >= 3) && !ident_map[c]) { /* Skip '0b' */ - yylval->lex_str= get_token(lip, 2, lip->yyLength()-2); + yylval->lex_str= get_token(2, yyLength() - 2); return (BIN_NUM); } - lip->yyUnget(); + yyUnget(); state= MY_LEX_IDENT_START; break; } - lip->yyUnget(); + yyUnget(); } - while (my_isdigit(cs, (c = lip->yyGet()))) ; + while (my_isdigit(cs, (c= yyGet()))) ; if (!ident_map[c]) - { // Can't be identifier - state=MY_LEX_INT_OR_REAL; - break; + { // Can't be identifier + state=MY_LEX_INT_OR_REAL; + break; } if (c == 'e' || c == 'E') { - // The following test is written this way to allow numbers of type 1e1 - if (my_isdigit(cs,lip->yyPeek()) || - (c=(lip->yyGet())) == '+' || c == '-') - { // Allow 1E+10 - if (my_isdigit(cs,lip->yyPeek())) // Number must have digit after sign - { - lip->yySkip(); - while (my_isdigit(cs,lip->yyGet())) ; - yylval->lex_str=get_token(lip, 0, lip->yyLength()); - return(FLOAT_NUM); - } - } - lip->yyUnget(); - } - // fall through - case MY_LEX_IDENT_START: // We come here after '.' - result_state= IDENT; -#if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(cs)) - { - result_state= IDENT_QUOTED; - while (ident_map[c=lip->yyGet()]) - { - int char_length= my_charlen(cs, lip->get_ptr() - 1, - lip->get_end_of_query()); - if (char_length <= 0) - break; - lip->skip_binary(char_length - 1); - } - } - else -#endif - { - for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c) - ; - /* If there were non-ASCII characters, mark that we must convert */ - result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; - } - if (c == '.' && ident_map[(uchar) lip->yyPeek()]) - lip->next_state=MY_LEX_IDENT_SEP;// Next is '.' - - yylval->lex_str= get_token(lip, 0, lip->yyLength()); - - lip->body_utf8_append(lip->m_cpp_text_start); - - lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end); - - return(result_state); - - case MY_LEX_USER_VARIABLE_DELIMITER: // Found quote char - { - uint double_quotes= 0; - char quote_char= c; // Used char - while ((c=lip->yyGet())) - { - int var_length= my_charlen(cs, lip->get_ptr() - 1, - lip->get_end_of_query()); - if (var_length == 1) - { - if (c == quote_char) - { - if (lip->yyPeek() != quote_char) - break; - c=lip->yyGet(); - double_quotes++; - continue; - } - } -#ifdef USE_MB - else if (var_length > 1) - { - lip->skip_binary(var_length - 1); + // The following test is written this way to allow numbers of type 1e1 + if (my_isdigit(cs, yyPeek()) || + (c=(yyGet())) == '+' || c == '-') + { // Allow 1E+10 + if (my_isdigit(cs, yyPeek())) // Number must have digit after sign + { + yySkip(); + while (my_isdigit(cs, yyGet())) ; + yylval->lex_str= get_token(0, yyLength()); + return(FLOAT_NUM); + } } -#endif + yyUnget(); } - if (double_quotes) - yylval->lex_str=get_quoted_token(lip, 1, - lip->yyLength() - double_quotes -1, - quote_char); - else - yylval->lex_str=get_token(lip, 1, lip->yyLength() -1); - if (c == quote_char) - lip->yySkip(); // Skip end ` - lip->next_state= MY_LEX_START; - - lip->body_utf8_append(lip->m_cpp_text_start); + // fall through + case MY_LEX_IDENT_START: // We come here after '.' + return scan_ident_start(thd, &yylval->ident_cli); - lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end); + case MY_LEX_USER_VARIABLE_DELIMITER: // Found quote char + return scan_ident_delimited(thd, &yylval->ident_cli); - return(IDENT_QUOTED); - } - case MY_LEX_INT_OR_REAL: // Complete int or incomplete real - if (c != '.' || lip->yyPeek() == '.') + case MY_LEX_INT_OR_REAL: // Complete int or incomplete real + if (c != '.' || yyPeek() == '.') { /* Found a complete integer number: - the number is either not followed by a dot at all, or - the number is followed by a double dot as in: FOR i IN 1..10 */ - yylval->lex_str=get_token(lip, 0, lip->yyLength()); - return int_token(yylval->lex_str.str, (uint) yylval->lex_str.length); + yylval->lex_str= get_token(0, yyLength()); + return int_token(yylval->lex_str.str, (uint) yylval->lex_str.length); } // fall through - case MY_LEX_REAL: // Incomplete real number - while (my_isdigit(cs,c = lip->yyGet())) ; + case MY_LEX_REAL: // Incomplete real number + while (my_isdigit(cs, c= yyGet())) ; if (c == 'e' || c == 'E') { - c = lip->yyGet(); - if (c == '-' || c == '+') - c = lip->yyGet(); // Skip sign - if (!my_isdigit(cs,c)) - { // No digit after sign - state= MY_LEX_CHAR; - break; - } - while (my_isdigit(cs,lip->yyGet())) ; - yylval->lex_str=get_token(lip, 0, lip->yyLength()); - return(FLOAT_NUM); + c= yyGet(); + if (c == '-' || c == '+') + c= yyGet(); // Skip sign + if (!my_isdigit(cs, c)) + { // No digit after sign + state= MY_LEX_CHAR; + break; + } + while (my_isdigit(cs, yyGet())) ; + yylval->lex_str= get_token(0, yyLength()); + return(FLOAT_NUM); } - yylval->lex_str=get_token(lip, 0, lip->yyLength()); + yylval->lex_str= get_token(0, yyLength()); return(DECIMAL_NUM); - case MY_LEX_HEX_NUMBER: // Found x'hexstring' - lip->yySkip(); // Accept opening ' - while (my_isxdigit(cs, (c= lip->yyGet()))) ; + case MY_LEX_HEX_NUMBER: // Found x'hexstring' + yySkip(); // Accept opening ' + while (my_isxdigit(cs, (c= yyGet()))) ; if (c != '\'') return(ABORT_SYM); // Illegal hex constant - lip->yySkip(); // Accept closing ' - length= lip->yyLength(); // Length of hexnum+3 + yySkip(); // Accept closing ' + length= yyLength(); // Length of hexnum+3 if ((length % 2) == 0) return(ABORT_SYM); // odd number of hex digits - yylval->lex_str=get_token(lip, - 2, // skip x' - length-3); // don't count x' and last ' + yylval->lex_str= get_token(2, // skip x' + length - 3); // don't count x' and last ' return HEX_STRING; case MY_LEX_BIN_NUMBER: // Found b'bin-string' - lip->yySkip(); // Accept opening ' - while ((c= lip->yyGet()) == '0' || c == '1') + yySkip(); // Accept opening ' + while ((c= yyGet()) == '0' || c == '1') ; if (c != '\'') return(ABORT_SYM); // Illegal hex constant - lip->yySkip(); // Accept closing ' - length= lip->yyLength(); // Length of bin-num + 3 - yylval->lex_str= get_token(lip, - 2, // skip b' - length-3); // don't count b' and last ' + yySkip(); // Accept closing ' + length= yyLength(); // Length of bin-num + 3 + yylval->lex_str= get_token(2, // skip b' + length - 3); // don't count b' and last ' return (BIN_NUM); - case MY_LEX_CMP_OP: // Incomplete comparison operator - lip->next_state= MY_LEX_START; // Allow signed numbers - if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP || - state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP) + case MY_LEX_CMP_OP: // Incomplete comparison operator + next_state= MY_LEX_START; // Allow signed numbers + if (state_map[(uchar) yyPeek()] == MY_LEX_CMP_OP || + state_map[(uchar) yyPeek()] == MY_LEX_LONG_CMP_OP) { - lip->yySkip(); - if ((tokval= find_keyword(lip, 2, 0))) + yySkip(); + if ((tokval= find_keyword(&yylval->kwd, 2, 0))) return(tokval); - lip->yyUnget(); + yyUnget(); } return(c); - case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator - lip->next_state= MY_LEX_START; - if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP || - state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP) + case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator + next_state= MY_LEX_START; + if (state_map[(uchar) yyPeek()] == MY_LEX_CMP_OP || + state_map[(uchar) yyPeek()] == MY_LEX_LONG_CMP_OP) { - lip->yySkip(); - if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP) + yySkip(); + if (state_map[(uchar) yyPeek()] == MY_LEX_CMP_OP) { - lip->yySkip(); - if ((tokval= find_keyword(lip, 3, 0))) + yySkip(); + if ((tokval= find_keyword(&yylval->kwd, 3, 0))) return(tokval); - lip->yyUnget(); + yyUnget(); } - if ((tokval= find_keyword(lip, 2, 0))) + if ((tokval= find_keyword(&yylval->kwd, 2, 0))) return(tokval); - lip->yyUnget(); + yyUnget(); } return(c); case MY_LEX_BOOL: - if (c != lip->yyPeek()) + if (c != yyPeek()) { - state=MY_LEX_CHAR; - break; + state= MY_LEX_CHAR; + break; } - lip->yySkip(); - tokval = find_keyword(lip,2,0); // Is a bool operator - lip->next_state= MY_LEX_START; // Allow signed numbers + yySkip(); + tokval= find_keyword(&yylval->kwd, 2, 0); // Is a bool operator + next_state= MY_LEX_START; // Allow signed numbers return(tokval); case MY_LEX_STRING_OR_DELIMITER: if (thd->variables.sql_mode & MODE_ANSI_QUOTES) { - state= MY_LEX_USER_VARIABLE_DELIMITER; - break; + state= MY_LEX_USER_VARIABLE_DELIMITER; + break; } /* " used for strings */ /* fall through */ - case MY_LEX_STRING: // Incomplete text string + case MY_LEX_STRING: // Incomplete text string { uint sep; - if (lip->get_text(&yylval->lex_string_with_metadata, - (sep= lip->yyGetLast()), 1, 1)) + if (get_text(&yylval->lex_string_with_metadata, (sep= yyGetLast()), 1, 1)) { - state= MY_LEX_CHAR; // Read char by char - break; + state= MY_LEX_CHAR; // Read char by char + break; } - CHARSET_INFO *strcs= lip->m_underscore_cs ? lip->m_underscore_cs : cs; - lip->body_utf8_append(lip->m_cpp_text_start); + CHARSET_INFO *strcs= m_underscore_cs ? m_underscore_cs : cs; + body_utf8_append(m_cpp_text_start); - lip->body_utf8_append_escape(thd, &yylval->lex_string_with_metadata, - strcs, lip->m_cpp_text_end, sep); - lip->m_underscore_cs= NULL; + body_utf8_append_escape(thd, &yylval->lex_string_with_metadata, + strcs, m_cpp_text_end, sep); + m_underscore_cs= NULL; return(TEXT_STRING); } - case MY_LEX_COMMENT: // Comment + case MY_LEX_COMMENT: // Comment lex->select_lex.options|= OPTION_FOUND_COMMENT; - while ((c = lip->yyGet()) != '\n' && c) ; - lip->yyUnget(); // Safety against eof - state = MY_LEX_START; // Try again + while ((c= yyGet()) != '\n' && c) ; + yyUnget(); // Safety against eof + state= MY_LEX_START; // Try again break; - case MY_LEX_LONG_COMMENT: /* Long C comment? */ - if (lip->yyPeek() != '*') + case MY_LEX_LONG_COMMENT: // Long C comment? + if (yyPeek() != '*') { - state=MY_LEX_CHAR; // Probable division - break; + state= MY_LEX_CHAR; // Probable division + break; } lex->select_lex.options|= OPTION_FOUND_COMMENT; /* Reject '/' '*', since we might need to turn off the echo */ - lip->yyUnget(); + yyUnget(); - lip->save_in_comment_state(); + save_in_comment_state(); - if (lip->yyPeekn(2) == '!' || - (lip->yyPeekn(2) == 'M' && lip->yyPeekn(3) == '!')) + if (yyPeekn(2) == '!' || + (yyPeekn(2) == 'M' && yyPeekn(3) == '!')) { - bool maria_comment_syntax= lip->yyPeekn(2) == 'M'; - lip->in_comment= DISCARD_COMMENT; + bool maria_comment_syntax= yyPeekn(2) == 'M'; + in_comment= DISCARD_COMMENT; /* Accept '/' '*' '!', but do not keep this marker. */ - lip->set_echo(FALSE); - lip->yySkipn(maria_comment_syntax ? 4 : 3); + set_echo(FALSE); + yySkipn(maria_comment_syntax ? 4 : 3); /* The special comment format is very strict: @@ -1923,24 +1723,24 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) 50114 -> 5.1.14 100000 -> 10.0.0 */ - if ( my_isdigit(cs, lip->yyPeekn(0)) - && my_isdigit(cs, lip->yyPeekn(1)) - && my_isdigit(cs, lip->yyPeekn(2)) - && my_isdigit(cs, lip->yyPeekn(3)) - && my_isdigit(cs, lip->yyPeekn(4)) + if ( my_isdigit(cs, yyPeekn(0)) + && my_isdigit(cs, yyPeekn(1)) + && my_isdigit(cs, yyPeekn(2)) + && my_isdigit(cs, yyPeekn(3)) + && my_isdigit(cs, yyPeekn(4)) ) { ulong version; uint length= 5; - char *end_ptr= (char*) lip->get_ptr()+length; + char *end_ptr= (char*) get_ptr() + length; int error; - if (my_isdigit(cs, lip->yyPeekn(5))) + if (my_isdigit(cs, yyPeekn(5))) { end_ptr++; // 6 digit number length++; } - version= (ulong) my_strtoll10(lip->get_ptr(), &end_ptr, &error); + version= (ulong) my_strtoll10(get_ptr(), &end_ptr, &error); /* MySQL-5.7 has new features and might have new SQL syntax that @@ -1952,31 +1752,31 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) (version < 50700 || version > 99999 || maria_comment_syntax)) { /* Accept 'M' 'm' 'm' 'd' 'd' */ - lip->yySkipn(length); + yySkipn(length); /* Expand the content of the special comment as real code */ - lip->set_echo(TRUE); + set_echo(TRUE); state=MY_LEX_START; break; /* Do not treat contents as a comment. */ } else { #ifdef WITH_WSREP - if (WSREP(thd) && version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE) - { - WSREP_DEBUG("consistency check: %s", thd->query()); - thd->wsrep_consistency_check= CONSISTENCY_CHECK_DECLARED; - lip->yySkipn(5); - lip->set_echo(TRUE); - state=MY_LEX_START; - break; /* Do not treat contents as a comment. */ - } + if (WSREP(thd) && version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE) + { + WSREP_DEBUG("consistency check: %s", thd->query()); + thd->wsrep_consistency_check= CONSISTENCY_CHECK_DECLARED; + yySkipn(5); + set_echo(TRUE); + state= MY_LEX_START; + break; /* Do not treat contents as a comment. */ + } #endif /* WITH_WSREP */ /* Patch and skip the conditional comment to avoid it being propagated infinitely (eg. to a slave). */ - char *pcom= lip->yyUnput(' '); - comment_closed= ! consume_comment(lip, 1); + char *pcom= yyUnput(' '); + comment_closed= ! consume_comment(1); if (! comment_closed) { *pcom= '!'; @@ -1988,16 +1788,16 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) { /* Not a version comment. */ state=MY_LEX_START; - lip->set_echo(TRUE); + set_echo(TRUE); break; } } else { - lip->in_comment= PRESERVE_COMMENT; - lip->yySkip(); // Accept / - lip->yySkip(); // Accept * - comment_closed= ! consume_comment(lip, 0); + in_comment= PRESERVE_COMMENT; + yySkip(); // Accept / + yySkip(); // Accept * + comment_closed= ! consume_comment(0); /* regular comments can have zero comments inside. */ } /* @@ -2011,140 +1811,364 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) /#!VERSI oned containing /# regular #/ is allowed #/ - Inside one versioned comment, another versioned comment - is treated as a regular discardable comment. It gets - no special parsing. + Inside one versioned comment, another versioned comment + is treated as a regular discardable comment. It gets + no special parsing. */ /* Unbalanced comments with a missing '*' '/' are a syntax error */ if (! comment_closed) return (ABORT_SYM); state = MY_LEX_START; // Try again - lip->restore_in_comment_state(); + restore_in_comment_state(); break; case MY_LEX_END_LONG_COMMENT: - if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/') + if ((in_comment != NO_COMMENT) && yyPeek() == '/') { /* Reject '*' '/' */ - lip->yyUnget(); + yyUnget(); /* Accept '*' '/', with the proper echo */ - lip->set_echo(lip->in_comment == PRESERVE_COMMENT); - lip->yySkipn(2); + set_echo(in_comment == PRESERVE_COMMENT); + yySkipn(2); /* And start recording the tokens again */ - lip->set_echo(TRUE); - lip->in_comment=NO_COMMENT; + set_echo(TRUE); + in_comment= NO_COMMENT; state=MY_LEX_START; } else - state=MY_LEX_CHAR; // Return '*' + state= MY_LEX_CHAR; // Return '*' break; - case MY_LEX_SET_VAR: // Check if ':=' - if (lip->yyPeek() != '=') + case MY_LEX_SET_VAR: // Check if ':=' + if (yyPeek() != '=') { - state=MY_LEX_CHAR; // Return ':' - break; + state= MY_LEX_CHAR; // Return ':' + break; } - lip->yySkip(); + yySkip(); return (SET_VAR); - case MY_LEX_SEMICOLON: // optional line terminator + case MY_LEX_SEMICOLON: // optional line terminator state= MY_LEX_CHAR; // Return ';' break; case MY_LEX_EOL: - if (lip->eof()) + if (eof()) { - lip->yyUnget(); // Reject the last '\0' - lip->set_echo(FALSE); - lip->yySkip(); - lip->set_echo(TRUE); + yyUnget(); // Reject the last '\0' + set_echo(FALSE); + yySkip(); + set_echo(TRUE); /* Unbalanced comments with a missing '*' '/' are a syntax error */ - if (lip->in_comment != NO_COMMENT) + if (in_comment != NO_COMMENT) return (ABORT_SYM); - lip->next_state=MY_LEX_END; // Mark for next loop + next_state= MY_LEX_END; // Mark for next loop return(END_OF_INPUT); } state=MY_LEX_CHAR; break; case MY_LEX_END: - lip->next_state=MY_LEX_END; - return(0); // We found end of input last time + next_state= MY_LEX_END; + return(0); // We found end of input last time /* Actually real shouldn't start with . but allow them anyhow */ case MY_LEX_REAL_OR_POINT: - if (my_isdigit(cs,(c= lip->yyPeek()))) - state = MY_LEX_REAL; // Real + if (my_isdigit(cs, (c= yyPeek()))) + state = MY_LEX_REAL; // Real else if (c == '.') { - lip->yySkip(); + yySkip(); return DOT_DOT_SYM; } else { - state= MY_LEX_IDENT_SEP; // return '.' - lip->yyUnget(); // Put back '.' + state= MY_LEX_IDENT_SEP; // return '.' + yyUnget(); // Put back '.' } break; - case MY_LEX_USER_END: // end '@' of user@hostname - switch (state_map[(uchar) lip->yyPeek()]) { + case MY_LEX_USER_END: // end '@' of user@hostname + switch (state_map[(uchar) yyPeek()]) { case MY_LEX_STRING: case MY_LEX_USER_VARIABLE_DELIMITER: case MY_LEX_STRING_OR_DELIMITER: - break; + break; case MY_LEX_USER_END: - lip->next_state=MY_LEX_SYSTEM_VAR; - break; + next_state= MY_LEX_SYSTEM_VAR; + break; default: - lip->next_state=MY_LEX_HOSTNAME; - break; + next_state= MY_LEX_HOSTNAME; + break; } - yylval->lex_str.str=(char*) lip->get_ptr(); - yylval->lex_str.length=1; + yylval->lex_str.str= (char*) get_ptr(); + yylval->lex_str.length= 1; return((int) '@'); - case MY_LEX_HOSTNAME: // end '@' of user@hostname - for (c=lip->yyGet() ; - my_isalnum(cs,c) || c == '.' || c == '_' || c == '$'; - c= lip->yyGet()) ; - yylval->lex_str=get_token(lip, 0, lip->yyLength()); + case MY_LEX_HOSTNAME: // end '@' of user@hostname + for (c= yyGet() ; + my_isalnum(cs, c) || c == '.' || c == '_' || c == '$'; + c= yyGet()) ; + yylval->lex_str= get_token(0, yyLength()); return(LEX_HOSTNAME); case MY_LEX_SYSTEM_VAR: - yylval->lex_str.str=(char*) lip->get_ptr(); - yylval->lex_str.length=1; - lip->yySkip(); // Skip '@' - lip->next_state= (state_map[(uchar) lip->yyPeek()] == - MY_LEX_USER_VARIABLE_DELIMITER ? - MY_LEX_OPERATOR_OR_IDENT : - MY_LEX_IDENT_OR_KEYWORD); + yylval->lex_str.str= (char*) get_ptr(); + yylval->lex_str.length= 1; + yySkip(); // Skip '@' + next_state= (state_map[(uchar) yyPeek()] == + MY_LEX_USER_VARIABLE_DELIMITER ? + MY_LEX_OPERATOR_OR_IDENT : + MY_LEX_IDENT_OR_KEYWORD); return((int) '@'); case MY_LEX_IDENT_OR_KEYWORD: /* - We come here when we have found two '@' in a row. - We should now be able to handle: - [(global | local | session) .]variable_name + We come here when we have found two '@' in a row. + We should now be able to handle: + [(global | local | session) .]variable_name */ + return scan_ident_sysvar(thd, &yylval->ident_cli); + } + } +} + + +bool Lex_input_stream::get_7bit_or_8bit_ident(THD *thd, uchar *last_char) +{ + uchar c; + CHARSET_INFO *const cs= thd->charset(); + const uchar *const ident_map= cs->ident_map; + bool is_8bit= false; + for ( ; ident_map[c= yyGet()]; ) + { + if (c & 0x80) + is_8bit= true; // will convert + } + *last_char= c; + return is_8bit; +} - for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) - ; - /* If there were non-ASCII characters, mark that we must convert */ - result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT; - - if (c == '.') - lip->next_state=MY_LEX_IDENT_SEP; - length= lip->yyLength(); - if (length == 0) - return(ABORT_SYM); // Names must be nonempty. - if ((tokval= find_keyword(lip, length,0))) - { - lip->yyUnget(); // Put back 'c' - return(tokval); // Was keyword - } - yylval->lex_str=get_token(lip, 0, length); - lip->body_utf8_append(lip->m_cpp_text_start); +int Lex_input_stream::scan_ident_sysvar(THD *thd, Lex_ident_cli_st *str) +{ + uchar last_char; + uint length; + int tokval; + bool is_8bit; + DBUG_ASSERT(m_tok_start == m_ptr); + + is_8bit= get_7bit_or_8bit_ident(thd, &last_char); + + if (last_char == '.') + next_state= MY_LEX_IDENT_SEP; + if (!(length= yyLength())) + return ABORT_SYM; // Names must be nonempty. + if ((tokval= find_keyword(str, length, 0))) + { + yyUnget(); // Put back 'c' + return tokval; // Was keyword + } - lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end); + yyUnget(); // ptr points now after last token char + str->set_ident(m_tok_start, length, is_8bit); - return(result_state); + m_cpp_text_start= m_cpp_tok_start; + m_cpp_text_end= m_cpp_text_start + length; + body_utf8_append(m_cpp_text_start); + body_utf8_append_ident(thd, str, m_cpp_text_end); + + return is_8bit ? IDENT_QUOTED : IDENT; +} + + +/* + We can come here if different parsing stages: + - In an identifier chain: + SELECT t1.cccc FROM t1; + (when the "cccc" part starts) + In this case both m_tok_start and m_ptr point to "cccc". + - When a sequence of digits has changed to something else, + therefore the token becomes an identifier rather than a number: + SELECT 12345_6 FROM t1; + In this case m_tok_start points to the entire "12345_678", + while m_ptr points to "678". +*/ +int Lex_input_stream::scan_ident_start(THD *thd, Lex_ident_cli_st *str) +{ + uchar c; + bool is_8bit; + CHARSET_INFO *const cs= thd->charset(); + const uchar *const ident_map= cs->ident_map; + DBUG_ASSERT(m_tok_start <= m_ptr); + + if (use_mb(cs)) + { + is_8bit= true; + while (ident_map[c= yyGet()]) + { + int char_length= my_charlen(cs, get_ptr() - 1, get_end_of_query()); + if (char_length <= 0) + break; + skip_binary(char_length - 1); } } + else + { + is_8bit= get_7bit_or_8bit_ident(thd, &c); + } + if (c == '.' && ident_map[(uchar) yyPeek()]) + next_state= MY_LEX_IDENT_SEP;// Next is '.' + + uint length= yyLength(); + yyUnget(); // ptr points now after last token char + str->set_ident(m_tok_start, length, is_8bit); + m_cpp_text_start= m_cpp_tok_start; + m_cpp_text_end= m_cpp_text_start + length; + body_utf8_append(m_cpp_text_start); + body_utf8_append_ident(thd, str, m_cpp_text_end); + return is_8bit ? IDENT_QUOTED : IDENT; +} + + +int Lex_input_stream::scan_ident_middle(THD *thd, Lex_ident_cli_st *str, + CHARSET_INFO **introducer, + my_lex_states *st) +{ + CHARSET_INFO *const cs= thd->charset(); + const uchar *const ident_map= cs->ident_map; + const uchar *const state_map= cs->state_map; + const char *start; + uint length; + uchar c; + bool is_8bit; + bool resolve_introducer= true; + DBUG_ASSERT(m_ptr == m_tok_start + 1); // m_ptr points to the second byte + + if (use_mb(cs)) + { + is_8bit= true; + int char_length= my_charlen(cs, get_ptr() - 1, get_end_of_query()); + if (char_length <= 0) + { + *st= MY_LEX_CHAR; + return 0; + } + skip_binary(char_length - 1); + + while (ident_map[c= yyGet()]) + { + char_length= my_charlen(cs, get_ptr() - 1, get_end_of_query()); + if (char_length <= 0) + break; + if (char_length > 1 || (c & 0x80)) + resolve_introducer= false; + skip_binary(char_length - 1); + } + } + else + { + is_8bit= get_7bit_or_8bit_ident(thd, &c) || (m_tok_start[0] & 0x80); + resolve_introducer= !is_8bit; + } + length= yyLength(); + start= get_ptr(); + if (ignore_space) + { + /* + If we find a space then this can't be an identifier. We notice this + below by checking start != lex->ptr. + */ + for (; state_map[(uchar) c] == MY_LEX_SKIP ; c= yyGet()) + { + if (c == '\n') + yylineno++; + } + } + if (start == get_ptr() && c == '.' && ident_map[(uchar) yyPeek()]) + next_state= MY_LEX_IDENT_SEP; + else + { // '(' must follow directly if function + int tokval; + yyUnget(); + if ((tokval= find_keyword(str, length, c == '('))) + { + next_state= MY_LEX_START; // Allow signed numbers + return(tokval); // Was keyword + } + yySkip(); // next state does a unget + } + + /* + Note: "SELECT _bla AS 'alias'" + _bla should be considered as a IDENT if charset haven't been found. + So we don't use MYF(MY_WME) with get_charset_by_csname to avoid + producing an error. + */ + DBUG_ASSERT(length > 0); + if (resolve_introducer && m_tok_start[0] == '_') + { + + yyUnget(); // ptr points now after last token char + str->set_ident(m_tok_start, length, false); + + m_cpp_text_start= m_cpp_tok_start; + m_cpp_text_end= m_cpp_text_start + length; + body_utf8_append(m_cpp_text_start, m_cpp_tok_start + length); + ErrConvString csname(str->str + 1, str->length - 1, &my_charset_bin); + CHARSET_INFO *cs= get_charset_by_csname(csname.ptr(), + MY_CS_PRIMARY, MYF(0)); + if (cs) + { + *introducer= cs; + return UNDERSCORE_CHARSET; + } + return IDENT; + } + + yyUnget(); // ptr points now after last token char + str->set_ident(m_tok_start, length, is_8bit); + m_cpp_text_start= m_cpp_tok_start; + m_cpp_text_end= m_cpp_text_start + length; + body_utf8_append(m_cpp_text_start); + body_utf8_append_ident(thd, str, m_cpp_text_end); + return is_8bit ? IDENT_QUOTED : IDENT; +} + + +int Lex_input_stream::scan_ident_delimited(THD *thd, + Lex_ident_cli_st *str) +{ + CHARSET_INFO *const cs= thd->charset(); + uint double_quotes= 0; + uchar c, quote_char= m_tok_start[0]; + DBUG_ASSERT(m_ptr == m_tok_start + 1); + + while ((c= yyGet())) + { + int var_length= my_charlen(cs, get_ptr() - 1, get_end_of_query()); + if (var_length == 1) + { + if (c == quote_char) + { + if (yyPeek() != quote_char) + break; + c= yyGet(); + double_quotes++; + continue; + } + } + else if (var_length > 1) + { + skip_binary(var_length - 1); + } + } + + str->set_ident_quoted(m_tok_start + 1, yyLength() - 1, true, quote_char); + yyUnget(); // ptr points now after last token char + + m_cpp_text_start= m_cpp_tok_start + 1; + m_cpp_text_end= m_cpp_text_start + str->length; + + if (c == quote_char) + yySkip(); // Skip end ` + next_state= MY_LEX_START; + body_utf8_append(m_cpp_text_start); + // QQQ: shouldn't it add unescaped version ???? + body_utf8_append_ident(thd, str, m_cpp_text_end); + return IDENT_QUOTED; } @@ -2251,6 +2275,7 @@ void st_select_lex::init_query() select_n_having_items= 0; n_sum_items= 0; n_child_sum_items= 0; + hidden_bit_fields= 0; subquery_in_having= explicit_limit= 0; is_item_list_lookup= 0; first_execution= 1; @@ -2298,6 +2323,7 @@ void st_select_lex::init_select() select_limit= 0; /* denotes the default limit = HA_POS_ERROR */ offset_limit= 0; /* denotes the default offset = 0 */ with_sum_func= 0; + with_all_modifier= 0; is_correlated= 0; cur_pos_in_select_list= UNDEF_POS; cond_value= having_value= Item::COND_UNDEF; @@ -2367,7 +2393,7 @@ void st_select_lex_node::add_slave(st_select_lex_node *slave_arg) ref - references on reference on this node */ void st_select_lex_node::include_standalone(st_select_lex_node *upper, - st_select_lex_node **ref) + st_select_lex_node **ref) { next= 0; prev= ref; @@ -2432,7 +2458,7 @@ void st_select_lex_node::fast_exclude() */ st_select_lex_node *st_select_lex_node:: insert_chain_before( - st_select_lex_node **ptr_pos_to_insert, + st_select_lex_node **ptr_pos_to_insert, st_select_lex_node *end_chain_node) { end_chain_node->link_next= *ptr_pos_to_insert; @@ -2787,6 +2813,10 @@ ulong st_select_lex::get_table_join_options() bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) { + + if (!((options & SELECT_DISTINCT) && !group_list.elements)) + hidden_bit_fields= 0; + // find_order_in_list() may need some extra space, so multiply by two. order_group_num*= 2; @@ -2801,7 +2831,8 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) select_n_reserved + select_n_having_items + select_n_where_fields + - order_group_num) * 5; + order_group_num + + hidden_bit_fields) * 5; if (!ref_pointer_array.is_null()) { /* @@ -2815,7 +2846,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) return false; } Item **array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems)); - if (array != NULL) + if (likely(array != NULL)) ref_pointer_array= Ref_ptr_array(array, n_elems); return array == NULL; @@ -3130,11 +3161,11 @@ bool LEX::can_be_merged() } return (selects_allow_merge && - select_lex.group_list.elements == 0 && - select_lex.having == 0 && + select_lex.group_list.elements == 0 && + select_lex.having == 0 && select_lex.with_sum_func == 0 && - select_lex.table_list.elements >= 1 && - !(select_lex.options & SELECT_DISTINCT) && + select_lex.table_list.elements >= 1 && + !(select_lex.options & SELECT_DISTINCT) && select_lex.select_limit == 0); } @@ -3515,14 +3546,14 @@ void LEX::set_trg_event_type_for_tables() SYNOPSIS unlink_first_table() - link_to_local Set to 1 if caller should link this table to local list + link_to_local Set to 1 if caller should link this table to local list NOTES We assume that first tables in both lists is the same table or the local list is empty. RETURN - 0 If 'query_tables' == 0 + 0 If 'query_tables' == 0 unlinked table In this case link_to_local is set. @@ -3549,7 +3580,7 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local) select_lex.context.table_list= select_lex.context.first_name_resolution_table= first->next_local; select_lex.table_list.first= first->next_local; - select_lex.table_list.elements--; //safety + select_lex.table_list.elements--; //safety first->next_local= 0; /* Ensure that the global list has the same first table as the local @@ -3611,14 +3642,14 @@ void LEX::first_lists_tables_same() SYNOPSIS link_first_table_back() - link_to_local do we need link this table to local + link_to_local do we need link this table to local RETURN global list */ void LEX::link_first_table_back(TABLE_LIST *first, - bool link_to_local) + bool link_to_local) { if (first) { @@ -3633,7 +3664,7 @@ void LEX::link_first_table_back(TABLE_LIST *first, first->next_local= select_lex.table_list.first; select_lex.context.table_list= first; select_lex.table_list.first= first; - select_lex.table_list.elements++; //safety + select_lex.table_list.elements++; //safety } } } @@ -3928,15 +3959,15 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only) { if (!subquery_predicate->fixed) { - /* - This subquery was excluded as part of some expression so it is - invisible from all prepared expression. + /* + This subquery was excluded as part of some expression so it is + invisible from all prepared expression. */ - next_unit= un->next_unit(); - un->exclude_level(); - if (next_unit) - continue; - break; + next_unit= un->next_unit(); + un->exclude_level(); + if (next_unit) + continue; + break; } if (subquery_predicate->substype() == Item_subselect::IN_SUBS) { @@ -4257,7 +4288,7 @@ bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived, for (uint i= 0; i < cnt; i++) { if (subq_select->expr_cache_may_be_used[i]) - expr_cache_may_be_used[i]= true; + expr_cache_may_be_used[i]= true; } List_iterator_fast<Item_func_in> it(subq_select->in_funcs); @@ -4323,7 +4354,7 @@ void SELECT_LEX::update_used_tables() for (embedding= tl->embedding; embedding; embedding=embedding->embedding) { if (embedding->is_view_or_derived()) - { + { DBUG_ASSERT(embedding->is_merged_derived()); TABLE *tab= tl->table; tab->covering_keys= tab->s->keys_for_keyread; @@ -4355,7 +4386,7 @@ void SELECT_LEX::update_used_tables() bool maybe_null; if ((maybe_null= MY_TEST(embedding->outer_join))) { - tl->table->maybe_null= maybe_null; + tl->table->maybe_null= maybe_null; break; } } @@ -4867,14 +4898,14 @@ bool LEX::set_arena_for_set_stmt(Query_arena *backup) if (!mem_root_for_set_stmt) { mem_root_for_set_stmt= new MEM_ROOT(); - if (!(mem_root_for_set_stmt)) + if (unlikely(!(mem_root_for_set_stmt))) DBUG_RETURN(1); init_sql_alloc(mem_root_for_set_stmt, "set_stmt", ALLOC_ROOT_SET, ALLOC_ROOT_SET, MYF(MY_THREAD_SPECIFIC)); } - if (!(arena_for_set_stmt= new(mem_root_for_set_stmt) - Query_arena_memroot(mem_root_for_set_stmt, - Query_arena::STMT_INITIALIZED))) + if (unlikely(!(arena_for_set_stmt= new(mem_root_for_set_stmt) + Query_arena_memroot(mem_root_for_set_stmt, + Query_arena::STMT_INITIALIZED)))) DBUG_RETURN(1); DBUG_PRINT("info", ("mem_root: %p arena: %p", mem_root_for_set_stmt, @@ -4987,6 +5018,8 @@ int st_select_lex_unit::save_union_explain(Explain_query *output) Explain_union *eu= new (output->mem_root) Explain_union(output->mem_root, thd->lex->analyze_stmt); + if (unlikely(!eu)) + return 0; if (with_element && with_element->is_recursive) eu->is_recursive_cte= true; @@ -5121,9 +5154,9 @@ bool LEX::add_unit_in_brackets(SELECT_LEX *nselect) /* add SELECT list*/ Item *item= new (thd->mem_root) Item_field(thd, context, NULL, NULL, &star_clex_str); - if (item == NULL) + if (unlikely(item == NULL)) DBUG_RETURN(TRUE); - if (add_item_to_list(thd, item)) + if (unlikely(add_item_to_list(thd, item))) DBUG_RETURN(TRUE); (dummy_select->with_wild)++; @@ -5136,20 +5169,21 @@ bool LEX::add_unit_in_brackets(SELECT_LEX *nselect) SELECT_LEX_UNIT *unit= nselect->master_unit(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); - if (ti == NULL) + if (unlikely(ti == NULL)) DBUG_RETURN(TRUE); char buff[10]; LEX_CSTRING alias; alias.length= my_snprintf(buff, sizeof(buff), "__%u", dummy_select->select_number); alias.str= thd->strmake(buff, alias.length); - if (!alias.str) + if (unlikely(!alias.str)) DBUG_RETURN(TRUE); TABLE_LIST *table_list; - if (!(table_list= dummy_select->add_table_to_list(thd, ti, &alias, - 0, TL_READ, - MDL_SHARED_READ))) + if (unlikely(!(table_list= + dummy_select->add_table_to_list(thd, ti, &alias, + 0, TL_READ, + MDL_SHARED_READ)))) DBUG_RETURN(TRUE); context->resolve_in_table_list_only(table_list); dummy_select->add_joined_table(table_list); @@ -5248,12 +5282,26 @@ LEX::find_variable(const LEX_CSTRING *name, } +static bool is_new(const char *str) +{ + return (str[0] == 'n' || str[0] == 'N') && + (str[1] == 'e' || str[1] == 'E') && + (str[2] == 'w' || str[2] == 'W'); +} + +static bool is_old(const char *str) +{ + return (str[0] == 'o' || str[0] == 'O') && + (str[1] == 'l' || str[1] == 'L') && + (str[2] == 'd' || str[2] == 'D'); +} + + bool LEX::is_trigger_new_or_old_reference(const LEX_CSTRING *name) const { + // "name" is not necessarily NULL-terminated! return sphead && sphead->m_handler->type() == TYPE_ENUM_TRIGGER && - name->length == 3 && - (!my_strcasecmp(system_charset_info, name->str, "NEW") || - !my_strcasecmp(system_charset_info, name->str, "OLD")); + name->length == 3 && (is_new(name->str) || is_old(name->str)); } @@ -5272,7 +5320,7 @@ bool LEX::sp_variable_declarations_set_default(THD *thd, int nvars, Item *dflt_value_item) { if (!dflt_value_item && - !(dflt_value_item= new (thd->mem_root) Item_null(thd))) + unlikely(!(dflt_value_item= new (thd->mem_root) Item_null(thd)))) return true; for (uint i= 0 ; i < (uint) nvars ; i++) @@ -5286,7 +5334,7 @@ bool LEX::sp_variable_declarations_set_default(THD *thd, int nvars, spcont, &sp_rcontext_handler_local, spvar->offset, dflt_value_item, this, last); - if (is == NULL || sphead->add_instr(is)) + if (unlikely(is == NULL || sphead->add_instr(is))) return true; } return false; @@ -5310,7 +5358,8 @@ LEX::sp_variable_declarations_copy_type_finalize(THD *thd, int nvars, } spvar->field_def.field_name= spvar->name; } - if (sp_variable_declarations_set_default(thd, nvars, default_value)) + if (unlikely(sp_variable_declarations_set_default(thd, nvars, + default_value))) return true; spcont->declare_var_boundary(0); return sphead->restore_lex(thd); @@ -5411,7 +5460,8 @@ LEX::sp_variable_declarations_table_rowtype_finalize(THD *thd, int nvars, Item *def) { Table_ident *table_ref; - if (!(table_ref= new (thd->mem_root) Table_ident(thd, &db, &table, false))) + if (unlikely(!(table_ref= + new (thd->mem_root) Table_ident(thd, &db, &table, false)))) return true; // Loop through all variables in the same declaration for (uint i= 0 ; i < (uint) nvars; i++) @@ -5451,7 +5501,7 @@ LEX::sp_variable_declarations_cursor_rowtype_finalize(THD *thd, int nvars, sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name); } - if (sp_variable_declarations_set_default(thd, nvars, def)) + if (unlikely(sp_variable_declarations_set_default(thd, nvars, def))) return true; // Make sure sp_rcontext is created using the invoker security context: sphead->m_flags|= sp_head::HAS_COLUMN_TYPE_REFS; @@ -5574,7 +5624,7 @@ sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name, spvar->field_def.set_handler(&type_handler_longlong); type_handler_longlong.Column_definition_prepare_stage2(&spvar->field_def, NULL, HA_CAN_GEOMETRY); - if (!value && !(value= new (thd->mem_root) Item_null(thd))) + if (!value && unlikely(!(value= new (thd->mem_root) Item_null(thd)))) return NULL; spvar->default_value= value; @@ -5583,7 +5633,7 @@ sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name, spcont, &sp_rcontext_handler_local, spvar->offset, value, this, true); - if (is == NULL || sphead->add_instr(is)) + if (unlikely(is == NULL || sphead->add_instr(is))) return NULL; spcont->declare_var_boundary(0); return spvar; @@ -5600,14 +5650,16 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd, if (sp_declare_cursor(thd, &name, cur, NULL, true)) return true; DBUG_ASSERT(thd->lex == this); - if (!(bounds->m_index= new (thd->mem_root) sp_assignment_lex(thd, this))) + if (unlikely(!(bounds->m_index= + new (thd->mem_root) sp_assignment_lex(thd, this)))) return true; bounds->m_index->sp_lex_in_use= true; sphead->reset_lex(thd, bounds->m_index); DBUG_ASSERT(thd->lex != this); - if (!(item= new (thd->mem_root) Item_field(thd, - thd->lex->current_context(), - NullS, NullS, &name))) + if (unlikely(!(item= + new (thd->mem_root) Item_field(thd, + thd->lex->current_context(), + NullS, NullS, &name)))) return true; bounds->m_index->set_item_and_free_list(item, NULL); if (thd->lex->sphead->restore_lex(thd)) @@ -5632,13 +5684,14 @@ LEX::sp_add_for_loop_cursor_variable(THD *thd, return NULL; spcont->declare_var_boundary(1); sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name); - if (!(spvar->default_value= new (thd->mem_root) Item_null(thd))) + if (unlikely(!(spvar->default_value= new (thd->mem_root) Item_null(thd)))) return NULL; spvar->field_def.set_cursor_rowtype_ref(coffset); - if (sphead->add_for_loop_open_cursor(thd, spcont, spvar, pcursor, coffset, - param_lex, parameters)) + if (unlikely(sphead->add_for_loop_open_cursor(thd, spcont, spvar, pcursor, + coffset, + param_lex, parameters))) return NULL; spcont->declare_var_boundary(0); @@ -5661,7 +5714,7 @@ bool LEX::sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop) args[i]= new (thd->mem_root) Item_splocal(thd, &sp_rcontext_handler_local, &src->name, src->offset, src->type_handler()); - if (args[i] == NULL) + if (unlikely(args[i] == NULL)) return true; #ifdef DBUG_ASSERT_EXISTS args[i]->m_sp= sphead; @@ -5671,7 +5724,7 @@ bool LEX::sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop) Item *expr= loop.m_direction > 0 ? (Item *) new (thd->mem_root) Item_func_le(thd, args[0], args[1]) : (Item *) new (thd->mem_root) Item_func_ge(thd, args[0], args[1]); - return !expr || sp_while_loop_expression(thd, expr); + return unlikely(!expr) || unlikely(sp_while_loop_expression(thd, expr)); } @@ -5683,7 +5736,7 @@ bool LEX::sp_for_loop_intrange_condition_test(THD *thd, { spcont->set_for_loop(loop); sphead->reset_lex(thd); - if (thd->lex->sp_for_loop_condition(thd, loop)) + if (unlikely(thd->lex->sp_for_loop_condition(thd, loop))) return true; return thd->lex->sphead->restore_lex(thd); } @@ -5698,8 +5751,10 @@ bool LEX::sp_for_loop_cursor_condition_test(THD *thd, sphead->reset_lex(thd); cursor_name= spcont->find_cursor(loop.m_cursor_offset); DBUG_ASSERT(cursor_name); - if (!(expr= new (thd->mem_root) Item_func_cursor_found(thd, cursor_name, - loop.m_cursor_offset))) + if (unlikely(!(expr= + new (thd->mem_root) + Item_func_cursor_found(thd, cursor_name, + loop.m_cursor_offset)))) return true; if (thd->lex->sp_while_loop_expression(thd, expr)) return true; @@ -5711,13 +5766,16 @@ bool LEX::sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop, const LEX_CSTRING *index, const Lex_for_loop_bounds_st &bounds) { - if (!(loop->m_index= - bounds.m_index->sp_add_for_loop_variable(thd, index, - bounds.m_index->get_item()))) + if (unlikely(!(loop->m_index= + bounds.m_index-> + sp_add_for_loop_variable(thd, index, + bounds.m_index->get_item())))) return true; - if (!(loop->m_upper_bound= - bounds.m_upper_bound->sp_add_for_loop_upper_bound(thd, - bounds.m_upper_bound->get_item()))) + if (unlikely(!(loop->m_upper_bound= + bounds.m_upper_bound-> + sp_add_for_loop_upper_bound(thd, + bounds. + m_upper_bound->get_item())))) return true; loop->m_direction= bounds.m_direction; loop->m_implicit_cursor= 0; @@ -5770,8 +5828,9 @@ bool LEX::sp_for_loop_cursor_declarations(THD *thd, thd->parse_error(); return true; } - if (!(pcursor= spcont->find_cursor_with_error(&name, &coffs, false)) || - pcursor->check_param_count_with_error(param_count)) + if (unlikely(!(pcursor= spcont->find_cursor_with_error(&name, &coffs, + false)) || + pcursor->check_param_count_with_error(param_count))) return true; if (!(loop->m_index= sp_add_for_loop_cursor_variable(thd, index, @@ -5796,18 +5855,19 @@ bool LEX::sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop) Item_splocal(thd, &sp_rcontext_handler_local, &loop.m_index->name, loop.m_index->offset, loop.m_index->type_handler()); - if (splocal == NULL) + if (unlikely(splocal == NULL)) return true; #ifdef DBUG_ASSERT_EXISTS splocal->m_sp= sphead; #endif Item_int *inc= new (thd->mem_root) Item_int(thd, loop.m_direction); - if (!inc) + if (unlikely(!inc)) return true; Item *expr= new (thd->mem_root) Item_func_plus(thd, splocal, inc); - if (!expr || - sphead->set_local_variable(thd, spcont, &sp_rcontext_handler_local, - loop.m_index, expr, this, true)) + if (unlikely(!expr) || + unlikely(sphead->set_local_variable(thd, spcont, + &sp_rcontext_handler_local, + loop.m_index, expr, this, true))) return true; return false; } @@ -5819,8 +5879,8 @@ bool LEX::sp_for_loop_intrange_finalize(THD *thd, const Lex_for_loop_st &loop) // Generate FOR LOOP index increment in its own lex DBUG_ASSERT(this != thd->lex); - if (thd->lex->sp_for_loop_increment(thd, loop) || - thd->lex->sphead->restore_lex(thd)) + if (unlikely(thd->lex->sp_for_loop_increment(thd, loop) || + thd->lex->sphead->restore_lex(thd))) return true; // Generate a jump to the beginning of the loop @@ -5834,7 +5894,7 @@ bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop) sp_instr_cfetch *instr= new (thd->mem_root) sp_instr_cfetch(sphead->instructions(), spcont, loop.m_cursor_offset, false); - if (instr == NULL || sphead->add_instr(instr)) + if (unlikely(instr == NULL) || unlikely(sphead->add_instr(instr))) return true; instr->add_to_varlist(loop.m_index); // Generate a jump to the beginning of the loop @@ -5857,7 +5917,7 @@ bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name, } cursor_stmt->set_cursor_name(name); - if (spcont->add_cursor(name, param_ctx, cursor_stmt)) + if (unlikely(spcont->add_cursor(name, param_ctx, cursor_stmt))) return true; if (add_cpush_instr) @@ -5865,7 +5925,7 @@ bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name, i= new (thd->mem_root) sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt, spcont->current_cursor_count() - 1); - return i == NULL || sphead->add_instr(i); + return unlikely(i == NULL) || unlikely(sphead->add_instr(i)); } return false; } @@ -5900,15 +5960,17 @@ bool LEX::sp_handler_declaration_init(THD *thd, int type) sp_instr_hpush_jump *i= new (thd->mem_root) sp_instr_hpush_jump(sphead->instructions(), spcont, h); - if (i == NULL || sphead->add_instr(i)) + if (unlikely(i == NULL) || unlikely(sphead->add_instr(i))) return true; /* For continue handlers, mark end of handler scope. */ if (type == sp_handler::CONTINUE && - sphead->push_backpatch(thd, i, spcont->last_label())) + unlikely(sphead->push_backpatch(thd, i, spcont->last_label()))) return true; - if (sphead->push_backpatch(thd, i, spcont->push_label(thd, &empty_clex_str, 0))) + if (unlikely(sphead->push_backpatch(thd, i, + spcont->push_label(thd, &empty_clex_str, + 0)))) return true; return false; @@ -5923,16 +5985,16 @@ bool LEX::sp_handler_declaration_finalize(THD *thd, int type) if (type == sp_handler::CONTINUE) { i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont); - if (i == NULL || - sphead->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i))) return true; } else { /* EXIT or UNDO handler, just jump to the end of the block */ i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont); - if (i == NULL || - sphead->add_instr(i) || - sphead->push_backpatch(thd, i, spcont->last_label())) /* Block end */ + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i)) || + unlikely(sphead->push_backpatch(thd, i, spcont->last_label()))) /* Block end */ return true; } sphead->backpatch(hlab); @@ -5960,16 +6022,16 @@ bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock, { i= new (thd->mem_root) sp_instr_hpop(sp->instructions(), ctx, spblock.hndlrs); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) return true; } if (spblock.curs) { i= new (thd->mem_root) sp_instr_cpop(sp->instructions(), ctx, spblock.curs); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) return true; } spcont= ctx->pop_context(); @@ -5982,11 +6044,11 @@ bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock, const LEX_CSTRING *end_label) { sp_label *splabel; - if (sp_block_finalize(thd, spblock, &splabel)) + if (unlikely(sp_block_finalize(thd, spblock, &splabel))) return true; - if (end_label->str && - lex_string_cmp(system_charset_info, - end_label, &splabel->name) != 0) + if (unlikely(end_label->str && + lex_string_cmp(system_charset_info, + end_label, &splabel->name) != 0)) { my_error(ER_SP_LABEL_MISMATCH, MYF(0), end_label->str); return true; @@ -5999,9 +6061,9 @@ sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name) { sp_name *res; LEX_CSTRING db; - if (check_routine_name(name) || - copy_db_to(&db) || - (!(res= new (thd->mem_root) sp_name(&db, name, false)))) + if (unlikely(check_routine_name(name)) || + unlikely(copy_db_to(&db)) || + unlikely((!(res= new (thd->mem_root) sp_name(&db, name, false))))) return NULL; return res; } @@ -6023,7 +6085,7 @@ sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name) sp_name *LEX::make_sp_name_package_routine(THD *thd, const LEX_CSTRING *name) { sp_name *res= make_sp_name(thd, name); - if (res && strchr(res->m_name.str, '.')) + if (likely(res) && unlikely(strchr(res->m_name.str, '.'))) { my_error(ER_SP_WRONG_NAME, MYF(0), res->m_name.str); res= NULL; @@ -6037,15 +6099,16 @@ sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name1, { sp_name *res; LEX_CSTRING norm_name1; - if (!name1->str || - !thd->make_lex_string(&norm_name1, name1->str, name1->length) || - check_db_name((LEX_STRING *) &norm_name1)) + if (unlikely(!name1->str) || + unlikely(!thd->make_lex_string(&norm_name1, name1->str, + name1->length)) || + unlikely(check_db_name((LEX_STRING *) &norm_name1))) { my_error(ER_WRONG_DB_NAME, MYF(0), name1->str); return NULL; } - if (check_routine_name(name2) || - (!(res= new (thd->mem_root) sp_name(&norm_name1, name2, true)))) + if (unlikely(check_routine_name(name2)) || + unlikely(!(res= new (thd->mem_root) sp_name(&norm_name1, name2, true)))) return NULL; return res; } @@ -6058,7 +6121,7 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name, sp_head *sp; /* Order is important here: new - reset - init */ - if ((sp= new sp_head(package, sph))) + if (likely((sp= new sp_head(package, sph)))) { sp->reset_thd_mem_root(thd); sp->init(this); @@ -6210,13 +6273,13 @@ bool LEX::sp_change_context(THD *thd, const sp_pcontext *ctx, bool exclusive) if ((n= spcont->diff_handlers(ctx, exclusive))) { sp_instr_hpop *hpop= new (thd->mem_root) sp_instr_hpop(ip++, spcont, n); - if (hpop == NULL || sphead->add_instr(hpop)) + if (unlikely(hpop == NULL) || unlikely(sphead->add_instr(hpop))) return true; } if ((n= spcont->diff_cursors(ctx, exclusive))) { sp_instr_cpop *cpop= new (thd->mem_root) sp_instr_cpop(ip++, spcont, n); - if (cpop == NULL || sphead->add_instr(cpop)) + if (unlikely(cpop == NULL) || unlikely(sphead->add_instr(cpop))) return true; } return false; @@ -6226,7 +6289,7 @@ bool LEX::sp_change_context(THD *thd, const sp_pcontext *ctx, bool exclusive) bool LEX::sp_leave_statement(THD *thd, const LEX_CSTRING *label_name) { sp_label *lab= spcont->find_label(label_name); - if (!lab) + if (unlikely(!lab)) { my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", label_name->str); return true; @@ -6266,7 +6329,7 @@ bool LEX::sp_push_goto_label(THD *thd, const LEX_CSTRING *label_name) sp_label *lab= spcont->find_goto_label(label_name, false); if (lab) { - if (lab->ip != 0) + if (unlikely(lab->ip != 0)) { my_error(ER_SP_LABEL_REDEFINE, MYF(0), label_name->str); return true; @@ -6310,9 +6373,9 @@ bool LEX::sp_exit_block(THD *thd, sp_label *lab, Item *when) sp_instr_jump_if_not(sphead->instructions(), spcont, when, thd->lex); - if (i == NULL || - sphead->add_instr(i) || - sp_exit_block(thd, lab)) + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i)) || + unlikely(sp_exit_block(thd, lab))) return true; i->backpatch(sphead->instructions(), spcont); return false; @@ -6322,7 +6385,7 @@ bool LEX::sp_exit_block(THD *thd, sp_label *lab, Item *when) bool LEX::sp_exit_statement(THD *thd, Item *item) { sp_label *lab= spcont->find_label_current_loop_start(); - if (!lab) + if (unlikely(!lab)) { my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "EXIT", ""); return true; @@ -6335,7 +6398,7 @@ bool LEX::sp_exit_statement(THD *thd, Item *item) bool LEX::sp_exit_statement(THD *thd, const LEX_CSTRING *label_name, Item *item) { sp_label *lab= spcont->find_label(label_name); - if (!lab || lab->type != sp_label::ITERATION) + if (unlikely(!lab || lab->type != sp_label::ITERATION)) { my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "EXIT", label_name->str); return true; @@ -6347,7 +6410,7 @@ bool LEX::sp_exit_statement(THD *thd, const LEX_CSTRING *label_name, Item *item) bool LEX::sp_iterate_statement(THD *thd, const LEX_CSTRING *label_name) { sp_label *lab= spcont->find_label(label_name); - if (!lab || lab->type != sp_label::ITERATION) + if (unlikely(!lab || lab->type != sp_label::ITERATION)) { my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", label_name->str); return true; @@ -6383,9 +6446,9 @@ bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when) sp_instr_jump_if_not(sphead->instructions(), spcont, when, thd->lex); - if (i == NULL || - sphead->add_instr(i) || - sp_continue_loop(thd, lab)) + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i)) || + unlikely(sp_continue_loop(thd, lab))) return true; i->backpatch(sphead->instructions(), spcont); return false; @@ -6395,7 +6458,7 @@ bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when) bool LEX::sp_continue_statement(THD *thd, Item *when) { sp_label *lab= spcont->find_label_current_loop_start(); - if (!lab) + if (unlikely(!lab)) { my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "CONTINUE", ""); return true; @@ -6483,11 +6546,11 @@ bool LEX::sp_while_loop_expression(THD *thd, Item *expr) { sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(sphead->instructions(), spcont, expr, this); - return i == NULL || - /* Jumping forward */ - sphead->push_backpatch(thd, i, spcont->last_label()) || - sphead->new_cont_backpatch(i) || - sphead->add_instr(i); + return (unlikely(i == NULL) || + /* Jumping forward */ + unlikely(sphead->push_backpatch(thd, i, spcont->last_label())) || + unlikely(sphead->new_cont_backpatch(i)) || + unlikely(sphead->add_instr(i))); } @@ -6496,8 +6559,8 @@ bool LEX::sp_while_loop_finalize(THD *thd) sp_label *lab= spcont->last_label(); /* Jumping back */ sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(sphead->instructions(), spcont, lab->ip); - if (i == NULL || - sphead->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sphead->add_instr(i))) return true; sphead->do_cont_backpatch(); return false; @@ -6510,13 +6573,13 @@ Item *LEX::create_and_link_Item_trigger_field(THD *thd, { Item_trigger_field *trg_fld; - if (trg_chistics.event == TRG_EVENT_INSERT && !new_row) + if (unlikely(trg_chistics.event == TRG_EVENT_INSERT && !new_row)) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT"); return NULL; } - if (trg_chistics.event == TRG_EVENT_DELETE && new_row) + if (unlikely(trg_chistics.event == TRG_EVENT_DELETE && new_row)) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); return NULL; @@ -6538,22 +6601,64 @@ Item *LEX::create_and_link_Item_trigger_field(THD *thd, Let us add this item to list of all Item_trigger_field objects in trigger. */ - if (trg_fld) - trg_table_fields.link_in_list(trg_fld, &trg_fld->next_trg_field); + if (likely(trg_fld)) + trg_table_fields.link_in_list(trg_fld, &trg_fld->next_trg_field); return trg_fld; } +Item *LEX::make_item_colon_ident_ident(THD *thd, + const Lex_ident_cli_st *ca, + const Lex_ident_cli_st *cb) +{ + Lex_ident_sys a(thd, ca), b(thd, cb); + if (a.is_null() || b.is_null()) + return NULL; // OEM + if (!is_trigger_new_or_old_reference(&a)) + { + thd->parse_error(); + return NULL; + } + bool new_row= (a.str[0] == 'N' || a.str[0] == 'n'); + return create_and_link_Item_trigger_field(thd, &b, new_row); +} + + +Item *LEX::make_item_sysvar(THD *thd, + enum_var_type type, + const LEX_CSTRING *name, + const LEX_CSTRING *component) + +{ + Item *item; + DBUG_ASSERT(name->str); + /* + "SELECT @@global.global.variable" is not allowed + Note, "global" can come through TEXT_STRING_sys. + */ + if (component->str && unlikely(check_reserved_words(name))) + { + thd->parse_error(); + return NULL; + } + if (unlikely(!(item= get_system_var(thd, type, name, component)))) + return NULL; + if (!((Item_func_get_system_var*) item)->is_written_to_binlog()) + set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE); + return item; +} + + Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name, const char *start, const char *end) { - if (!thd->m_parser_state->m_lip.stmt_prepare_mode) + if (unlikely(!thd->m_parser_state->m_lip.stmt_prepare_mode)) { thd->parse_error(ER_SYNTAX_ERROR, start); return NULL; } - if (!parsing_options.allows_variable) + if (unlikely(!parsing_options.allows_variable)) { my_error(ER_VIEW_SELECT_VARIABLE, MYF(0)); return NULL; @@ -6562,7 +6667,7 @@ Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name, Query_fragment pos(thd, sphead, start, end); Item_param *item= new (thd->mem_root) Item_param(thd, name, pos.pos(), pos.length()); - if (!item || param_list.push_back(item, thd->mem_root)) + if (unlikely(!item) || unlikely(param_list.push_back(item, thd->mem_root))) { my_error(ER_OUT_OF_RESOURCES, MYF(0)); return NULL; @@ -6590,8 +6695,8 @@ bool LEX::add_resignal_statement(THD *thd, const sp_condition_value *v) Item *LEX::create_item_ident_nospvar(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b) + const Lex_ident_sys_st *a, + const Lex_ident_sys_st *b) { DBUG_ASSERT(this == thd->lex); /* @@ -6606,7 +6711,7 @@ Item *LEX::create_item_ident_nospvar(THD *thd, return create_and_link_Item_trigger_field(thd, b, new_row); } - if (current_select->no_table_names_allowed) + if (unlikely(current_select->no_table_names_allowed)) { my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), a->str, thd->where); return NULL; @@ -6622,13 +6727,13 @@ Item *LEX::create_item_ident_nospvar(THD *thd, Item_splocal *LEX::create_item_spvar_row_field(THD *thd, const Sp_rcontext_handler *rh, - const LEX_CSTRING *a, - const LEX_CSTRING *b, + const Lex_ident_sys *a, + const Lex_ident_sys *b, sp_variable *spv, const char *start, const char *end) { - if (!parsing_options.allows_variable) + if (unlikely(!parsing_options.allows_variable)) { my_error(ER_VIEW_SELECT_VARIABLE, MYF(0)); return NULL; @@ -6639,24 +6744,24 @@ Item_splocal *LEX::create_item_spvar_row_field(THD *thd, if (spv->field_def.is_table_rowtype_ref() || spv->field_def.is_cursor_rowtype_ref()) { - if (!(item= new (thd->mem_root) - Item_splocal_row_field_by_name(thd, rh, a, b, spv->offset, - &type_handler_null, - pos.pos(), pos.length()))) + if (unlikely(!(item= new (thd->mem_root) + Item_splocal_row_field_by_name(thd, rh, a, b, spv->offset, + &type_handler_null, + pos.pos(), pos.length())))) return NULL; } else { uint row_field_offset; const Spvar_definition *def; - if (!(def= spv->find_row_field(a, b, &row_field_offset))) + if (unlikely(!(def= spv->find_row_field(a, b, &row_field_offset)))) return NULL; - if (!(item= new (thd->mem_root) - Item_splocal_row_field(thd, rh, a, b, - spv->offset, row_field_offset, - def->type_handler(), - pos.pos(), pos.length()))) + if (unlikely(!(item= new (thd->mem_root) + Item_splocal_row_field(thd, rh, a, b, + spv->offset, row_field_offset, + def->type_handler(), + pos.pos(), pos.length())))) return NULL; } #ifdef DBUG_ASSERT_EXISTS @@ -6671,7 +6776,7 @@ my_var *LEX::create_outvar(THD *thd, const LEX_CSTRING *name) { const Sp_rcontext_handler *rh; sp_variable *spv; - if ((spv= find_variable(name, &rh))) + if (likely((spv= find_variable(name, &rh)))) return result ? new (thd->mem_root) my_var_sp(rh, name, spv->offset, spv->type_handler(), sphead) : @@ -6687,7 +6792,7 @@ my_var *LEX::create_outvar(THD *thd, { const Sp_rcontext_handler *rh; sp_variable *t; - if (!(t= find_variable(a, &rh))) + if (unlikely(!(t= find_variable(a, &rh)))) { my_error(ER_SP_UNDECLARED_VAR, MYF(0), a->str); return NULL; @@ -6705,11 +6810,12 @@ my_var *LEX::create_outvar(THD *thd, Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident) { TABLE_LIST *table; - if (!(table= current_select->add_table_to_list(thd, table_ident, 0, - TL_OPTION_SEQUENCE, - TL_WRITE_ALLOW_WRITE, - MDL_SHARED_WRITE))) + if (unlikely(!(table= current_select->add_table_to_list(thd, table_ident, 0, + TL_OPTION_SEQUENCE, + TL_WRITE_ALLOW_WRITE, + MDL_SHARED_WRITE)))) return NULL; + thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); return new (thd->mem_root) Item_func_nextval(thd, table); } @@ -6717,11 +6823,12 @@ Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident) Item *LEX::create_item_func_lastval(THD *thd, Table_ident *table_ident) { TABLE_LIST *table; - if (!(table= current_select->add_table_to_list(thd, table_ident, 0, - TL_OPTION_SEQUENCE, - TL_READ, - MDL_SHARED_READ))) + if (unlikely(!(table= current_select->add_table_to_list(thd, table_ident, 0, + TL_OPTION_SEQUENCE, + TL_READ, + MDL_SHARED_READ)))) return NULL; + thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); return new (thd->mem_root) Item_func_lastval(thd, table); } @@ -6731,7 +6838,8 @@ Item *LEX::create_item_func_nextval(THD *thd, const LEX_CSTRING *name) { Table_ident *table_ident; - if (!(table_ident= new (thd->mem_root) Table_ident(thd, db, name, false))) + if (unlikely(!(table_ident= + new (thd->mem_root) Table_ident(thd, db, name, false)))) return NULL; return create_item_func_nextval(thd, table_ident); } @@ -6742,7 +6850,8 @@ Item *LEX::create_item_func_lastval(THD *thd, const LEX_CSTRING *name) { Table_ident *table_ident; - if (!(table_ident= new (thd->mem_root) Table_ident(thd, db, name, false))) + if (unlikely(!(table_ident= + new (thd->mem_root) Table_ident(thd, db, name, false)))) return NULL; return create_item_func_lastval(thd, table_ident); } @@ -6753,10 +6862,10 @@ Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident, bool is_used) { TABLE_LIST *table; - if (!(table= current_select->add_table_to_list(thd, table_ident, 0, - TL_OPTION_SEQUENCE, - TL_WRITE_ALLOW_WRITE, - MDL_SHARED_WRITE))) + if (unlikely(!(table= current_select->add_table_to_list(thd, table_ident, 0, + TL_OPTION_SEQUENCE, + TL_WRITE_ALLOW_WRITE, + MDL_SHARED_WRITE)))) return NULL; return new (thd->mem_root) Item_func_setval(thd, table, nextval, round, is_used); @@ -6764,38 +6873,45 @@ Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident, Item *LEX::create_item_ident(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b, - const char *start, const char *end) + const Lex_ident_cli_st *ca, + const Lex_ident_cli_st *cb) { + const char *start= ca->pos(); + const char *end= cb->end(); const Sp_rcontext_handler *rh; sp_variable *spv; - if ((spv= find_variable(a, &rh)) && + DBUG_ASSERT(thd->m_parser_state->m_lip.get_buf() <= start); + DBUG_ASSERT(start <= end); + DBUG_ASSERT(end <= thd->m_parser_state->m_lip.get_end_of_query()); + Lex_ident_sys a(thd, ca), b(thd, cb); + if (a.is_null() || b.is_null()) + return NULL; // OEM + if ((spv= find_variable(&a, &rh)) && (spv->field_def.is_row() || spv->field_def.is_table_rowtype_ref() || spv->field_def.is_cursor_rowtype_ref())) - return create_item_spvar_row_field(thd, rh, a, b, spv, start, end); + return create_item_spvar_row_field(thd, rh, &a, &b, spv, start, end); - if ((thd->variables.sql_mode & MODE_ORACLE) && b->length == 7) + if ((thd->variables.sql_mode & MODE_ORACLE) && b.length == 7) { if (!my_strnncoll(system_charset_info, - (const uchar *) b->str, 7, + (const uchar *) b.str, 7, (const uchar *) "NEXTVAL", 7)) - return create_item_func_nextval(thd, &null_clex_str, a); + return create_item_func_nextval(thd, &null_clex_str, &a); else if (!my_strnncoll(system_charset_info, - (const uchar *) b->str, 7, + (const uchar *) b.str, 7, (const uchar *) "CURRVAL", 7)) - return create_item_func_lastval(thd, &null_clex_str, a); + return create_item_func_lastval(thd, &null_clex_str, &a); } - return create_item_ident_nospvar(thd, a, b); + return create_item_ident_nospvar(thd, &a, &b); } Item *LEX::create_item_ident(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b, - const LEX_CSTRING *c) + const Lex_ident_sys_st *a, + const Lex_ident_sys_st *b, + const Lex_ident_sys_st *c) { const char *schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS : a->str); @@ -6826,23 +6942,29 @@ Item *LEX::create_item_ident(THD *thd, } -Item *LEX::create_item_limit(THD *thd, - const LEX_CSTRING *a, - const char *start, const char *end) +Item *LEX::create_item_limit(THD *thd, const Lex_ident_cli_st *ca) { + DBUG_ASSERT(thd->m_parser_state->m_lip.get_buf() <= ca->pos()); + DBUG_ASSERT(ca->pos() <= ca->end()); + DBUG_ASSERT(ca->end() <= thd->m_parser_state->m_lip.get_end_of_query()); + const Sp_rcontext_handler *rh; sp_variable *spv; - if (!(spv= find_variable(a, &rh))) + Lex_ident_sys sa(thd, ca); + if (sa.is_null()) + return NULL; // EOM + if (!(spv= find_variable(&sa, &rh))) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), a->str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), sa.str); return NULL; } - Query_fragment pos(thd, sphead, start, end); + Query_fragment pos(thd, sphead, ca->pos(), ca->end()); Item_splocal *item; - if (!(item= new (thd->mem_root) Item_splocal(thd, rh, a, - spv->offset, spv->type_handler(), - pos.pos(), pos.length()))) + if (unlikely(!(item= new (thd->mem_root) + Item_splocal(thd, rh, &sa, + spv->offset, spv->type_handler(), + pos.pos(), pos.length())))) return NULL; #ifdef DBUG_ASSERT_EXISTS item->m_sp= sphead; @@ -6858,21 +6980,28 @@ Item *LEX::create_item_limit(THD *thd, Item *LEX::create_item_limit(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b, - const char *start, const char *end) + const Lex_ident_cli_st *ca, + const Lex_ident_cli_st *cb) { + DBUG_ASSERT(thd->m_parser_state->m_lip.get_buf() <= ca->pos()); + DBUG_ASSERT(ca->pos() <= cb->end()); + DBUG_ASSERT(cb->end() <= thd->m_parser_state->m_lip.get_end_of_query()); + const Sp_rcontext_handler *rh; sp_variable *spv; - if (!(spv= find_variable(a, &rh))) + Lex_ident_sys sa(thd, ca), sb(thd, cb); + if (unlikely(sa.is_null() || sb.is_null())) + return NULL; // EOM + if (!(spv= find_variable(&sa, &rh))) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), a->str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), sa.str); return NULL; } // Qualified %TYPE variables are not possible DBUG_ASSERT(!spv->field_def.column_type_ref()); Item_splocal *item; - if (!(item= create_item_spvar_row_field(thd, rh, a, b, spv, start, end))) + if (unlikely(!(item= create_item_spvar_row_field(thd, rh, &sa, &sb, spv, + ca->pos(), cb->end())))) return NULL; if (!item->is_valid_limit_clause_variable_with_error()) return NULL; @@ -6885,15 +7014,17 @@ bool LEX::set_user_variable(THD *thd, const LEX_CSTRING *name, Item *val) { Item_func_set_user_var *item; set_var_user *var; - if (!(item= new (thd->mem_root) Item_func_set_user_var(thd, name, val)) || - !(var= new (thd->mem_root) set_var_user(item))) + if (unlikely(!(item= new (thd->mem_root) Item_func_set_user_var(thd, name, + val))) || + unlikely(!(var= new (thd->mem_root) set_var_user(item)))) + return true; + if (unlikely(var_list.push_back(var, thd->mem_root))) return true; - var_list.push_back(var, thd->mem_root); return false; } -Item *LEX::create_item_ident_nosp(THD *thd, LEX_CSTRING *name) +Item *LEX::create_item_ident_nosp(THD *thd, Lex_ident_sys_st *name) { if (current_select->parsing_place != IN_HAVING || current_select->get_in_sum_expr() > 0) @@ -6905,10 +7036,14 @@ Item *LEX::create_item_ident_nosp(THD *thd, LEX_CSTRING *name) } -Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name, +Item *LEX::create_item_ident_sp(THD *thd, Lex_ident_sys_st *name, const char *start, const char *end) { + DBUG_ASSERT(thd->m_parser_state->m_lip.get_buf() <= start); + DBUG_ASSERT(start <= end); + DBUG_ASSERT(end <= thd->m_parser_state->m_lip.get_end_of_query()); + const Sp_rcontext_handler *rh; sp_variable *spv; DBUG_ASSERT(spcont); @@ -6931,7 +7066,7 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name, new (thd->mem_root) Item_splocal(thd, rh, name, spv->offset, spv->type_handler(), pos.pos(), pos.length()); - if (splocal == NULL) + if (unlikely(splocal == NULL)) return NULL; #ifdef DBUG_ASSERT_EXISTS splocal->m_sp= sphead; @@ -6942,9 +7077,9 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name, if (thd->variables.sql_mode & MODE_ORACLE) { - if (!my_strcasecmp(system_charset_info, name->str, "SQLCODE")) + if (lex_string_eq(name, STRING_WITH_LEN("SQLCODE"))) return new (thd->mem_root) Item_func_sqlcode(thd); - if (!my_strcasecmp(system_charset_info, name->str, "SQLERRM")) + if (lex_string_eq(name, STRING_WITH_LEN("SQLERRM"))) return new (thd->mem_root) Item_func_sqlerrm(thd); } return create_item_ident_nosp(thd, name); @@ -7004,7 +7139,7 @@ bool LEX::set_default_system_variable(enum_var_type var_type, sys_var *var= find_sys_var(thd, name->str, name->length); if (!var) return true; - if (!var->is_struct()) + if (unlikely(!var->is_struct())) { my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), name->str); return true; @@ -7019,7 +7154,7 @@ bool LEX::set_system_variable(enum_var_type var_type, { sys_var *var= find_sys_var(thd, name->str, name->length); DBUG_ASSERT(thd->is_error() || var != NULL); - return var ? set_system_variable(var_type, var, &null_clex_str, val) : true; + return likely(var) ? set_system_variable(var_type, var, &null_clex_str, val) : true; } @@ -7029,14 +7164,15 @@ bool LEX::set_system_variable(THD *thd, enum_var_type var_type, Item *val) { sys_var *tmp; - if (check_reserved_words(name1) || - !(tmp= find_sys_var_ex(thd, name2->str, name2->length, true, false))) + if (unlikely(check_reserved_words(name1)) || + unlikely(!(tmp= find_sys_var_ex(thd, name2->str, name2->length, true, + false)))) { my_error(ER_UNKNOWN_STRUCTURED_VARIABLE, MYF(0), (int) name1->length, name1->str); return true; } - if (!tmp->is_struct()) + if (unlikely(!tmp->is_struct())) { my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), name2->str); return true; @@ -7049,17 +7185,17 @@ bool LEX::set_trigger_field(const LEX_CSTRING *name1, const LEX_CSTRING *name2, Item *val) { DBUG_ASSERT(is_trigger_new_or_old_reference(name1)); - if (name1->str[0]=='O' || name1->str[0]=='o') + if (unlikely(name1->str[0]=='O' || name1->str[0]=='o')) { my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", ""); return true; } - if (trg_chistics.event == TRG_EVENT_DELETE) + if (unlikely(trg_chistics.event == TRG_EVENT_DELETE)) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); return true; } - if (trg_chistics.action_time == TRG_ACTION_AFTER) + if (unlikely(trg_chistics.action_time == TRG_ACTION_AFTER)) { my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after "); return true; @@ -7366,8 +7502,8 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, } else new_cond= new (thd->mem_root) Item_cond_or(thd); - if (!new_cond) - return 0; + if (unlikely(!new_cond)) + return 0; List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); Item *item; while ((item=li++)) @@ -7380,7 +7516,7 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, } Item *fix= build_cond_for_grouping_fields(thd, item, no_top_clones & cond_and); - if (!fix) + if (unlikely(!fix)) { if (cond_and) continue; @@ -7398,7 +7534,7 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond, switch (new_cond->argument_list()->elements) { case 0: - return 0; + return 0; case 1: return new_cond->argument_list()->head(); default: @@ -7413,12 +7549,12 @@ int set_statement_var_if_exists(THD *thd, const char *var_name, size_t var_name_length, ulonglong value) { sys_var *sysvar; - if (thd->lex->sql_command == SQLCOM_CREATE_VIEW) + if (unlikely(thd->lex->sql_command == SQLCOM_CREATE_VIEW)) { my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "[NO]WAIT"); return 1; } - if (thd->lex->sphead) + if (unlikely(thd->lex->sphead)) { my_error(ER_SP_BADSTATEMENT, MYF(0), "[NO]WAIT"); return 1; @@ -7429,7 +7565,8 @@ int set_statement_var_if_exists(THD *thd, const char *var_name, set_var *var= new (thd->mem_root) set_var(thd, OPT_SESSION, sysvar, &null_clex_str, item); - if (!item || !var || thd->lex->stmt_var_list.push_back(var, thd->mem_root)) + if (unlikely(!item) || unlikely(!var) || + unlikely(thd->lex->stmt_var_list.push_back(var, thd->mem_root))) { my_error(ER_OUT_OF_RESOURCES, MYF(0)); return 1; @@ -7452,7 +7589,7 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name) i= new (thd->mem_root) sp_instr_cfetch(sphead->instructions(), spcont, offset, !(thd->variables.sql_mode & MODE_ORACLE)); - if (i == NULL || sphead->add_instr(i)) + if (unlikely(i == NULL) || unlikely(sphead->add_instr(i))) return true; return false; } @@ -7462,10 +7599,10 @@ bool LEX::create_or_alter_view_finalize(THD *thd, Table_ident *table_ident) { sql_command= SQLCOM_CREATE_VIEW; /* first table in list is target VIEW name */ - if (!select_lex.add_table_to_list(thd, table_ident, NULL, - TL_OPTION_UPDATING, - TL_IGNORE, - MDL_EXCLUSIVE)) + if (unlikely(!select_lex.add_table_to_list(thd, table_ident, NULL, + TL_OPTION_UPDATING, + TL_IGNORE, + MDL_EXCLUSIVE))) return true; query_tables->open_strategy= TABLE_LIST::OPEN_STUB; return false; @@ -7476,13 +7613,13 @@ bool LEX::add_alter_view(THD *thd, uint16 algorithm, enum_view_suid suid, Table_ident *table_ident) { - if (sphead) + if (unlikely(sphead)) { my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW"); return true; } - if (!(create_view= new (thd->mem_root) - Create_view_info(VIEW_ALTER, algorithm, suid))) + if (unlikely(!(create_view= new (thd->mem_root) + Create_view_info(VIEW_ALTER, algorithm, suid)))) return true; return create_or_alter_view_finalize(thd, table_ident); } @@ -7492,13 +7629,13 @@ bool LEX::add_create_view(THD *thd, DDL_options_st ddl, uint16 algorithm, enum_view_suid suid, Table_ident *table_ident) { - if (set_create_options_with_check(ddl)) + if (unlikely(set_create_options_with_check(ddl))) return true; - if (!(create_view= new (thd->mem_root) - Create_view_info(ddl.or_replace() ? - VIEW_CREATE_OR_REPLACE : - VIEW_CREATE_NEW, - algorithm, suid))) + if (unlikely(!(create_view= new (thd->mem_root) + Create_view_info(ddl.or_replace() ? + VIEW_CREATE_OR_REPLACE : + VIEW_CREATE_NEW, + algorithm, suid)))) return true; return create_or_alter_view_finalize(thd, table_ident); } @@ -7510,10 +7647,10 @@ bool LEX::call_statement_start(THD *thd, sp_name *name) const Sp_handler *sph= &sp_handler_procedure; sql_command= SQLCOM_CALL; value_list.empty(); - if (sph->sp_resolve_package_routine(thd, thd->lex->sphead, - name, &sph, &pkgname)) + if (unlikely(sph->sp_resolve_package_routine(thd, thd->lex->sphead, + name, &sph, &pkgname))) return true; - if (!(m_sql_cmd= new (thd->mem_root) Sql_cmd_call(name, sph))) + if (unlikely(!(m_sql_cmd= new (thd->mem_root) Sql_cmd_call(name, sph)))) return true; sph->add_used_routine(this, thd, name); if (pkgname.m_name.length) @@ -7525,7 +7662,7 @@ bool LEX::call_statement_start(THD *thd, sp_name *name) bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name) { sp_name *spname= make_sp_name(thd, name); - return !spname || call_statement_start(thd, spname); + return unlikely(!spname) || call_statement_start(thd, spname); } @@ -7533,7 +7670,7 @@ bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name1, const LEX_CSTRING *name2) { sp_name *spname= make_sp_name(thd, name1, name2); - return !spname || call_statement_start(thd, spname); + return unlikely(!spname) || call_statement_start(thd, spname); } @@ -7550,12 +7687,13 @@ sp_package *LEX::create_package_start(THD *thd, DDL_options_st options) { sp_package *pkg; - if (sphead) + + if (unlikely(sphead)) { my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), sph->type_str()); return NULL; } - if (set_command_with_check(command, options)) + if (unlikely(set_command_with_check(command, options))) return NULL; if (sph->type() == TYPE_ENUM_PACKAGE_BODY) { @@ -7577,7 +7715,7 @@ sp_package *LEX::create_package_start(THD *thd, sp_head *spec; int ret= sp_handler_package_spec. sp_cache_routine_reentrant(thd, name_arg, &spec); - if (!spec) + if (unlikely(!spec)) { if (!ret) my_error(ER_SP_DOES_NOT_EXIST, MYF(0), @@ -7585,7 +7723,7 @@ sp_package *LEX::create_package_start(THD *thd, return 0; } } - if (!(pkg= new sp_package(this, name_arg, sph))) + if (unlikely(!(pkg= new sp_package(this, name_arg, sph)))) return NULL; pkg->reset_thd_mem_root(thd); pkg->init(this); @@ -7613,7 +7751,8 @@ bool LEX::create_package_finalize(THD *thd, return true; } sphead->m_body.length= body_end - body_start; - if (!(sphead->m_body.str= thd->strmake(body_start, sphead->m_body.length))) + if (unlikely(!(sphead->m_body.str= thd->strmake(body_start, + sphead->m_body.length)))) return true; size_t not_used; @@ -7670,20 +7809,24 @@ Item *LEX::make_item_func_replace(THD *thd, } -bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name) +bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, + const LEX_CSTRING field_name) { DBUG_ASSERT(field_name.str); Item_field *fld= new (thd->mem_root) Item_field(thd, &context, - table->db.str, table->alias.str, &field_name); - if (!fld || item_list.push_back(fld)) + table->db.str, + table->alias.str, + &field_name); + if (unlikely(!fld) || unlikely(item_list.push_back(fld))) return true; if (thd->lex->view_list.elements) { LEX_CSTRING *l; - if (!(l= thd->make_clex_string(field_name.str, field_name.length))) + if (unlikely(!(l= thd->make_clex_string(field_name.str, + field_name.length))) || + unlikely(thd->lex->view_list.push_back(l))) return true; - thd->lex->view_list.push_back(l); } return false; @@ -7875,3 +8018,277 @@ void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond, *remaining_cond= cond; } + + +Item *LEX::create_item_qualified_asterisk(THD *thd, + const Lex_ident_sys_st *name) +{ + Item *item; + if (!(item= new (thd->mem_root) Item_field(thd, current_context(), + NullS, name->str, + &star_clex_str))) + return NULL; + current_select->with_wild++; + return item; +} + + +Item *LEX::make_item_func_call_generic(THD *thd, Lex_ident_cli_st *cdb, + Lex_ident_cli_st *cname, List<Item> *args) +{ + Lex_ident_sys db(thd, cdb), name(thd, cname); + if (db.is_null() || name.is_null()) + return NULL; // EOM + /* + The following in practice calls: + <code>Create_sp_func::create()</code> + and builds a stored function. + + However, it's important to maintain the interface between the + parser and the implementation in item_create.cc clean, + since this will change with WL#2128 (SQL PATH): + - INFORMATION_SCHEMA.version() is the SQL 99 syntax for the native + function version(), + - MySQL.version() is the SQL 2003 syntax for the native function + version() (a vendor can specify any schema). + */ + + if (!name.str || check_db_name((LEX_STRING*) static_cast<LEX_CSTRING*>(&db))) + { + my_error(ER_WRONG_DB_NAME, MYF(0), db.str); + return NULL; + } + if (check_routine_name(&name)) + return NULL; + + Create_qfunc *builder= find_qualified_function_builder(thd); + DBUG_ASSERT(builder); + return builder->create_with_db(thd, &db, &name, true, args); +} + + +Item *LEX::create_item_qualified_asterisk(THD *thd, + const Lex_ident_sys_st *a, + const Lex_ident_sys_st *b) +{ + Item *item; + const char* schema= thd->client_capabilities & CLIENT_NO_SCHEMA ? + NullS : a->str; + if (!(item= new (thd->mem_root) Item_field(thd, current_context(), + schema, b->str, + &star_clex_str))) + return NULL; + current_select->with_wild++; + return item; +} + + +bool Lex_ident_sys_st::copy_ident_cli(THD *thd, const Lex_ident_cli_st *str) +{ + return thd->to_ident_sys_alloc(this, str); +} + +bool Lex_ident_sys_st::copy_keyword(THD *thd, const Lex_ident_cli_st *str) +{ + return thd->make_lex_string(static_cast<LEX_CSTRING*>(this), + str->str, str->length) == NULL; +} + +bool Lex_ident_sys_st::copy_or_convert(THD *thd, + const Lex_ident_cli_st *src, + CHARSET_INFO *cs) +{ + if (!src->is_8bit()) + return copy_keyword(thd, src); // 7bit string makes a wellformed identifier + return convert(thd, src, cs); +} + + +bool Lex_ident_sys_st::copy_sys(THD *thd, const LEX_CSTRING *src) +{ + if (thd->check_string_for_wellformedness(src->str, src->length, + system_charset_info)) + return true; + return thd->make_lex_string(this, src->str, src->length) == NULL; +} + + +bool Lex_ident_sys_st::convert(THD *thd, + const LEX_CSTRING *src, CHARSET_INFO *cs) +{ + LEX_STRING tmp; + if (thd->convert_with_error(system_charset_info, &tmp, cs, + src->str, src->length)) + return true; + str= tmp.str; + length= tmp.length; + return false; +} + + +bool Lex_ident_sys_st::to_size_number(ulonglong *to) const +{ + ulonglong number; + uint text_shift_number= 0; + longlong prefix_number; + const char *start_ptr= str; + size_t str_len= length; + const char *end_ptr= start_ptr + str_len; + int error; + prefix_number= my_strtoll10(start_ptr, (char**) &end_ptr, &error); + if (likely((start_ptr + str_len - 1) == end_ptr)) + { + switch (end_ptr[0]) + { + case 'g': + case 'G': text_shift_number+=30; break; + case 'm': + case 'M': text_shift_number+=20; break; + case 'k': + case 'K': text_shift_number+=10; break; + default: + my_error(ER_WRONG_SIZE_NUMBER, MYF(0)); + return true; + } + if (unlikely(prefix_number >> 31)) + { + my_error(ER_SIZE_OVERFLOW_ERROR, MYF(0)); + return true; + } + number= prefix_number << text_shift_number; + } + else + { + my_error(ER_WRONG_SIZE_NUMBER, MYF(0)); + return true; + } + *to= number; + return false; +} + + +bool LEX::part_values_current(THD *thd) +{ + partition_element *elem= part_info->curr_part_elem; + if (!is_partition_management()) + { + if (unlikely(part_info->part_type != VERSIONING_PARTITION)) + { + my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + return true; + } + } + else + { + DBUG_ASSERT(create_last_non_select_table); + DBUG_ASSERT(create_last_non_select_table->table_name.str); + // FIXME: other ALTER commands? + my_error(ER_VERS_WRONG_PARTS, MYF(0), + create_last_non_select_table->table_name.str); + return true; + } + elem->type(partition_element::CURRENT); + DBUG_ASSERT(part_info->vers_info); + part_info->vers_info->now_part= elem; + if (unlikely(part_info->init_column_part(thd))) + return true; + return false; +} + + +bool LEX::part_values_history(THD *thd) +{ + partition_element *elem= part_info->curr_part_elem; + if (!is_partition_management()) + { + if (unlikely(part_info->part_type != VERSIONING_PARTITION)) + { + my_error(ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME"); + return true; + } + } + else + { + part_info->vers_init_info(thd); + elem->id= UINT_MAX32; + } + DBUG_ASSERT(part_info->vers_info); + if (unlikely(part_info->vers_info->now_part)) + { + DBUG_ASSERT(create_last_non_select_table); + DBUG_ASSERT(create_last_non_select_table->table_name.str); + my_error(ER_VERS_WRONG_PARTS, MYF(0), + create_last_non_select_table->table_name.str); + return true; + } + elem->type(partition_element::HISTORY); + if (unlikely(part_info->init_column_part(thd))) + return true; + return false; +} + + +bool LEX::last_field_generated_always_as_row_start_or_end(Lex_ident *p, + const char *type, + uint flag) +{ + if (unlikely(p->str)) + { + my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0), type, + last_field->field_name.str); + return true; + } + last_field->flags|= (flag | NOT_NULL_FLAG); + DBUG_ASSERT(p); + *p= last_field->field_name; + return false; +} + + + +bool LEX::last_field_generated_always_as_row_start() +{ + Vers_parse_info &info= vers_get_info(); + Lex_ident *p= &info.as_row.start; + return last_field_generated_always_as_row_start_or_end(p, "START", + VERS_SYS_START_FLAG); +} + + +bool LEX::last_field_generated_always_as_row_end() +{ + Vers_parse_info &info= vers_get_info(); + Lex_ident *p= &info.as_row.end; + return last_field_generated_always_as_row_start_or_end(p, "END", + VERS_SYS_END_FLAG); +} + + +bool LEX::tvc_finalize() +{ + mysql_init_select(this); + if (unlikely(!(current_select->tvc= + new (thd->mem_root) + table_value_constr(many_values, + current_select, + current_select->options)))) + return true; + many_values.empty(); + return false; +} + + +bool LEX::tvc_finalize_derived() +{ + derived_tables|= DERIVED_SUBQUERY; + if (unlikely(!expr_allows_subselect || sql_command == (int)SQLCOM_PURGE)) + { + thd->parse_error(); + return true; + } + if (current_select->linkage == GLOBAL_OPTIONS_TYPE || + unlikely(mysql_new_select(this, 1, NULL))) + return true; + current_select->linkage= DERIVED_TABLE_TYPE; + return tvc_finalize(); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 89e3abe284f..c3ef33ea9dd 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -37,12 +37,16 @@ /** - A string with metadata. + A string with metadata. Usually points to a string in the client + character set, but unlike Lex_ident_cli_st (see below) it does not + necessarily point to a query fragment. It can also point to memory + of other kinds (e.g. an additional THD allocated memory buffer + not overlapping with the current query text). + We'll add more flags here eventually, to know if the string has, e.g.: - multi-byte characters - bad byte sequences - backslash escapes: 'a\nb' - - separator escapes: 'a''b' and reuse the original query fragments instead of making the string copy too early, in Lex_input_stream::get_text(). This will allow to avoid unnecessary copying, as well as @@ -50,9 +54,30 @@ */ struct Lex_string_with_metadata_st: public LEX_CSTRING { +private: bool m_is_8bit; // True if the string has 8bit characters + char m_quote; // Quote character, or 0 if not quoted public: void set_8bit(bool is_8bit) { m_is_8bit= is_8bit; } + void set_metadata(bool is_8bit, char quote) + { + m_is_8bit= is_8bit; + m_quote= quote; + } + void set(const char *s, size_t len, bool is_8bit, char quote) + { + str= s; + length= len; + set_metadata(is_8bit, quote); + } + void set(const LEX_CSTRING *s, bool is_8bit, char quote) + { + ((LEX_CSTRING &)*this)= *s; + set_metadata(is_8bit, quote); + } + bool is_8bit() const { return m_is_8bit; } + bool is_quoted() const { return m_quote != '\0'; } + char quote() const { return m_quote; } // Get string repertoire by the 8-bit flag and the character set uint repertoire(CHARSET_INFO *cs) const { @@ -67,6 +92,76 @@ public: }; +/* + Used to store identifiers in the client character set. + Points to a query fragment. +*/ +struct Lex_ident_cli_st: public Lex_string_with_metadata_st +{ +public: + void set_keyword(const char *s, size_t len) + { + set(s, len, false, '\0'); + } + void set_ident(const char *s, size_t len, bool is_8bit) + { + set(s, len, is_8bit, '\0'); + } + void set_ident_quoted(const char *s, size_t len, bool is_8bit, char quote) + { + set(s, len, is_8bit, quote); + } + void set_unquoted(const LEX_CSTRING *s, bool is_8bit) + { + set(s, is_8bit, '\0'); + } + const char *pos() const { return str - is_quoted(); } + const char *end() const { return str + length + is_quoted(); } +}; + + +class Lex_ident_cli: public Lex_ident_cli_st +{ +public: + Lex_ident_cli(const LEX_CSTRING *s, bool is_8bit) + { + set_unquoted(s, is_8bit); + } + Lex_ident_cli(const char *s, size_t len) + { + set_ident(s, len, false); + } +}; + + +struct Lex_ident_sys_st: public LEX_CSTRING +{ +public: + bool copy_ident_cli(THD *thd, const Lex_ident_cli_st *str); + bool copy_keyword(THD *thd, const Lex_ident_cli_st *str); + bool copy_sys(THD *thd, const LEX_CSTRING *str); + bool convert(THD *thd, const LEX_CSTRING *str, CHARSET_INFO *cs); + bool copy_or_convert(THD *thd, const Lex_ident_cli_st *str, CHARSET_INFO *cs); + bool is_null() const { return str == NULL; } + bool to_size_number(ulonglong *to) const; +}; + + +class Lex_ident_sys: public Lex_ident_sys_st +{ +public: + Lex_ident_sys(THD *thd, const Lex_ident_cli_st *str) + { + if (copy_ident_cli(thd, str)) + ((LEX_CSTRING &) *this)= null_clex_str; + } + Lex_ident_sys() + { + ((LEX_CSTRING &) *this)= null_clex_str; + } +}; + + enum sub_select_type { UNSPECIFIED_TYPE, @@ -173,7 +268,7 @@ struct LEX_TYPE #define LEX_YYSTYPE void * #else #include "lex_symbol.h" -#if MYSQL_LEX +#ifdef MYSQL_LEX #include "item_func.h" /* Cast_target used in sql_yacc.h */ #include "sql_get_diagnostics.h" /* Types used in sql_yacc.h */ #include "sp_pcontext.h" @@ -186,13 +281,13 @@ struct LEX_TYPE #endif // describe/explain types -#define DESCRIBE_NORMAL 1 -#define DESCRIBE_EXTENDED 2 +#define DESCRIBE_NORMAL 1 +#define DESCRIBE_EXTENDED 2 /* This is not within #ifdef because we want "EXPLAIN PARTITIONS ..." to produce additional "partitions" column even if partitioning is not compiled in. */ -#define DESCRIBE_PARTITIONS 4 +#define DESCRIBE_PARTITIONS 4 #ifdef MYSQL_SERVER @@ -224,24 +319,24 @@ enum enum_sp_aggregate_type GROUP_AGGREGATE }; -const LEX_STRING sp_data_access_name[]= +const LEX_CSTRING sp_data_access_name[]= { - { C_STRING_WITH_LEN("") }, - { C_STRING_WITH_LEN("CONTAINS SQL") }, - { C_STRING_WITH_LEN("NO SQL") }, - { C_STRING_WITH_LEN("READS SQL DATA") }, - { C_STRING_WITH_LEN("MODIFIES SQL DATA") } + { STRING_WITH_LEN("") }, + { STRING_WITH_LEN("CONTAINS SQL") }, + { STRING_WITH_LEN("NO SQL") }, + { STRING_WITH_LEN("READS SQL DATA") }, + { STRING_WITH_LEN("MODIFIES SQL DATA") } }; -#define DERIVED_SUBQUERY 1 -#define DERIVED_VIEW 2 +#define DERIVED_SUBQUERY 1 +#define DERIVED_VIEW 2 #define DERIVED_WITH 4 enum enum_view_create_mode { - VIEW_CREATE_NEW, // check that there are not such VIEW/table - VIEW_ALTER, // check that VIEW .frm with such name exists - VIEW_CREATE_OR_REPLACE // check only that there are not such table + VIEW_CREATE_NEW, // check that there are not such VIEW/table + VIEW_ALTER, // check that VIEW .frm with such name exists + VIEW_CREATE_OR_REPLACE // check only that there are not such table }; @@ -273,8 +368,8 @@ enum enum_drop_mode }; /* Options to add_table_to_list() */ -#define TL_OPTION_UPDATING 1 -#define TL_OPTION_FORCE_INDEX 2 +#define TL_OPTION_UPDATING 1 +#define TL_OPTION_FORCE_INDEX 2 #define TL_OPTION_IGNORE_LEAVES 4 #define TL_OPTION_ALIAS 8 #define TL_OPTION_SEQUENCE 16 @@ -749,7 +844,7 @@ public: st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */ bool describe; /* union exec() called for EXPLAIN */ - Procedure *last_procedure; /* Pointer to procedure, if such exists */ + Procedure *last_procedure; /* Pointer to procedure, if such exists */ bool columns_are_renamed; @@ -770,7 +865,8 @@ public: bool is_excluded() { return prev == NULL; } /* UNION methods */ - bool prepare(THD *thd, select_result *result, ulong additional_options); + bool prepare(TABLE_LIST *derived_arg, select_result *sel_result, + ulong additional_options); bool optimize(); bool exec(); bool exec_recursive(); @@ -839,7 +935,7 @@ public: /* Point to the LEX in which it was created, used in view subquery detection. - TODO: make also st_select_lex::parent_stmt_lex (see THD::stmt_lex) + TODO: make also st_select_lex::parent_stmt_lex (see LEX::stmt_lex) and use st_select_lex::parent_lex & st_select_lex::parent_stmt_lex instead of global (from THD) references where it is possible. */ @@ -859,7 +955,7 @@ public: List<Item> item_list; /* list of fields & expressions */ List<Item> pre_fix; /* above list before fix_fields */ - bool is_item_list_lookup; + bool is_item_list_lookup; /* Usualy it is pointer to ftfunc_list_alloc, but in union used to create fake select_lex for calling mysql_select under results of union @@ -942,6 +1038,11 @@ public: uint select_n_where_fields; /* reserved for exists 2 in */ uint select_n_reserved; + /* + it counts the number of bit fields in the SELECT list. These are used when DISTINCT is + converted to a GROUP BY involving BIT fields. + */ + uint hidden_bit_fields; enum_parsing_place parsing_place; /* where we are parsing expression */ enum_parsing_place context_analysis_place; /* where we are in prepare */ bool with_sum_func; /* sum function indicator */ @@ -983,6 +1084,7 @@ public: */ bool subquery_in_having; /* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */ + bool with_all_modifier; /* used for selects in union */ bool is_correlated; /* This variable is required to ensure proper work of subqueries and @@ -1087,11 +1189,11 @@ public: bool add_order_to_list(THD *thd, Item *item, bool asc); bool add_gorder_to_list(THD *thd, Item *item, bool asc); TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table, - LEX_CSTRING *alias, - ulong table_options, - thr_lock_type flags= TL_UNLOCK, + LEX_CSTRING *alias, + ulong table_options, + thr_lock_type flags= TL_UNLOCK, enum_mdl_type mdl_type= MDL_SHARED_READ, - List<Index_hint> *hints= 0, + List<Index_hint> *hints= 0, List<String> *partition_names= 0, LEX_STRING *option= 0); TABLE_LIST* get_table_list(); @@ -1242,7 +1344,7 @@ public: void collect_grouping_fields(THD *thd, ORDER *grouping_list); void check_cond_extraction_for_grouping_fields(Item *cond); Item *build_cond_for_grouping_fields(THD *thd, Item *cond, - bool no_to_clones); + bool no_to_clones); List<Window_spec> window_specs; void prepare_add_window_spec(THD *thd); @@ -2065,6 +2167,16 @@ public: void reset(char *buff, size_t length); /** + The main method to scan the next token, with token contraction processing + for LALR(2) resolution, e.g. translate "WITH" followed by "ROLLUP" + to a single token WITH_ROLLUP_SYM. + */ + int lex_token(union YYSTYPE *yylval, THD *thd); + + void reduce_digest_token(uint token_left, uint token_right); + +private: + /** Set the echo mode. When echo is true, characters parsed from the raw input stream are @@ -2193,15 +2305,6 @@ public: /** End of file indicator for the query text to parse. - @return true if there are no more characters to parse - */ - bool eof() - { - return (m_ptr >= m_end_of_query); - } - - /** - End of file indicator for the query text to parse. @param n number of characters expected @return true if there are less than n characters to parse */ @@ -2210,24 +2313,6 @@ public: return ((m_ptr + n) >= m_end_of_query); } - /** Get the raw query buffer. */ - const char *get_buf() - { - return m_buf; - } - - /** Get the pre-processed query buffer. */ - const char *get_cpp_buf() - { - return m_cpp_buf; - } - - /** Get the end of the raw query buffer. */ - const char *get_end_of_query() - { - return m_end_of_query; - } - /** Mark the stream position as the start of a new token. */ void start_token() { @@ -2250,10 +2335,65 @@ public: m_cpp_tok_start= m_cpp_ptr; } + /** + Get the maximum length of the utf8-body buffer. + The utf8 body can grow because of the character set conversion and escaping. + */ + size_t get_body_utf8_maximum_length(THD *thd); + + /** Get the length of the current token, in the raw buffer. */ + uint yyLength() + { + /* + The assumption is that the lexical analyser is always 1 character ahead, + which the -1 account for. + */ + DBUG_ASSERT(m_ptr > m_tok_start); + return (uint) ((m_ptr - m_tok_start) - 1); + } + + /** + Test if a lookahead token was already scanned by lex_token(), + for LALR(2) resolution. + */ + bool has_lookahead() const + { + return lookahead_token >= 0; + } + +public: + + /** + End of file indicator for the query text to parse. + @return true if there are no more characters to parse + */ + bool eof() + { + return (m_ptr >= m_end_of_query); + } + + /** Get the raw query buffer. */ + const char *get_buf() + { + return m_buf; + } + + /** Get the pre-processed query buffer. */ + const char *get_cpp_buf() + { + return m_cpp_buf; + } + + /** Get the end of the raw query buffer. */ + const char *get_end_of_query() + { + return m_end_of_query; + } + /** Get the token start position, in the raw buffer. */ const char *get_tok_start() { - return m_tok_start; + return has_lookahead() ? m_tok_start_prev : m_tok_start; } void set_cpp_tok_start(const char *pos) @@ -2267,39 +2407,16 @@ public: return m_tok_end; } - /** Get the previous token start position, in the raw buffer. */ - const char *get_tok_start_prev() - { - return m_tok_start_prev; - } - /** Get the current stream pointer, in the raw buffer. */ const char *get_ptr() { return m_ptr; } - /** Get the length of the current token, in the raw buffer. */ - uint yyLength() - { - /* - The assumption is that the lexical analyser is always 1 character ahead, - which the -1 account for. - */ - DBUG_ASSERT(m_ptr > m_tok_start); - return (uint) ((m_ptr - m_tok_start) - 1); - } - - /** Get the previus token start position, in the pre-processed buffer. */ - const char *get_cpp_start_prev() - { - return m_cpp_tok_start_prev; - } - /** Get the token start position, in the pre-processed buffer. */ const char *get_cpp_tok_start() { - return m_cpp_tok_start; + return has_lookahead() ? m_cpp_tok_start_prev : m_cpp_tok_start; } /** Get the token end position, in the pre-processed buffer. */ @@ -2353,32 +2470,19 @@ public: return (size_t) (m_body_utf8_ptr - m_body_utf8); } - /** - Get the maximum length of the utf8-body buffer. - The utf8 body can grow because of the character set conversion and escaping. - */ - size_t get_body_utf8_maximum_length(THD *thd); - void body_utf8_start(THD *thd, const char *begin_ptr); void body_utf8_append(const char *ptr); void body_utf8_append(const char *ptr, const char *end_ptr); void body_utf8_append_ident(THD *thd, - const LEX_CSTRING *txt, + const Lex_string_with_metadata_st *txt, const char *end_ptr); void body_utf8_append_escape(THD *thd, const LEX_CSTRING *txt, CHARSET_INFO *txt_cs, const char *end_ptr, my_wc_t sep); - /** Current thread. */ - THD *m_thd; - - /** Current line number. */ - uint yylineno; - - /** Interface with bison, value of the last token parsed. */ - LEX_YYSTYPE yylval; +private: /** LALR(2) resolution, look ahead token. Value of the next token to return, if any, @@ -2395,9 +2499,20 @@ public: void add_digest_token(uint token, LEX_YYSTYPE yylval); - void reduce_digest_token(uint token_left, uint token_right); + bool consume_comment(int remaining_recursions_permitted); + int lex_one_token(union YYSTYPE *yylval, THD *thd); + int find_keyword(Lex_ident_cli_st *str, uint len, bool function); + LEX_CSTRING get_token(uint skip, uint length); + int scan_ident_sysvar(THD *thd, Lex_ident_cli_st *str); + int scan_ident_start(THD *thd, Lex_ident_cli_st *str); + int scan_ident_middle(THD *thd, Lex_ident_cli_st *str, + CHARSET_INFO **cs, my_lex_states *); + int scan_ident_delimited(THD *thd, Lex_ident_cli_st *str); + bool get_7bit_or_8bit_ident(THD *thd, uchar *last_char); + + /** Current thread. */ + THD *m_thd; -private: /** Pointer to the current position in the raw input stream. */ char *m_ptr; @@ -2483,6 +2598,15 @@ public: */ bool multi_statements; + /** Current line number. */ + uint yylineno; + + /** + Current statement digest instrumentation. + */ + sql_digest_state* m_digest; + +private: /** State of the lexical analyser for comments. */ enum_comment_state in_comment; enum_comment_state in_comment_saved; @@ -2509,13 +2633,9 @@ public: NOTE: this member must be used within MYSQLlex() function only. */ CHARSET_INFO *m_underscore_cs; - - /** - Current statement digest instrumentation. - */ - sql_digest_state* m_digest; }; + /** Abstract representation of a statement. This class is an interface between the parser and the runtime. @@ -2691,10 +2811,25 @@ struct LEX: public Query_tables_list // type information CHARSET_INFO *charset; + /* + LEX which represents current statement (conventional, SP or PS) + + For example during view parsing THD::lex will point to the views LEX and + lex::stmt_lex will point to LEX of the statement where the view will be + included + + Currently it is used to have always correct select numbering inside + statement (LEX::current_select_number) without storing and restoring a + global counter which was THD::select_number. + + TODO: make some unified statement representation (now SP has different) + to store such data like LEX::current_select_number. + */ + LEX *stmt_lex; LEX_CSTRING name; const char *help_arg; - const char *backup_dir; /* For RESTORE/BACKUP */ + const char *backup_dir; /* For RESTORE/BACKUP */ const char* to_log; /* For PURGE MASTER LOGS TO */ const char* x509_subject,*x509_issuer,*ssl_cipher; String *wild; /* Wildcard in SHOW {something} LIKE 'wild'*/ @@ -2732,7 +2867,7 @@ struct LEX: public Query_tables_list List<Key_part_spec> ref_list; List<LEX_USER> users_list; List<LEX_COLUMN> columns; - List<Item> *insert_list,field_list,value_list,update_list; + List<Item> *insert_list,field_list,value_list,update_list; List<List_item> many_values; List<set_var_base> var_list; List<set_var_base> stmt_var_list; //SET_STATEMENT values @@ -2785,10 +2920,10 @@ public: Column_definition *last_field; Item_sum *in_sum_func; udf_func udf; - HA_CHECK_OPT check_opt; // check/repair options + HA_CHECK_OPT check_opt; // check/repair options Table_specification_st create_info; Key *last_key; - LEX_MASTER_INFO mi; // used by CHANGE MASTER + LEX_MASTER_INFO mi; // used by CHANGE MASTER LEX_SERVER_OPTIONS server_options; LEX_CSTRING relay_log_connection_name; USER_RESOURCES mqh; @@ -2827,7 +2962,7 @@ public: */ bool parse_vcol_expr; - enum SSL_type ssl_type; /* defined in violite.h */ + enum SSL_type ssl_type; // defined in violite.h enum enum_duplicates duplicates; enum enum_tx_isolation tx_isolation; enum enum_ha_read_modes ha_read_mode; @@ -2888,7 +3023,7 @@ public: List<Item> prepared_stmt_params; sp_head *sphead; sp_name *spname; - bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ + bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling bool all_privileges; bool proxy_priv; @@ -3149,7 +3284,10 @@ public: void restore_backup_query_tables_list(Query_tables_list *backup); bool table_or_sp_used(); + bool is_partition_management() const; + bool part_values_current(THD *thd); + bool part_values_history(THD *thd); /** @brief check if the statement is a single-level join @@ -3181,6 +3319,11 @@ public: void init_last_field(Column_definition *field, const LEX_CSTRING *name, const CHARSET_INFO *cs); + bool last_field_generated_always_as_row_start_or_end(Lex_ident *p, + const char *type, + uint flags); + bool last_field_generated_always_as_row_start(); + bool last_field_generated_always_as_row_end(); bool set_bincmp(CHARSET_INFO *cs, bool bin); bool get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer); @@ -3304,20 +3447,42 @@ public: bool sp_open_cursor(THD *thd, const LEX_CSTRING *name, List<sp_assignment_lex> *parameters); - Item_splocal *create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar, - const char *start, const char *end); + Item_splocal *create_item_for_sp_var(const Lex_ident_cli_st *name, + sp_variable *spvar); + + Item *create_item_qualified_asterisk(THD *thd, const Lex_ident_sys_st *name); + Item *create_item_qualified_asterisk(THD *thd, + const Lex_ident_sys_st *a, + const Lex_ident_sys_st *b); + Item *create_item_qualified_asterisk(THD *thd, const Lex_ident_cli_st *cname) + { + Lex_ident_sys name(thd, cname); + if (name.is_null()) + return NULL; // EOM + return create_item_qualified_asterisk(thd, &name); + } + Item *create_item_qualified_asterisk(THD *thd, + const Lex_ident_cli_st *ca, + const Lex_ident_cli_st *cb) + { + Lex_ident_sys a(thd, ca), b(thd, cb); + if (a.is_null() || b.is_null()) + return NULL; // EOM + return create_item_qualified_asterisk(thd, &a, &b); + } - Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name); - Item *create_item_ident_sp(THD *thd, LEX_CSTRING *name, + Item *create_item_ident_nosp(THD *thd, Lex_ident_sys_st *name); + Item *create_item_ident_sp(THD *thd, Lex_ident_sys_st *name, const char *start, const char *end); - Item *create_item_ident(THD *thd, LEX_CSTRING *name, - const char *start, const char *end) + Item *create_item_ident(THD *thd, Lex_ident_cli_st *cname) { + Lex_ident_sys name(thd, cname); + if (name.is_null()) + return NULL; // EOM return sphead ? - create_item_ident_sp(thd, name, start, end) : - create_item_ident_nosp(thd, name); + create_item_ident_sp(thd, &name, cname->pos(), cname->end()) : + create_item_ident_nosp(thd, &name); } - /* Create an Item corresponding to a qualified name: a.b when the parser is out of an SP context. @@ -3332,8 +3497,8 @@ public: - Item_ref */ Item *create_item_ident_nospvar(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b); + const Lex_ident_sys_st *a, + const Lex_ident_sys_st *b); /* Create an Item corresponding to a ROW field valiable: var.field @param THD - THD, for mem_root @@ -3347,8 +3512,8 @@ public: */ Item_splocal *create_item_spvar_row_field(THD *thd, const Sp_rcontext_handler *rh, - const LEX_CSTRING *var, - const LEX_CSTRING *field, + const Lex_ident_sys *var, + const Lex_ident_sys *field, sp_variable *spvar, const char *start, const char *end); @@ -3361,15 +3526,11 @@ public: @param thd - THD, for mem_root @param a - the first name @param b - the second name - @param start - position in the query (for binary log) - @param end - end in the query (for binary log) @retval - NULL on error, or a pointer to a new Item. */ Item *create_item_ident(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b, - const char *start, - const char *end); + const Lex_ident_cli_st *a, + const Lex_ident_cli_st *b); /* Create an item from its qualified name. Depending on context, it can be a table field, a table field reference, @@ -3381,9 +3542,27 @@ public: @retval - NULL on error, or a pointer to a new Item. */ Item *create_item_ident(THD *thd, - const LEX_CSTRING *a, - const LEX_CSTRING *b, - const LEX_CSTRING *c); + const Lex_ident_sys_st *a, + const Lex_ident_sys_st *b, + const Lex_ident_sys_st *c); + + Item *create_item_ident(THD *thd, + const Lex_ident_cli_st *ca, + const Lex_ident_cli_st *cb, + const Lex_ident_cli_st *cc) + { + Lex_ident_sys b(thd, cb), c(thd, cc); + if (b.is_null() || c.is_null()) + return NULL; + if (ca->pos() == cb->pos()) // SELECT .t1.col1 + { + DBUG_ASSERT(ca->length == 0); + Lex_ident_sys none; + return create_item_ident(thd, &none, &b, &c); + } + Lex_ident_sys a(thd, ca); + return a.is_null() ? NULL : create_item_ident(thd, &a, &b, &c); + } /* Create an item for "NEXT VALUE FOR sequence_name" @@ -3408,16 +3587,11 @@ public: Create an item for a name in LIMIT clause: LIMIT var @param THD - THD, for mem_root @param var_name - the variable name - @param start - position in the query (for binary log) - @param end - end in the query (for binary log) @retval - a new Item corresponding to the SP variable, or NULL on error (non in SP, unknown variable, wrong data type). */ - Item *create_item_limit(THD *thd, - const LEX_CSTRING *var_name, - const char *start, - const char *end); + Item *create_item_limit(THD *thd, const Lex_ident_cli_st *var_name); /* Create an item for a qualified name in LIMIT clause: LIMIT var.field @@ -3432,14 +3606,14 @@ public: wrong data type). */ Item *create_item_limit(THD *thd, - const LEX_CSTRING *var_name, - const LEX_CSTRING *field_name, - const char *start, - const char *end); + const Lex_ident_cli_st *var_name, + const Lex_ident_cli_st *field_name); Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace); Item *make_item_func_substr(THD *thd, Item *a, Item *b, Item *c); Item *make_item_func_substr(THD *thd, Item *a, Item *b); + Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db, + Lex_ident_cli_st *name, List<Item> *args); my_var *create_outvar(THD *thd, const LEX_CSTRING *name); /* @@ -3457,7 +3631,21 @@ public: Item *create_and_link_Item_trigger_field(THD *thd, const LEX_CSTRING *name, bool new_row); - + // For syntax with colon, e.g. :NEW.a or :OLD.a + Item *make_item_colon_ident_ident(THD *thd, + const Lex_ident_cli_st *a, + const Lex_ident_cli_st *b); + // For "SELECT @@var", "SELECT @@var.field" + Item *make_item_sysvar(THD *thd, + enum_var_type type, + const LEX_CSTRING *name) + { + return make_item_sysvar(thd, type, name, &null_clex_str); + } + Item *make_item_sysvar(THD *thd, + enum_var_type type, + const LEX_CSTRING *name, + const LEX_CSTRING *component); void sp_block_init(THD *thd, const LEX_CSTRING *label); void sp_block_init(THD *thd) { @@ -3529,7 +3717,7 @@ public: Item *value); sp_variable *sp_add_for_loop_upper_bound(THD *thd, Item *value) { - LEX_CSTRING name= { C_STRING_WITH_LEN("[upper_bound]") }; + LEX_CSTRING name= { STRING_WITH_LEN("[upper_bound]") }; return sp_add_for_loop_variable(thd, &name, value); } bool sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop, @@ -3753,6 +3941,34 @@ public: return create_info.vers_info; } sp_package *get_sp_package() const; + + /** + Check if the select is a simple select (not an union). + @retval + 0 ok + @retval + 1 error ; In this case the error messege is sent to the client + */ + bool check_simple_select(const LEX_CSTRING *option) + { + if (current_select != &select_lex) + { + char command[80]; + strmake(command, option->str, MY_MIN(option->length, sizeof(command)-1)); + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command); + return true; + } + return false; + } + + void tvc_start() + { + field_list.empty(); + many_values.empty(); + insert_list= 0; + } + bool tvc_finalize(); + bool tvc_finalize_derived(); }; diff --git a/sql/sql_lifo_buffer.h b/sql/sql_lifo_buffer.h index 17024d15beb..62b23e7773a 100644 --- a/sql/sql_lifo_buffer.h +++ b/sql/sql_lifo_buffer.h @@ -84,7 +84,7 @@ public: start= start_arg; end= end_arg; if (end != start) - TRASH_ALLOC(start, end - start); + TRASH_ALLOC(start, size_t(end - start)); reset(); } @@ -224,7 +224,7 @@ public: { DBUG_ASSERT(unused_end >= unused_start); DBUG_ASSERT(end == unused_start); - TRASH_ALLOC(unused_start, unused_end - unused_start); + TRASH_ALLOC(unused_start, size_t(unused_end - unused_start)); end= unused_end; } /* Return pointer to start of the memory area that is occupied by the data */ diff --git a/sql/sql_list.h b/sql/sql_list.h index 311e601490b..0219c226803 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -138,6 +138,13 @@ public: first == rhs.first && last == rhs.last; } + base_list& operator=(const base_list &rhs) + { + elements= rhs.elements; + first= rhs.first; + last= elements ? rhs.last : &first; + return *this; + } inline void empty() { elements=0; first= &end_of_list; last=&first;} inline base_list() { empty(); } @@ -152,9 +159,7 @@ public: */ inline base_list(const base_list &tmp) :Sql_alloc() { - elements= tmp.elements; - first= tmp.first; - last= elements ? tmp.last : &first; + *this= tmp; } /** Construct a deep copy of the argument in memory root mem_root. @@ -164,7 +169,7 @@ public: */ bool copy(const base_list *rhs, MEM_ROOT *mem_root); base_list(const base_list &rhs, MEM_ROOT *mem_root) { copy(&rhs, mem_root); } - inline base_list(bool error) { } + inline base_list(bool) {} inline bool push_back(void *info) { if (((*last)=new list_node(info, &end_of_list))) @@ -533,10 +538,10 @@ public: template <class T> class List_iterator_fast :public base_list_iterator { protected: - inline T *replace(T *a) { return (T*) 0; } - inline T *replace(List<T> &a) { return (T*) 0; } - inline void remove(void) { } - inline void after(T *a) { } + inline T *replace(T *) { return (T*) 0; } + inline T *replace(List<T> &) { return (T*) 0; } + inline void remove(void) {} + inline void after(T *) {} inline T** ref(void) { return (T**) 0; } public: @@ -605,7 +610,7 @@ struct ilink { return (void*)my_malloc((uint)size, MYF(MY_WME | MY_FAE | ME_FATALERROR)); } - static void operator delete(void* ptr_arg, size_t size) + static void operator delete(void* ptr_arg, size_t) { my_free(ptr_arg); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index cfa92f170ab..cc5a5c7c794 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -444,6 +444,9 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, field_iterator.set(table_list); for (; !field_iterator.end_of_fields(); field_iterator.next()) { + if (field_iterator.field() && + field_iterator.field()->invisible > VISIBLE) + continue; Item *item; if (!(item= field_iterator.create_item(thd))) DBUG_RETURN(TRUE); @@ -593,7 +596,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, *ex->field_term, *ex->line_start, *ex->line_term, *ex->enclosed, info.escape_char, read_file_from_client, is_fifo); - if (read_info.error) + if (unlikely(read_info.error)) { if (file >= 0) mysql_file_close(file, MYF(0)); // no files in net reading @@ -625,7 +628,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, } thd_proc_info(thd, "Reading file"); - if (!(error= MY_TEST(read_info.error))) + if (likely(!(error= MY_TEST(read_info.error)))) { table->reset_default_fields(); table->next_number_field=table->found_next_number_field; @@ -662,7 +665,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, *ex->enclosed, skip_lines, ignore); thd_proc_info(thd, "End bulk insert"); - if (!error) + if (likely(!error)) thd_progress_next_stage(thd); if (thd->locked_tables_mode <= LTM_LOCK_TABLES && table->file->ha_end_bulk_insert() && !error) @@ -787,7 +790,7 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list, */ error= error || mysql_bin_log.get_log_file()->error; } - if (error) + if (unlikely(error)) goto err; } #endif /*!EMBEDDED_LIBRARY*/ @@ -1110,11 +1113,11 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, } } - if (thd->is_error()) + if (unlikely(thd->is_error())) read_info.error= 1; - - if (read_info.error) + if (unlikely(read_info.error)) break; + if (skip_lines) { skip_lines--; @@ -1129,16 +1132,16 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, { Load_data_outvar *dst= item->get_load_data_outvar_or_error(); DBUG_ASSERT(dst); - if (dst->load_data_set_no_data(thd, &read_info)) + if (unlikely(dst->load_data_set_no_data(thd, &read_info))) DBUG_RETURN(1); } } - if (thd->killed || - fill_record_n_invoke_before_triggers(thd, table, set_fields, - set_values, - ignore_check_option_errors, - TRG_EVENT_INSERT)) + if (unlikely(thd->killed) || + unlikely(fill_record_n_invoke_before_triggers(thd, table, set_fields, + set_values, + ignore_check_option_errors, + TRG_EVENT_INSERT))) DBUG_RETURN(1); switch (table_list->view_check_option(thd, @@ -1247,7 +1250,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, DBUG_RETURN(1); } - if (read_info.error) + if (unlikely(read_info.error)) break; if (skip_lines) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 09ef7a587ba..e136f271fb7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -420,7 +420,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) /* - Implicitly commit a active transaction if statement requires so. + Check whether the statement implicitly commits an active transaction. @param thd Thread handle. @param mask Bitmask used for the SQL command match. @@ -428,7 +428,7 @@ static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables) @return 0 No implicit commit @return 1 Do a commit */ -static bool stmt_causes_implicit_commit(THD *thd, uint mask) +bool stmt_causes_implicit_commit(THD *thd, uint mask) { LEX *lex= thd->lex; bool skip= FALSE; @@ -775,6 +775,8 @@ void init_update_queries(void) There are other statements that deal with temporary tables and open them, but which are not listed here. The thing is that the order of pre-opening temporary tables for those statements is somewhat custom. + + Note that SQLCOM_RENAME_TABLE should not be in this list! */ sql_command_flags[SQLCOM_CREATE_TABLE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DROP_TABLE]|= CF_PREOPEN_TMP_TABLES; @@ -789,7 +791,6 @@ void init_update_queries(void) sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES; - sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES; @@ -952,7 +953,7 @@ static char *fgets_fn(char *buffer, size_t size, fgets_input_t input, int *error { MYSQL_FILE *in= static_cast<MYSQL_FILE*> (input); char *line= mysql_file_fgets(buffer, (int)size, in); - if (error) + if (unlikely(error)) *error= (line == NULL) ? ferror(in->m_file) : 0; return line; } @@ -1066,7 +1067,7 @@ static void handle_bootstrap_impl(THD *thd) #endif delete_explain_query(thd->lex); - if (bootstrap_error) + if (unlikely(bootstrap_error)) break; thd->reset_kill_query(); /* Ensure that killed_errmsg is released */ @@ -1214,13 +1215,13 @@ bool do_command(THD *thd) #ifdef WITH_WSREP if (WSREP(thd)) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_query_state= QUERY_IDLE; if (thd->wsrep_conflict_state==MUST_ABORT) { wsrep_client_rollback(thd); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ @@ -1266,15 +1267,15 @@ bool do_command(THD *thd) packet_length= my_net_read_packet(net, 1); #ifdef WITH_WSREP if (WSREP(thd)) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); /* these THD's are aborted or are aborting during being idle */ if (thd->wsrep_conflict_state == ABORTING) { while (thd->wsrep_conflict_state == ABORTING) { - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); my_sleep(1000); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); } thd->store_globals(); } @@ -1284,11 +1285,11 @@ bool do_command(THD *thd) } thd->wsrep_query_state= QUERY_EXEC; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ - if (packet_length == packet_error) + if (unlikely(packet_length == packet_error)) { DBUG_PRINT("info",("Got error %d reading command from socket %s", net->error, @@ -1297,14 +1298,14 @@ bool do_command(THD *thd) #ifdef WITH_WSREP if (WSREP(thd)) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state == MUST_ABORT) { DBUG_PRINT("wsrep",("aborted for wsrep rollback: %lu", (ulong) thd->real_id)); wsrep_client_rollback(thd); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ @@ -1582,7 +1583,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->wsrep_PA_safe= true; } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_query_state= QUERY_EXEC; if (thd->wsrep_conflict_state== RETRY_AUTOCOMMIT) { @@ -1599,14 +1600,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, my_message(ER_LOCK_DEADLOCK, "Deadlock: wsrep aborted transaction", MYF(0)); WSREP_DEBUG("Deadlock error for: %s", thd->query()); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); thd->reset_killed(); thd->mysys_var->abort = 0; thd->wsrep_conflict_state = NO_CONFLICT; thd->wsrep_retry_counter = 0; goto dispatch_end; } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ #if defined(ENABLED_PROFILING) @@ -1686,8 +1687,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { LEX_CSTRING tmp; status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]); - if (thd->copy_with_error(system_charset_info, (LEX_STRING*) &tmp, - thd->charset(), packet, packet_length)) + if (unlikely(thd->copy_with_error(system_charset_info, (LEX_STRING*) &tmp, + thd->charset(), packet, packet_length))) break; if (!mysql_change_db(thd, &tmp, FALSE)) { @@ -1819,7 +1820,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->m_digest= & thd->m_digest_state; thd->m_digest->reset(thd->m_token_array, max_digest_length); - if (alloc_query(thd, packet, packet_length)) + if (unlikely(alloc_query(thd, packet, packet_length))) break; // fatal error is set MYSQL_QUERY_START(thd->query(), thd->thread_id, thd->get_db(), @@ -1835,7 +1836,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->query_length()); Parser_state parser_state; - if (parser_state.init(thd, thd->query(), thd->query_length())) + if (unlikely(parser_state.init(thd, thd->query(), thd->query_length()))) break; if (WSREP_ON) @@ -2378,10 +2379,10 @@ com_multi_end: DBUG_ASSERT((command != COM_QUIT && command != COM_STMT_CLOSE) || thd->get_stmt_da()->is_disabled()); /* wsrep BF abort in query exec phase */ - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); do_end_of_statement= thd->wsrep_conflict_state != REPLAYING && thd->wsrep_conflict_state != RETRY_AUTOCOMMIT; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } else do_end_of_statement= true; @@ -2406,7 +2407,7 @@ com_multi_end: if (drop_more_results) thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; - if (!thd->is_error() && !thd->killed_errno()) + if (likely(!thd->is_error() && !thd->killed_errno())) mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0); mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS, @@ -3237,10 +3238,6 @@ mysql_execute_command(THD *thd) #endif DBUG_ENTER("mysql_execute_command"); -#ifdef WITH_PARTITION_STORAGE_ENGINE - thd->work_part_info= 0; -#endif - DBUG_ASSERT(thd->transaction.stmt.is_empty() || thd->in_sub_stmt); /* Each statement or replication event which might produce deadlock @@ -3933,7 +3930,7 @@ mysql_execute_command(THD *thd) { /* New replication created */ mi= new Master_info(&lex_mi->connection_name, relay_log_recovery); - if (!mi || mi->error()) + if (unlikely(!mi || mi->error())) { delete mi; res= 1; @@ -4043,7 +4040,7 @@ mysql_execute_command(THD *thd) copy. */ Alter_info alter_info(lex->alter_info, thd->mem_root); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) { /* If out of memory when creating a copy of alter_info. */ res= 1; @@ -4100,6 +4097,7 @@ mysql_execute_command(THD *thd) } #ifdef WITH_PARTITION_STORAGE_ENGINE + thd->work_part_info= 0; { partition_info *part_info= thd->lex->part_info; if (part_info && !(part_info= part_info->get_clone(thd))) @@ -4185,7 +4183,7 @@ mysql_execute_command(THD *thd) thd->lex->create_info.options|= create_info.options; res= open_and_lock_tables(thd, create_info, lex->query_tables, TRUE, 0); thd->lex->create_info.options= save_thd_create_info_options; - if (res) + if (unlikely(res)) { /* Got error or warning. Set res to 1 if error */ if (!(res= thd->is_error())) @@ -4197,9 +4195,9 @@ mysql_execute_command(THD *thd) if (create_info.or_replace() && !create_info.tmp_table()) { TABLE_LIST *duplicate; - if ((duplicate= unique_table(thd, lex->query_tables, - lex->query_tables->next_global, - 0))) + if (unlikely((duplicate= unique_table(thd, lex->query_tables, + lex->query_tables->next_global, + CHECK_DUP_FOR_CREATE)))) { update_non_unique_table_error(lex->query_tables, "CREATE", duplicate); @@ -4223,13 +4221,14 @@ mysql_execute_command(THD *thd) needs to be created for every execution of a PS/SP. Note: In wsrep-patch, CTAS is handled like a regular transaction. */ - if ((result= new (thd->mem_root) select_create(thd, create_table, - &create_info, - &alter_info, - select_lex->item_list, - lex->duplicates, - lex->ignore, - select_tables))) + if (unlikely((result= new (thd->mem_root) + select_create(thd, create_table, + &create_info, + &alter_info, + select_lex->item_list, + lex->duplicates, + lex->ignore, + select_tables)))) { /* CREATE from SELECT give its SELECT_LEX for SELECT, @@ -4310,7 +4309,7 @@ end_with_restore_list: HA_CREATE_INFO create_info; Alter_info alter_info(lex->alter_info, thd->mem_root); - if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */ + if (unlikely(thd->is_fatal_error)) /* out of memory creating alter_info */ goto error; DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -4347,8 +4346,8 @@ end_with_restore_list: We don't need to ensure that only one user is using master_info as start_slave is protected against simultaneous usage */ - if ((mi= get_master_info(&lex_mi->connection_name, - Sql_condition::WARN_LEVEL_ERROR))) + if (unlikely((mi= get_master_info(&lex_mi->connection_name, + Sql_condition::WARN_LEVEL_ERROR)))) { if (load_error) { @@ -4891,7 +4890,7 @@ end_with_restore_list: unit->set_limit(select_lex); MYSQL_DELETE_START(thd->query()); - Protocol *save_protocol; + Protocol * UNINIT_VAR(save_protocol); bool replaced_protocol= false; if (!select_lex->item_list.is_empty()) @@ -4961,17 +4960,17 @@ end_with_restore_list: break; MYSQL_MULTI_DELETE_START(thd->query()); - if ((res= mysql_multi_delete_prepare(thd))) + if (unlikely(res= mysql_multi_delete_prepare(thd))) { MYSQL_MULTI_DELETE_DONE(1, 0); goto error; } - if (!thd->is_fatal_error) + if (likely(!thd->is_fatal_error)) { result= new (thd->mem_root) multi_delete(thd, aux_tables, lex->table_count); - if (result) + if (unlikely(result)) { res= mysql_select(thd, select_lex->get_table_list(), @@ -5132,9 +5131,9 @@ end_with_restore_list: if ((check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE) || open_and_lock_tables(thd, all_tables, TRUE, 0))) goto error; - if (!(res= sql_set_variables(thd, lex_var_list, true))) + if (likely(!(res= sql_set_variables(thd, lex_var_list, true)))) { - if (!thd->is_error()) + if (likely(!thd->is_error())) my_ok(thd); } else @@ -6226,7 +6225,7 @@ end_with_restore_list: WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL); - if ((error= alter_server(thd, &lex->server_options))) + if (unlikely((error= alter_server(thd, &lex->server_options)))) { DBUG_PRINT("info", ("problem altering server <%s>", lex->server_options.server_name.str)); @@ -6306,6 +6305,10 @@ finish: lex->unit.cleanup(); + /* close/reopen tables that were marked to need reopen under LOCK TABLES */ + if (! thd->lex->requires_prelocking()) + thd->locked_tables_list.reopen_tables(thd, true); + if (! thd->in_sub_stmt) { if (thd->killed != NOT_KILLED) @@ -6319,7 +6322,8 @@ finish: } thd->reset_kill_query(); } - if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR)) + if (unlikely(thd->is_error()) || + (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR)) { THD_STAGE_INFO(thd, stage_rollback); trans_rollback_stmt(thd); @@ -6467,7 +6471,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) to prepend EXPLAIN to any query and receive output for it, even if the query itself redirects the output. */ - if (!(result= new (thd->mem_root) select_send(thd))) + if (unlikely(!(result= new (thd->mem_root) select_send(thd)))) return 1; /* purecov: inspected */ thd->send_explain_fields(result, lex->describe, lex->analyze_stmt); @@ -6478,7 +6482,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) res= mysql_explain_union(thd, &lex->unit, result); /* Print EXPLAIN only if we don't have an error */ - if (!res) + if (likely(!res)) { /* Do like the original select_describe did: remove OFFSET from the @@ -6588,6 +6592,60 @@ static bool execute_show_status(THD *thd, TABLE_LIST *all_tables) } +/* + Find out if a table is a temporary table + + A table is a temporary table if it's a temporary table or + there has been before a temporary table that has been renamed + to the current name. + + Some examples: + A->B B is a temporary table if and only if A is a temp. + A->B, B->C Second B is temp if A is temp + A->B, A->C Second A can't be temp as if A was temp then B is temp + and Second A can only be a normal table. C is also not temp +*/ + +static TABLE *find_temporary_table_for_rename(THD *thd, + TABLE_LIST *first_table, + TABLE_LIST *cur_table) +{ + TABLE_LIST *table; + TABLE *res= 0; + bool found= 0; + DBUG_ENTER("find_temporary_table_for_rename"); + + /* Find last instance when cur_table is in TO part */ + for (table= first_table; + table != cur_table; + table= table->next_local->next_local) + { + TABLE_LIST *next= table->next_local; + + if (!strcmp(table->get_db_name(), cur_table->get_db_name()) && + !strcmp(table->get_table_name(), cur_table->get_table_name())) + { + /* Table was moved away, can't be same as 'table' */ + found= 1; + res= 0; // Table can't be a temporary table + } + if (!strcmp(next->get_db_name(), cur_table->get_db_name()) && + !strcmp(next->get_table_name(), cur_table->get_table_name())) + { + /* + Table has matching name with new name of this table. cur_table should + have same temporary type as this table. + */ + found= 1; + res= table->table; + } + } + if (!found) + res= thd->find_temporary_table(table, THD::TMP_TABLE_ANY); + DBUG_RETURN(res); +} + + static bool check_rename_table(THD *thd, TABLE_LIST *first_table, TABLE_LIST *all_tables) { @@ -6604,13 +6662,19 @@ static bool check_rename_table(THD *thd, TABLE_LIST *first_table, &table->next_local->grant.m_internal, 0, 0)) return 1; + + /* check if these are refering to temporary tables */ + table->table= find_temporary_table_for_rename(thd, first_table, table); + table->next_local->table= table->table; + TABLE_LIST old_list, new_list; /* we do not need initialize old_list and new_list because we will - come table[0] and table->next[0] there + copy table[0] and table->next[0] there */ old_list= table[0]; new_list= table->next_local[0]; + if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, FALSE, 1, FALSE) || (!test_all_bits(table->next_local->grant.privilege, INSERT_ACL | CREATE_ACL) && @@ -6689,7 +6753,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, /* check access may be called twice in a row. Don't change to same stage */ if (thd->proc_info != stage_checking_permissions.m_name) THD_STAGE_INFO(thd, stage_checking_permissions); - if ((!db || !db[0]) && !thd->db.str && !dont_check_global_grants) + if (unlikely((!db || !db[0]) && !thd->db.str && !dont_check_global_grants)) { DBUG_PRINT("error",("No database")); if (!no_errors) @@ -6698,7 +6762,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_RETURN(TRUE); /* purecov: tested */ } - if ((db != NULL) && (db != any_db)) + if (likely((db != NULL) && (db != any_db))) { /* Check if this is reserved database, like information schema or @@ -6768,8 +6832,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, *save_priv|= sctx->master_access; DBUG_RETURN(FALSE); } - if (((want_access & ~sctx->master_access) & ~DB_ACLS) || - (! db && dont_check_global_grants)) + if (unlikely(((want_access & ~sctx->master_access) & ~DB_ACLS) || + (! db && dont_check_global_grants))) { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) @@ -6785,7 +6849,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_RETURN(TRUE); /* purecov: tested */ } - if (db == any_db) + if (unlikely(db == any_db)) { /* Access granted; Allow select on *any* db. @@ -7279,7 +7343,7 @@ bool check_global_access(THD *thd, ulong want_access, bool no_errors) char command[128]; if ((thd->security_ctx->master_access & want_access)) return 0; - if (!no_errors) + if (unlikely(!no_errors)) { get_privilege_desc(command, sizeof(command), want_access); my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); @@ -7526,7 +7590,7 @@ void THD::reset_for_next_command(bool do_clear_error) DBUG_ASSERT(!spcont); /* not for substatements of routines */ DBUG_ASSERT(!in_sub_stmt); - if (do_clear_error) + if (likely(do_clear_error)) clear_error(1); free_list= 0; @@ -7534,8 +7598,9 @@ void THD::reset_for_next_command(bool do_clear_error) We also assign stmt_lex in lex_start(), but during bootstrap this code is executed first. */ - stmt_lex= &main_lex; stmt_lex->current_select_number= 1; - DBUG_PRINT("info", ("Lex %p stmt_lex: %p", lex, stmt_lex)); + DBUG_ASSERT(lex == &main_lex); + main_lex.stmt_lex= &main_lex; main_lex.current_select_number= 1; + DBUG_PRINT("info", ("Lex and stmt_lex: %p", &main_lex)); /* Those two lines below are theoretically unneeded as THD::cleanup_after_query() should take care of this already. @@ -7652,7 +7717,7 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex) { if (!(select_lex= new (thd->mem_root) SELECT_LEX())) DBUG_RETURN(1); - select_lex->select_number= ++thd->stmt_lex->current_select_number; + select_lex->select_number= ++thd->lex->stmt_lex->current_select_number; select_lex->parent_lex= lex; /* Used in init_query. */ select_lex->init_query(); select_lex->init_select(); @@ -7803,13 +7868,22 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, com_statement_info[thd->get_command()].m_key); MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), thd->query_length()); + + DBUG_EXECUTE_IF("sync.wsrep_retry_autocommit", + { + const char act[]= + "now " + "SIGNAL wsrep_retry_autocommit_reached " + "WAIT_FOR wsrep_retry_autocommit_continue"; + DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act))); + }); } mysql_parse(thd, rawbuf, length, parser_state, is_com_multi, is_next_command); if (WSREP(thd)) { /* wsrep BF abort in query exec phase */ - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state == MUST_ABORT) { wsrep_client_rollback(thd); @@ -7818,8 +7892,11 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, if (thd->wsrep_conflict_state == MUST_REPLAY) { + mysql_mutex_unlock(&thd->LOCK_thd_data); if (thd->lex->explain) delete_explain_query(thd->lex); + mysql_mutex_lock(&thd->LOCK_thd_data); + wsrep_replay_transaction(thd); } @@ -7861,13 +7938,13 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, if (thd->wsrep_conflict_state != REPLAYING) thd->wsrep_retry_counter= 0; // reset } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); thd->reset_killed(); } else { set_if_smaller(thd->wsrep_retry_counter, 0); // reset; eventually ok - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } } @@ -7953,7 +8030,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, bool err= parse_sql(thd, parser_state, NULL, true); - if (!err) + if (likely(!err)) { thd->m_statement_psi= MYSQL_REFINE_STATEMENT(thd->m_statement_psi, @@ -7968,7 +8045,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, else #endif { - if (! thd->is_error()) + if (likely(! thd->is_error())) { const char *found_semicolon= parser_state->m_lip.found_semicolon; /* @@ -8062,7 +8139,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length) DBUG_ENTER("mysql_test_parse_for_slave"); Parser_state parser_state; - if (!(error= parser_state.init(thd, rawbuf, length))) + if (likely(!(error= parser_state.init(thd, rawbuf, length)))) { lex_start(thd); thd->reset_for_next_command(); @@ -8084,7 +8161,7 @@ add_proc_to_list(THD* thd, Item *item) ORDER *order; Item **item_ptr; - if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*)))) + if (unlikely(!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))) return 1; item_ptr = (Item**) (order+1); *item_ptr= item; @@ -8102,7 +8179,7 @@ bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc) { ORDER *order; DBUG_ENTER("add_to_list"); - if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)))) + if (unlikely(!(order = (ORDER *) thd->alloc(sizeof(ORDER))))) DBUG_RETURN(1); order->item_ptr= item; order->item= &order->item_ptr; @@ -8145,25 +8222,25 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, List<String> *partition_names, LEX_STRING *option) { - register TABLE_LIST *ptr; + TABLE_LIST *ptr; TABLE_LIST *UNINIT_VAR(previous_table_ref); /* The table preceding the current one. */ LEX_CSTRING alias_str; LEX *lex= thd->lex; DBUG_ENTER("add_table_to_list"); - if (!table) + if (unlikely(!table)) DBUG_RETURN(0); // End of memory alias_str= alias ? *alias : table->table; DBUG_ASSERT(alias_str.str); if (!MY_TEST(table_options & TL_OPTION_ALIAS) && - check_table_name(table->table.str, table->table.length, FALSE)) + unlikely(check_table_name(table->table.str, table->table.length, FALSE))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); } - if (table->is_derived_table() == FALSE && table->db.str && - check_db_name((LEX_STRING*) &table->db)) + if (unlikely(table->is_derived_table() == FALSE && table->db.str && + check_db_name((LEX_STRING*) &table->db))) { my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str); DBUG_RETURN(0); @@ -8171,17 +8248,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!alias) /* Alias is case sensitive */ { - if (table->sel) + if (unlikely(table->sel)) { my_message(ER_DERIVED_MUST_HAVE_ALIAS, ER_THD(thd, ER_DERIVED_MUST_HAVE_ALIAS), MYF(0)); DBUG_RETURN(0); } /* alias_str points to table->table; Let's make a copy */ - if (!(alias_str.str= (char*) thd->memdup(alias_str.str, alias_str.length+1))) + if (unlikely(!(alias_str.str= (char*) thd->memdup(alias_str.str, alias_str.length+1)))) DBUG_RETURN(0); } - if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) + if (unlikely(!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))) DBUG_RETURN(0); /* purecov: inspected */ if (table->db.str) { @@ -8227,7 +8304,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, DBUG_RETURN(0); } schema_table= find_schema_table(thd, &ptr->table_name); - if (!schema_table || + if (unlikely(!schema_table) || (schema_table->hidden && ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 || /* @@ -8261,8 +8338,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, tables ; tables=tables->next_local) { - if (!my_strcasecmp(table_alias_charset, alias_str.str, tables->alias.str) && - !cmp(&ptr->db, &tables->db) && ! tables->sequence) + if (unlikely(!my_strcasecmp(table_alias_charset, alias_str.str, + tables->alias.str) && + !cmp(&ptr->db, &tables->db) && ! tables->sequence)) { my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str.str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ @@ -8270,7 +8348,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, } } /* Store the table reference preceding the current one. */ - if (table_list.elements > 0 && !ptr->sequence) + if (table_list.elements > 0 && likely(!ptr->sequence)) { /* table_list.next points to the last inserted TABLE_LIST->next_local' @@ -8298,7 +8376,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, We don't store sequences into the local list to hide them from INSERT and SELECT. */ - if (!ptr->sequence) + if (likely(!ptr->sequence)) table_list.link_in_list(ptr, &ptr->next_local); ptr->next_name_resolution_table= NULL; #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -8343,13 +8421,14 @@ bool st_select_lex::init_nested_join(THD *thd) NESTED_JOIN *nested_join; DBUG_ENTER("init_nested_join"); - if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+ - sizeof(NESTED_JOIN)))) + if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+ + sizeof(NESTED_JOIN))))) DBUG_RETURN(1); nested_join= ptr->nested_join= ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST)))); - join_list->push_front(ptr, thd->mem_root); + if (unlikely(join_list->push_front(ptr, thd->mem_root))) + DBUG_RETURN(1); ptr->embedding= embedding; ptr->join_list= join_list; ptr->alias.str="(nested_join)"; @@ -8425,8 +8504,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) List<TABLE_LIST> *embedded_list; DBUG_ENTER("nest_last_join"); - if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+ - sizeof(NESTED_JOIN)))) + if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+ + sizeof(NESTED_JOIN))))) DBUG_RETURN(0); nested_join= ptr->nested_join= ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST)))); @@ -8441,7 +8520,7 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) for (uint i=0; i < 2; i++) { TABLE_LIST *table= join_list->pop(); - if (!table) + if (unlikely(!table)) DBUG_RETURN(NULL); table->join_list= embedded_list; table->embedding= ptr; @@ -8894,7 +8973,7 @@ kill_one_thread(THD *thd, longlong id, killed_state kill_signal, killed_type typ if (((thd->security_ctx->master_access & SUPER_ACL) || thd->security_ctx->user_matches(tmp->security_ctx)) && - !wsrep_thd_is_BF(tmp, true)) + !wsrep_thd_is_BF(tmp, false)) { tmp->awake_no_mutex(kill_signal); error=0; @@ -8932,7 +9011,7 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user, *rows= 0; - if (thd->is_fatal_error) // If we run out of memory + if (unlikely(thd->is_fatal_error)) // If we run out of memory DBUG_RETURN(ER_OUT_OF_RESOURCES); DBUG_PRINT("enter", ("user: %s signal: %u", user->user.str, @@ -9002,7 +9081,7 @@ static void sql_kill(THD *thd, longlong id, killed_state state, killed_type type) { uint error; - if (!(error= kill_one_thread(thd, id, state, type))) + if (likely(!(error= kill_one_thread(thd, id, state, type)))) { if (!thd->killed) my_ok(thd); @@ -9019,7 +9098,7 @@ void sql_kill_user(THD *thd, LEX_USER *user, killed_state state) { uint error; ha_rows rows; - if (!(error= kill_threads_for_user(thd, user, state, &rows))) + if (likely(!(error= kill_threads_for_user(thd, user, state, &rows)))) my_ok(thd, rows); else { @@ -9051,7 +9130,8 @@ bool append_file_to_dir(THD *thd, const char **filename_ptr, /* Fix is using unix filename format on dos */ strmov(buff,*filename_ptr); end=convert_dirname(buff, *filename_ptr, NullS); - if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + table_name->length + 1))) + if (unlikely(!(ptr= (char*) thd->alloc((size_t) (end-buff) + + table_name->length + 1)))) return 1; // End of memory *filename_ptr=ptr; strxmov(ptr,buff,table_name->str,NullS); @@ -9059,32 +9139,6 @@ bool append_file_to_dir(THD *thd, const char **filename_ptr, } -/** - Check if the select is a simple select (not an union). - - @retval - 0 ok - @retval - 1 error ; In this case the error messege is sent to the client -*/ - -bool check_simple_select() -{ - THD *thd= current_thd; - LEX *lex= thd->lex; - if (lex->current_select != &lex->select_lex) - { - char command[80]; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; - strmake(command, lip->yylval->symbol.str, - MY_MIN(lip->yylval->symbol.length, sizeof(command)-1)); - my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command); - return 1; - } - return 0; -} - - Comp_creator *comp_eq_creator(bool invert) { return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator; @@ -9424,7 +9478,7 @@ bool update_precheck(THD *thd, TABLE_LIST *tables) bool delete_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("delete_precheck"); - if (tables->vers_conditions) + if (tables->vers_conditions.is_set()) { if (check_one_table_access(thd, DELETE_HISTORY_ACL, tables)) DBUG_RETURN(TRUE); @@ -9724,7 +9778,7 @@ LEX_USER *create_default_definer(THD *thd, bool role) { LEX_USER *definer; - if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))) return 0; thd->get_definer(definer, role); @@ -9759,7 +9813,7 @@ LEX_USER *create_definer(THD *thd, LEX_CSTRING *user_name, /* Create and initialize. */ - if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!(definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))) return 0; definer->user= *user_name; @@ -9822,7 +9876,8 @@ bool check_string_char_length(const LEX_CSTRING *str, uint err_msg, bool no_error) { Well_formed_prefix prefix(cs, str->str, str->length, max_char_length); - if (!prefix.well_formed_error_pos() && str->length == prefix.length()) + if (likely(!prefix.well_formed_error_pos() && + str->length == prefix.length())) return FALSE; if (!no_error) diff --git a/sql/sql_parse.h b/sql/sql_parse.h index d23da6f1b68..1027872898a 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -85,6 +85,7 @@ bool check_identifier_name(LEX_CSTRING *str, uint max_char_length, uint err_code, const char *param_for_err_msg); bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length); bool sqlcom_can_generate_row_events(const THD *thd); +bool stmt_causes_implicit_commit(THD *thd, uint mask); bool is_update_query(enum enum_sql_command command); bool is_log_table_write_query(enum enum_sql_command command); bool alloc_query(THD *thd, const char *packet, size_t packet_length); @@ -119,7 +120,6 @@ bool push_new_name_resolution_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op); void init_update_queries(void); -bool check_simple_select(); Item *normalize_cond(THD *thd, Item *cond); Item *negate_expression(THD *thd, Item *expr); bool check_stack_overrun(THD *thd, long margin, uchar *dummy); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 09c59c862ad..c0ff1c54549 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2005, 2017, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, SkySQL Ab. + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -108,14 +108,14 @@ static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*); uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter); uint32 get_next_partition_id_list(PARTITION_ITERATOR* part_iter); + +#ifdef WITH_PARTITION_STORAGE_ENGINE static int get_part_iter_for_interval_via_mapping(partition_info *, bool, uint32 *, uchar *, uchar *, uint, uint, uint, PARTITION_ITERATOR *); static int get_part_iter_for_interval_cols_via_map(partition_info *, bool, uint32 *, uchar *, uchar *, uint, uint, uint, PARTITION_ITERATOR *); static int get_part_iter_for_interval_via_walking(partition_info *, bool, uint32 *, uchar *, uchar *, uint, uint, uint, PARTITION_ITERATOR *); - -#ifdef WITH_PARTITION_STORAGE_ENGINE static int cmp_rec_and_tuple(part_column_list_val *val, uint32 nvals_in_rec); static int cmp_rec_and_tuple_prune(part_column_list_val *val, uint32 n_vals_in_rec, @@ -343,7 +343,7 @@ static bool set_up_field_array(THD *thd, TABLE *table, if (field->flags & GET_FIXED_FIELDS_FLAG) num_fields++; } - if (num_fields > MAX_REF_PARTS) + if (unlikely(num_fields > MAX_REF_PARTS)) { char *err_str; if (is_sub_part) @@ -359,15 +359,13 @@ static bool set_up_field_array(THD *thd, TABLE *table, We are using hidden key as partitioning field */ DBUG_ASSERT(!is_sub_part); - DBUG_RETURN(result); + DBUG_RETURN(FALSE); } size_field_array= (num_fields+1)*sizeof(Field*); field_array= (Field**) thd->calloc(size_field_array); if (unlikely(!field_array)) - { - mem_alloc_error(size_field_array); - result= TRUE; - } + DBUG_RETURN(TRUE); + ptr= table->field; while ((field= *(ptr++))) { @@ -490,7 +488,6 @@ static bool create_full_part_field_array(THD *thd, TABLE *table, field_array= (Field**) thd->calloc(size_field_array); if (unlikely(!field_array)) { - mem_alloc_error(size_field_array); result= TRUE; goto end; } @@ -515,14 +512,12 @@ static bool create_full_part_field_array(THD *thd, TABLE *table, if (!(bitmap_buf= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(table->s->fields)))) { - mem_alloc_error(bitmap_buffer_size(table->s->fields)); result= TRUE; goto end; } - if (my_bitmap_init(&part_info->full_part_field_set, bitmap_buf, - table->s->fields, FALSE)) + if (unlikely(my_bitmap_init(&part_info->full_part_field_set, bitmap_buf, + table->s->fields, FALSE))) { - mem_alloc_error(table->s->fields); result= TRUE; goto end; } @@ -530,9 +525,16 @@ static bool create_full_part_field_array(THD *thd, TABLE *table, full_part_field_array may be NULL if storage engine supports native partitioning. */ + table->vcol_set= table->read_set= &part_info->full_part_field_set; if ((ptr= part_info->full_part_field_array)) for (; *ptr; ptr++) - bitmap_set_bit(&part_info->full_part_field_set, (*ptr)->field_index); + { + if ((*ptr)->vcol_info) + table->mark_virtual_col(*ptr); + else + bitmap_fast_test_and_set(table->read_set, (*ptr)->field_index); + } + table->default_column_bitmaps(); end: DBUG_RETURN(result); @@ -820,7 +822,7 @@ int check_signed_flag(partition_info *part_info) */ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, - bool is_sub_part, bool is_create_table_ind) + bool is_sub_part, bool is_create_table_ind) { partition_info *part_info= table->part_info; bool result= TRUE; @@ -857,8 +859,8 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func; thd->lex->allow_sum_func= 0; - if (!(error= func_expr->fix_fields(thd, (Item**)&func_expr))) - func_expr->walk(&Item::vcol_in_partition_func_processor, 0, NULL); + if (likely(!(error= func_expr->fix_fields(thd, (Item**)&func_expr)))) + func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL); /* Restore agg_field/agg_func and allow_sum_func, @@ -901,7 +903,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, ER_THD(thd, ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR)); } - if ((!is_sub_part) && (error= check_signed_flag(part_info))) + if (unlikely((!is_sub_part) && (error= check_signed_flag(part_info)))) goto end; result= set_up_field_array(thd, table, is_sub_part); end: @@ -1088,12 +1090,11 @@ static bool set_up_partition_bitmaps(THD *thd, partition_info *part_info) DBUG_ASSERT(!part_info->bitmaps_are_initialized); /* Allocate for both read and lock_partitions */ - if (!(bitmap_buf= (uint32*) alloc_root(&part_info->table->mem_root, - bitmap_bytes * 2))) - { - mem_alloc_error(bitmap_bytes * 2); + if (unlikely(!(bitmap_buf= + (uint32*) alloc_root(&part_info->table->mem_root, + bitmap_bytes * 2)))) DBUG_RETURN(TRUE); - } + my_bitmap_init(&part_info->read_partitions, bitmap_buf, bitmap_bits, FALSE); /* Use the second half of the allocated buffer for lock_partitions */ my_bitmap_init(&part_info->lock_partitions, bitmap_buf + (bitmap_bytes / 4), @@ -1291,11 +1292,9 @@ static bool check_range_constants(THD *thd, partition_info *part_info) uint size_entries= sizeof(part_column_list_val) * num_column_values; part_info->range_col_array= (part_column_list_val*) thd->calloc(part_info->num_parts * size_entries); - if (part_info->range_col_array == NULL) - { - mem_alloc_error(part_info->num_parts * size_entries); + if (unlikely(part_info->range_col_array == NULL)) goto end; - } + loc_range_col_array= part_info->range_col_array; i= 0; do @@ -1329,11 +1328,9 @@ static bool check_range_constants(THD *thd, partition_info *part_info) part_info->range_int_array= (longlong*) thd->alloc(part_info->num_parts * sizeof(longlong)); - if (part_info->range_int_array == NULL) - { - mem_alloc_error(part_info->num_parts * sizeof(longlong)); + if (unlikely(part_info->range_int_array == NULL)) goto end; - } + i= 0; do { @@ -1574,7 +1571,7 @@ static bool check_vers_constants(THD *thd, partition_info *part_info) my_tz_OFFSET0->TIME_to_gmt_sec(<ime, &error); if (error) goto err; - if (vers_info->hist_part->range_value <= thd->systime()) + if (vers_info->hist_part->range_value <= thd->query_start()) vers_info->hist_part= el; } return 0; @@ -2823,10 +2820,9 @@ static inline int part_val_int(Item *item_expr, longlong *result) *result= item_expr->val_int(); if (item_expr->null_value) { - if (current_thd->is_error()) + if (unlikely(current_thd->is_error())) return TRUE; - else - *result= LONGLONG_MIN; + *result= LONGLONG_MIN; } return FALSE; } @@ -3534,7 +3530,7 @@ int get_partition_id_range(partition_info *part_info, bool unsigned_flag= part_info->part_expr->unsigned_flag; DBUG_ENTER("get_partition_id_range"); - if (error) + if (unlikely(error)) DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND); if (part_info->part_expr->null_value) @@ -4107,26 +4103,21 @@ bool verify_data_with_partition(TABLE *table, TABLE *part_table, old_rec= part_table->record[0]; part_table->record[0]= table->record[0]; part_info->table->move_fields(part_info->full_part_field_array, table->record[0], old_rec); - if ((error= file->ha_rnd_init(TRUE))) - { - file->print_error(error, MYF(0)); + if (unlikely(error= file->ha_rnd_init_with_error(TRUE))) goto err; - } do { - if ((error= file->ha_rnd_next(table->record[0]))) + if (unlikely((error= file->ha_rnd_next(table->record[0])))) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) error= 0; else file->print_error(error, MYF(0)); break; } - if ((error= part_info->get_partition_id(part_info, &found_part_id, - &func_value))) + if (unlikely((error= part_info->get_partition_id(part_info, &found_part_id, + &func_value)))) { part_table->file->print_error(error, MYF(0)); break; @@ -4144,9 +4135,7 @@ err: part_info->table->move_fields(part_info->full_part_field_array, old_rec, table->record[0]); part_table->record[0]= old_rec; - if (error) - DBUG_RETURN(TRUE); - DBUG_RETURN(FALSE); + DBUG_RETURN(unlikely(error) ? TRUE : FALSE); } @@ -4461,26 +4450,24 @@ bool mysql_unpack_partition(THD *thd, thd->variables.character_set_client= system_charset_info; Parser_state parser_state; - if (parser_state.init(thd, part_buf, part_info_len)) + if (unlikely(parser_state.init(thd, part_buf, part_info_len))) goto end; - if (init_lex_with_single_table(thd, table, &lex)) + if (unlikely(init_lex_with_single_table(thd, table, &lex))) goto end; *work_part_info_used= FALSE; - lex.part_info= new partition_info(); - lex.part_info->table= table; /* Indicates MYSQLparse from this place */ - if (!lex.part_info) - { - mem_alloc_error(sizeof(partition_info)); + + if (unlikely(!(lex.part_info= new partition_info()))) goto end; - } + + lex.part_info->table= table; /* Indicates MYSQLparse from this place */ part_info= lex.part_info; DBUG_PRINT("info", ("Parse: %s", part_buf)); thd->m_statement_psi= NULL; - if (parse_sql(thd, & parser_state, NULL) || - part_info->fix_parser_data(thd)) + if (unlikely(parse_sql(thd, & parser_state, NULL)) || + unlikely(part_info->fix_parser_data(thd))) { thd->free_items(); thd->m_statement_psi= parent_locker; @@ -4765,8 +4752,6 @@ bool compare_partition_options(HA_CREATE_INFO *table_create_info, const char *option_diffs[MAX_COMPARE_PARTITION_OPTION_ERRORS + 1]; int i, errors= 0; DBUG_ENTER("compare_partition_options"); - DBUG_ASSERT(!part_elem->tablespace_name && - !table_create_info->tablespace); /* Note that there are not yet any engine supporting tablespace together @@ -4877,6 +4862,17 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, ALTER_PARTITION_TABLE_REORG | ALTER_PARTITION_REBUILD)) { + /* + You can't add column when we are doing alter related to partition + */ + DBUG_EXECUTE_IF("test_pseudo_invisible", { + my_error(ER_INTERNAL_ERROR, MYF(0), "Don't to it with test_pseudo_invisible"); + DBUG_RETURN(1); + }); + DBUG_EXECUTE_IF("test_completely_invisible", { + my_error(ER_INTERNAL_ERROR, MYF(0), "Don't to it with test_completely_invisible"); + DBUG_RETURN(1); + }); partition_info *tab_part_info; ulonglong flags= 0; bool is_last_partition_reorged= FALSE; @@ -5314,7 +5310,7 @@ that are reorganised. if (*fast_alter_table && tab_part_info->vers_info->interval.is_set()) { partition_element *hist_part= tab_part_info->vers_info->hist_part; - if (hist_part->range_value <= thd->systime()) + if (hist_part->range_value <= thd->query_start()) hist_part->part_state= PART_CHANGED; } } @@ -5325,21 +5321,17 @@ that are reorganised. partition_element *part_elem= alt_it++; if (*fast_alter_table) part_elem->part_state= PART_TO_BE_ADDED; - if (tab_part_info->partitions.push_back(part_elem, thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(tab_part_info->partitions.push_back(part_elem, + thd->mem_root))) goto err; - } } while (++part_count < num_new_partitions); tab_part_info->num_parts+= num_new_partitions; if (tab_part_info->part_type == VERSIONING_PARTITION) { DBUG_ASSERT(now_part); - if (tab_part_info->partitions.push_back(now_part, thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(tab_part_info->partitions.push_back(now_part, + thd->mem_root))) goto err; - } } } /* @@ -5672,12 +5664,10 @@ the generated partition syntax in a correct manner. else tab_max_range= part_elem->range_value; if (*fast_alter_table && - tab_part_info->temp_partitions.push_back(part_elem, - thd->mem_root)) - { - mem_alloc_error(1); + unlikely(tab_part_info->temp_partitions. + push_back(part_elem, thd->mem_root))) goto err; - } + if (*fast_alter_table) part_elem->part_state= PART_TO_BE_REORGED; if (!found_first) @@ -5995,9 +5985,11 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) /* TODO: test if bulk_insert would increase the performance */ - if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied, - &lpt->deleted, lpt->pack_frm_data, - lpt->pack_frm_len))) + if (unlikely((error= file->ha_change_partitions(lpt->create_info, path, + &lpt->copied, + &lpt->deleted, + lpt->pack_frm_data, + lpt->pack_frm_len)))) { file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR)); } @@ -6035,7 +6027,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_ENTER("mysql_rename_partitions"); build_table_filename(path, sizeof(path) - 1, lpt->db.str, lpt->table_name.str, "", 0); - if ((error= lpt->table->file->ha_rename_partitions(path))) + if (unlikely((error= lpt->table->file->ha_rename_partitions(path)))) { if (error != 1) lpt->table->file->print_error(error, MYF(0)); @@ -6772,14 +6764,14 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) Diagnostics_area *stmt_da= NULL; Diagnostics_area tmp_stmt_da(true); - if (thd->is_error()) + if (unlikely(thd->is_error())) { /* reopen might fail if we have a previous error, use a temporary da. */ stmt_da= thd->get_stmt_da(); thd->set_stmt_da(&tmp_stmt_da); } - if (thd->locked_tables_list.reopen_tables(thd)) + if (unlikely(thd->locked_tables_list.reopen_tables(thd, false))) sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); if (stmt_da) @@ -6978,14 +6970,14 @@ err_exclusive_lock: Diagnostics_area *stmt_da= NULL; Diagnostics_area tmp_stmt_da(true); - if (thd->is_error()) + if (unlikely(thd->is_error())) { /* reopen might fail if we have a previous error, use a temporary da. */ stmt_da= thd->get_stmt_da(); thd->set_stmt_da(&tmp_stmt_da); } - if (thd->locked_tables_list.reopen_tables(thd)) + if (unlikely(thd->locked_tables_list.reopen_tables(thd, false))) sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); if (stmt_da) @@ -7536,27 +7528,6 @@ void append_row_to_str(String &str, const uchar *row, TABLE *table) } -/* - SYNOPSIS - mem_alloc_error() - size Size of memory attempted to allocate - None - - RETURN VALUES - None - - DESCRIPTION - A routine to use for all the many places in the code where memory - allocation error can happen, a tremendous amount of them, needs - simple routine that signals this error. -*/ - -void mem_alloc_error(size_t size) -{ - my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), - static_cast<int>(size)); -} - #ifdef WITH_PARTITION_STORAGE_ENGINE /** Return comma-separated list of used partitions in the provided given string. diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 4315c84e4f0..170ae8ccee1 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -133,7 +133,6 @@ Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs); @param[in] table Table containing read_set and fields for the row. */ void append_row_to_str(String &str, const uchar *row, TABLE *table); -void mem_alloc_error(size_t size); void truncate_partition_filename(char *path); /* diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc index 6e176a40e6c..99fe09d5afe 100644 --- a/sql/sql_partition_admin.cc +++ b/sql/sql_partition_admin.cc @@ -67,25 +67,29 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd) DBUG_ENTER("Sql_cmd_alter_table_exchange_partition::execute"); - if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */ + if (unlikely(thd->is_fatal_error)) + { + /* out of memory creating a copy of alter_info */ DBUG_RETURN(TRUE); + } /* Must be set in the parser */ DBUG_ASSERT(select_lex->db.str); /* also check the table to be exchanged with the partition */ DBUG_ASSERT(alter_info.partition_flags & ALTER_PARTITION_EXCHANGE); - if (check_access(thd, priv_needed, first_table->db.str, - &first_table->grant.privilege, - &first_table->grant.m_internal, - 0, 0) || - check_access(thd, priv_needed, first_table->next_local->db.str, - &first_table->next_local->grant.privilege, - &first_table->next_local->grant.m_internal, - 0, 0)) + if (unlikely(check_access(thd, priv_needed, first_table->db.str, + &first_table->grant.privilege, + &first_table->grant.m_internal, + 0, 0)) || + unlikely(check_access(thd, priv_needed, first_table->next_local->db.str, + &first_table->next_local->grant.privilege, + &first_table->next_local->grant.m_internal, + 0, 0))) DBUG_RETURN(TRUE); - if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE)) + if (unlikely(check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, + FALSE))) DBUG_RETURN(TRUE); /* Not allowed with EXCHANGE PARTITION */ @@ -109,31 +113,32 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd) @retval FALSE if OK, otherwise error is reported and TRUE is returned. */ + static bool check_exchange_partition(TABLE *table, TABLE *part_table) { DBUG_ENTER("check_exchange_partition"); /* Both tables must exist */ - if (!part_table || !table) + if (unlikely(!part_table || !table)) { my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0)); DBUG_RETURN(TRUE); } /* The first table must be partitioned, and the second must not */ - if (!part_table->part_info) + if (unlikely(!part_table->part_info)) { my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0)); DBUG_RETURN(TRUE); } - if (table->part_info) + if (unlikely(table->part_info)) { my_error(ER_PARTITION_EXCHANGE_PART_TABLE, MYF(0), table->s->table_name.str); DBUG_RETURN(TRUE); } - if (part_table->file->ht != partition_hton) + if (unlikely(part_table->file->ht != partition_hton)) { /* Only allowed on partitioned tables throught the generic ha_partition @@ -143,14 +148,14 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table) DBUG_RETURN(TRUE); } - if (table->file->ht != part_table->part_info->default_engine_type) + if (unlikely(table->file->ht != part_table->part_info->default_engine_type)) { my_error(ER_MIX_HANDLER_ERROR, MYF(0)); DBUG_RETURN(TRUE); } /* Verify that table is not tmp table, partitioned tables cannot be tmp. */ - if (table->s->tmp_table != NO_TMP_TABLE) + if (unlikely(table->s->tmp_table != NO_TMP_TABLE)) { my_error(ER_PARTITION_EXCHANGE_TEMP_TABLE, MYF(0), table->s->table_name.str); @@ -158,7 +163,7 @@ static bool check_exchange_partition(TABLE *table, TABLE *part_table) } /* The table cannot have foreign keys constraints or be referenced */ - if(!table->file->can_switch_engines()) + if (unlikely(!table->file->can_switch_engines())) { my_error(ER_PARTITION_EXCHANGE_FOREIGN_KEY, MYF(0), table->s->table_name.str); @@ -197,8 +202,8 @@ static bool compare_table_with_partition(THD *thd, TABLE *table, /* mark all columns used, since they are used when preparing the new table */ part_table->use_all_columns(); table->use_all_columns(); - if (mysql_prepare_alter_table(thd, part_table, &part_create_info, - &part_alter_info, &part_alter_ctx)) + if (unlikely(mysql_prepare_alter_table(thd, part_table, &part_create_info, + &part_alter_info, &part_alter_ctx))) { my_error(ER_TABLES_DIFFERENT_METADATA, MYF(0)); DBUG_RETURN(TRUE); @@ -336,11 +341,8 @@ static bool exchange_name_with_ddl_log(THD *thd, handler *file= NULL; DBUG_ENTER("exchange_name_with_ddl_log"); - if (!(file= get_new_handler(NULL, thd->mem_root, ht))) - { - mem_alloc_error(sizeof(handler)); + if (unlikely(!(file= get_new_handler(NULL, thd->mem_root, ht)))) DBUG_RETURN(TRUE); - } /* prepare the action entry */ exchange_entry.entry_type= DDL_LOG_ENTRY_CODE; @@ -360,12 +362,13 @@ static bool exchange_name_with_ddl_log(THD *thd, */ DBUG_EXECUTE_IF("exchange_partition_fail_1", goto err_no_action_written;); DBUG_EXECUTE_IF("exchange_partition_abort_1", DBUG_SUICIDE();); - if (write_ddl_log_entry(&exchange_entry, &log_entry)) + if (unlikely(write_ddl_log_entry(&exchange_entry, &log_entry))) goto err_no_action_written; DBUG_EXECUTE_IF("exchange_partition_fail_2", goto err_no_execute_written;); DBUG_EXECUTE_IF("exchange_partition_abort_2", DBUG_SUICIDE();); - if (write_execute_ddl_log_entry(log_entry->entry_pos, FALSE, &exec_log_entry)) + if (unlikely(write_execute_ddl_log_entry(log_entry->entry_pos, FALSE, + &exec_log_entry))) goto err_no_execute_written; /* ddl_log is written and synced */ @@ -383,7 +386,7 @@ static bool exchange_name_with_ddl_log(THD *thd, error_set= TRUE; goto err_rename;); DBUG_EXECUTE_IF("exchange_partition_abort_3", DBUG_SUICIDE();); - if (file->ha_rename_table(name, tmp_name)) + if (unlikely(file->ha_rename_table(name, tmp_name))) { my_error(ER_ERROR_ON_RENAME, MYF(0), name, tmp_name, my_errno); error_set= TRUE; @@ -391,7 +394,7 @@ static bool exchange_name_with_ddl_log(THD *thd, } DBUG_EXECUTE_IF("exchange_partition_fail_4", goto err_rename;); DBUG_EXECUTE_IF("exchange_partition_abort_4", DBUG_SUICIDE();); - if (deactivate_ddl_log_entry(log_entry->entry_pos)) + if (unlikely(deactivate_ddl_log_entry(log_entry->entry_pos))) goto err_rename; /* call rename table from partition to table */ @@ -400,7 +403,7 @@ static bool exchange_name_with_ddl_log(THD *thd, error_set= TRUE; goto err_rename;); DBUG_EXECUTE_IF("exchange_partition_abort_5", DBUG_SUICIDE();); - if (file->ha_rename_table(from_name, name)) + if (unlikely(file->ha_rename_table(from_name, name))) { my_error(ER_ERROR_ON_RENAME, MYF(0), from_name, name, my_errno); error_set= TRUE; @@ -408,7 +411,7 @@ static bool exchange_name_with_ddl_log(THD *thd, } DBUG_EXECUTE_IF("exchange_partition_fail_6", goto err_rename;); DBUG_EXECUTE_IF("exchange_partition_abort_6", DBUG_SUICIDE();); - if (deactivate_ddl_log_entry(log_entry->entry_pos)) + if (unlikely(deactivate_ddl_log_entry(log_entry->entry_pos))) goto err_rename; /* call rename table from tmp-nam to partition */ @@ -417,7 +420,7 @@ static bool exchange_name_with_ddl_log(THD *thd, error_set= TRUE; goto err_rename;); DBUG_EXECUTE_IF("exchange_partition_abort_7", DBUG_SUICIDE();); - if (file->ha_rename_table(tmp_name, from_name)) + if (unlikely(file->ha_rename_table(tmp_name, from_name))) { my_error(ER_ERROR_ON_RENAME, MYF(0), tmp_name, from_name, my_errno); error_set= TRUE; @@ -425,7 +428,7 @@ static bool exchange_name_with_ddl_log(THD *thd, } DBUG_EXECUTE_IF("exchange_partition_fail_8", goto err_rename;); DBUG_EXECUTE_IF("exchange_partition_abort_8", DBUG_SUICIDE();); - if (deactivate_ddl_log_entry(log_entry->entry_pos)) + if (unlikely(deactivate_ddl_log_entry(log_entry->entry_pos))) goto err_rename; /* The exchange is complete and ddl_log is deactivated */ @@ -525,23 +528,24 @@ bool Sql_cmd_alter_table_exchange_partition:: to be able to verify the structure/metadata. */ table_list->mdl_request.set_type(MDL_SHARED_NO_WRITE); - if (open_tables(thd, &table_list, &table_counter, 0, - &alter_prelocking_strategy)) + if (unlikely(open_tables(thd, &table_list, &table_counter, 0, + &alter_prelocking_strategy))) DBUG_RETURN(true); part_table= table_list->table; swap_table= swap_table_list->table; - if (check_exchange_partition(swap_table, part_table)) + if (unlikely(check_exchange_partition(swap_table, part_table))) DBUG_RETURN(TRUE); /* set lock pruning on first table */ partition_name= alter_info->partition_names.head(); - if (table_list->table->part_info-> - set_named_partition_bitmap(partition_name, strlen(partition_name))) + if (unlikely(table_list->table->part_info-> + set_named_partition_bitmap(partition_name, + strlen(partition_name)))) DBUG_RETURN(true); - if (lock_tables(thd, table_list, table_counter, 0)) + if (unlikely(lock_tables(thd, table_list, table_counter, 0))) DBUG_RETURN(true); @@ -569,32 +573,35 @@ bool Sql_cmd_alter_table_exchange_partition:: table_list->next_local->db.str, temp_name, "", FN_IS_TMP); - if (!(part_elem= part_table->part_info->get_part_elem(partition_name, - part_file_name + part_file_name_len, - sizeof(part_file_name) - part_file_name_len, - &swap_part_id))) + if (unlikely(!(part_elem= + part_table->part_info->get_part_elem(partition_name, + part_file_name + + part_file_name_len, + sizeof(part_file_name) - + part_file_name_len, + &swap_part_id)))) { - // my_error(ER_UNKNOWN_PARTITION, MYF(0), partition_name, - // part_table->alias); DBUG_RETURN(TRUE); } - if (swap_part_id == NOT_A_PARTITION_ID) + if (unlikely(swap_part_id == NOT_A_PARTITION_ID)) { DBUG_ASSERT(part_table->part_info->is_sub_partitioned()); my_error(ER_PARTITION_INSTEAD_OF_SUBPARTITION, MYF(0)); DBUG_RETURN(TRUE); } - if (compare_table_with_partition(thd, swap_table, part_table, part_elem, - swap_part_id)) + if (unlikely(compare_table_with_partition(thd, swap_table, part_table, + part_elem, + swap_part_id))) DBUG_RETURN(TRUE); /* Table and partition has same structure/options, OK to exchange */ thd_proc_info(thd, "Verifying data with partition"); - if (verify_data_with_partition(swap_table, part_table, swap_part_id)) + if (unlikely(verify_data_with_partition(swap_table, part_table, + swap_part_id))) DBUG_RETURN(TRUE); /* @@ -621,8 +628,8 @@ bool Sql_cmd_alter_table_exchange_partition:: DEBUG_SYNC(thd, "swap_partition_before_rename"); - if (exchange_name_with_ddl_log(thd, swap_file_name, part_file_name, - temp_file_name, table_hton)) + if (unlikely(exchange_name_with_ddl_log(thd, swap_file_name, part_file_name, + temp_file_name, table_hton))) goto err; /* @@ -630,9 +637,10 @@ bool Sql_cmd_alter_table_exchange_partition:: better to keep master/slave in consistent state. Alternative would be to try to revert the exchange operation and issue error. */ - (void) thd->locked_tables_list.reopen_tables(thd); + (void) thd->locked_tables_list.reopen_tables(thd, false); - if ((error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()))) + if (unlikely((error= write_bin_log(thd, TRUE, thd->query(), + thd->query_length())))) { /* The error is reported in write_bin_log(). @@ -651,7 +659,7 @@ err: part_table_mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE); } - if (!error) + if (unlikely(!error)) my_ok(thd); // For query cache @@ -823,7 +831,8 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) partition= (ha_partition*) first_table->table->file; /* Invoke the handler method responsible for truncating the partition. */ - if ((error= partition->truncate_partition(alter_info, &binlog_stmt))) + if (unlikely(error= partition->truncate_partition(alter_info, + &binlog_stmt))) partition->print_error(error, MYF(0)); /* @@ -836,7 +845,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) Since we've changed data within the table, we also have to invalidate the query cache for it. */ - if (error != HA_ERR_WRONG_COMMAND) + if (likely(error != HA_ERR_WRONG_COMMAND)) { query_cache_invalidate3(thd, first_table, FALSE); if (binlog_stmt) @@ -851,7 +860,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd) if (thd->locked_tables_mode) ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE); - if (! error) + if (likely(!error)) my_ok(thd); // Invalidate query cache diff --git a/sql/sql_plist.h b/sql/sql_plist.h index 14f6eb5e2aa..bb9889cc534 100644 --- a/sql/sql_plist.h +++ b/sql/sql_plist.h @@ -230,7 +230,7 @@ protected: void reset() {} void inc() {} void dec() {} - void swap(I_P_List_null_counter &rhs) {} + void swap(I_P_List_null_counter &) {} }; @@ -262,14 +262,14 @@ public: template <typename T> class I_P_List_no_push_back { protected: - I_P_List_no_push_back(T **a) {}; - void set_last(T **a) {} + I_P_List_no_push_back(T **) {} + void set_last(T **) {} /* T** get_last() const method is intentionally left unimplemented in order to prohibit usage of push_back() method in lists which use this policy. */ - void swap(I_P_List_no_push_back<T> &rhs) {} + void swap(I_P_List_no_push_back<T> &) {} }; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 605f96293d3..ac1524381c7 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2005, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB Corporation. + Copyright (c) 2005, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,9 +40,6 @@ #include <mysql/plugin_encryption.h> #include "sql_plugin_compat.h" -#define REPORT_TO_LOG 1 -#define REPORT_TO_USER 2 - #ifdef HAVE_LINK_H #include <link.h> #endif @@ -333,24 +330,6 @@ bool plugin_is_forced(struct st_plugin_int *p) p->load_option == PLUGIN_FORCE_PLUS_PERMANENT; } -static void report_error(int where_to, uint error, ...) -{ - va_list args; - DBUG_ASSERT(where_to & (REPORT_TO_USER | REPORT_TO_LOG)); - if (where_to & REPORT_TO_USER) - { - va_start(args, error); - my_printv_error(error, ER(error), MYF(0), args); - va_end(args); - } - if (where_to & REPORT_TO_LOG) - { - va_start(args, error); - error_log_print(ERROR_LEVEL, ER_DEFAULT(error), args); - va_end(args); - } -} - /** Check if the provided path is valid in the sense that it does cause a relative reference outside the directory. @@ -523,7 +502,7 @@ static void free_plugin_mem(struct st_plugin_dl *p) @param plugin_dl Structure where the data should be put @param sym Reverence on version info @param dlpath Path to the module - @param report What errors should be reported + @param MyFlags Where errors should be reported (0 or ME_ERROR_LOG) @retval FALSE OK @retval TRUE ERROR @@ -531,14 +510,13 @@ static void free_plugin_mem(struct st_plugin_dl *p) #ifdef HAVE_DLOPEN static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, - void *sym, char *dlpath, - int report) + void *sym, char *dlpath, myf MyFlags) { DBUG_ENTER("read_maria_plugin_info"); /* Determine interface version */ if (!sym) { - report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_interface_version_sym); + my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, plugin_interface_version_sym); DBUG_RETURN(TRUE); } plugin_dl->mariaversion= 0; @@ -547,14 +525,14 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, if (plugin_dl->mysqlversion < min_plugin_interface_version || (plugin_dl->mysqlversion >> 8) > (MYSQL_PLUGIN_INTERFACE_VERSION >> 8)) { - report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, ENOEXEC, + my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dlpath, ENOEXEC, "plugin interface version mismatch"); DBUG_RETURN(TRUE); } /* Find plugin declarations */ if (!(sym= dlsym(plugin_dl->handle, plugin_declarations_sym))) { - report_error(report, ER_CANT_FIND_DL_ENTRY, plugin_declarations_sym); + my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, plugin_declarations_sym); DBUG_RETURN(TRUE); } @@ -584,7 +562,7 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, MYF(MY_ZEROFILL|MY_WME)); if (!cur) { - report_error(report, ER_OUTOFMEMORY, + my_error(ER_OUTOFMEMORY, MyFlags, static_cast<int>(plugin_dl->dl.length)); DBUG_RETURN(TRUE); } @@ -639,15 +617,14 @@ static my_bool read_mysql_plugin_info(struct st_plugin_dl *plugin_dl, @param plugin_dl Structure where the data should be put @param sym Reverence on version info @param dlpath Path to the module - @param report what errors should be reported + @param MyFlags Where errors should be reported (0 or ME_ERROR_LOG) @retval FALSE OK @retval TRUE ERROR */ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, - void *sym, char *dlpath, - int report) + void *sym, char *dlpath, myf MyFlags) { DBUG_ENTER("read_maria_plugin_info"); @@ -658,7 +635,7 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, Actually this branch impossible because in case of absence of maria version we try mysql version. */ - report_error(report, ER_CANT_FIND_DL_ENTRY, + my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, maria_plugin_interface_version_sym); DBUG_RETURN(TRUE); } @@ -668,14 +645,14 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, if (plugin_dl->mariaversion < min_maria_plugin_interface_version || (plugin_dl->mariaversion >> 8) > (MARIA_PLUGIN_INTERFACE_VERSION >> 8)) { - report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, ENOEXEC, + my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dlpath, ENOEXEC, "plugin interface version mismatch"); DBUG_RETURN(TRUE); } /* Find plugin declarations */ if (!(sym= dlsym(plugin_dl->handle, maria_plugin_declarations_sym))) { - report_error(report, ER_CANT_FIND_DL_ENTRY, maria_plugin_declarations_sym); + my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, maria_plugin_declarations_sym); DBUG_RETURN(TRUE); } if (plugin_dl->mariaversion != MARIA_PLUGIN_INTERFACE_VERSION) @@ -688,7 +665,7 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, sizeof_st_plugin= *(int *)sym; else { - report_error(report, ER_CANT_FIND_DL_ENTRY, maria_sizeof_st_plugin_sym); + my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, maria_sizeof_st_plugin_sym); DBUG_RETURN(TRUE); } @@ -705,7 +682,7 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, MYF(MY_ZEROFILL|MY_WME)); if (!cur) { - report_error(report, ER_OUTOFMEMORY, + my_error(ER_OUTOFMEMORY, MyFlags, static_cast<int>(plugin_dl->dl.length)); DBUG_RETURN(TRUE); } @@ -731,7 +708,7 @@ static my_bool read_maria_plugin_info(struct st_plugin_dl *plugin_dl, } #endif /* HAVE_DLOPEN */ -static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) +static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, myf MyFlags) { #ifdef HAVE_DLOPEN char dlpath[FN_REFLEN]; @@ -755,7 +732,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) system_charset_info, 1) || plugin_dir_len + dl->length + 1 >= FN_REFLEN) { - report_error(report, ER_UDF_NO_PATHS); + my_error(ER_UDF_NO_PATHS, MyFlags); DBUG_RETURN(0); } /* If this dll is already loaded just increase ref_count. */ @@ -772,7 +749,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) /* Open new dll handle */ if (!(plugin_dl.handle= dlopen(dlpath, RTLD_NOW))) { - report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, my_dlerror(dlpath)); + my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dlpath, errno, my_dlerror(dlpath)); goto ret; } dlopen_count++; @@ -792,12 +769,12 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) dlsym(plugin_dl.handle, plugin_interface_version_sym), dlpath, - report)) + MyFlags)) goto ret; } else { - if (read_maria_plugin_info(&plugin_dl, sym, dlpath, report)) + if (read_maria_plugin_info(&plugin_dl, sym, dlpath, MyFlags)) goto ret; } @@ -815,7 +792,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) my_snprintf(buf, sizeof(buf), "service '%s' interface version mismatch", list_of_services[i].name); - report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, ENOEXEC, buf); + my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dlpath, ENOEXEC, buf); goto ret; } tmp_backup[plugin_dl.nbackups++].save(ptr); @@ -830,7 +807,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) if (!plugin_dl.ptr_backup) { restore_ptr_backup(plugin_dl.nbackups, tmp_backup); - report_error(report, ER_OUTOFMEMORY, bytes); + my_error(ER_OUTOFMEMORY, MyFlags, bytes); goto ret; } memcpy(plugin_dl.ptr_backup, tmp_backup, bytes); @@ -840,7 +817,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) plugin_dl.dl.length= dl->length * files_charset_info->mbmaxlen + 1; if (! (plugin_dl.dl.str= (char*) my_malloc(plugin_dl.dl.length, MYF(0)))) { - report_error(report, ER_OUTOFMEMORY, + my_error(ER_OUTOFMEMORY, MyFlags, static_cast<int>(plugin_dl.dl.length)); goto ret; } @@ -853,7 +830,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_CSTRING *dl, int report) /* Add this dll to array */ if (! (tmp= plugin_dl_insert_or_reuse(&plugin_dl))) { - report_error(report, ER_OUTOFMEMORY, + my_error(ER_OUTOFMEMORY, MyFlags, static_cast<int>(sizeof(struct st_plugin_dl))); goto ret; } @@ -866,7 +843,7 @@ ret: #else DBUG_ENTER("plugin_dl_add"); - report_error(report, ER_FEATURE_DISABLED, "plugin", "HAVE_DLOPEN"); + my_error(ER_FEATURE_DISABLED, MyFlags, "plugin", "HAVE_DLOPEN"); DBUG_RETURN(0); #endif } @@ -1101,7 +1078,7 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) Requires that a write-lock is held on LOCK_system_variables_hash */ static bool plugin_add(MEM_ROOT *tmp_root, - const LEX_CSTRING *name, LEX_CSTRING *dl, int report) + const LEX_CSTRING *name, LEX_CSTRING *dl, myf MyFlags) { struct st_plugin_int tmp, *maybe_dupe; struct st_maria_plugin *plugin; @@ -1111,13 +1088,13 @@ static bool plugin_add(MEM_ROOT *tmp_root, if (name->str && plugin_find_internal(name, MYSQL_ANY_PLUGIN)) { - report_error(report, ER_PLUGIN_INSTALLED, name->str); + my_error(ER_PLUGIN_INSTALLED, MyFlags, name->str); DBUG_RETURN(TRUE); } /* Clear the whole struct to catch future extensions. */ bzero((char*) &tmp, sizeof(tmp)); fix_dl_name(tmp_root, dl); - if (! (tmp.plugin_dl= plugin_dl_add(dl, report))) + if (! (tmp.plugin_dl= plugin_dl_add(dl, MyFlags))) DBUG_RETURN(TRUE); /* Find plugin by name */ for (plugin= tmp.plugin_dl->plugins; plugin->info; plugin++) @@ -1143,7 +1120,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, { if (plugin->name != maybe_dupe->plugin->name) { - report_error(report, ER_UDF_EXISTS, plugin->name); + my_error(ER_UDF_EXISTS, MyFlags, plugin->name); DBUG_RETURN(TRUE); } dupes++; @@ -1160,7 +1137,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, plugin_type_names[plugin->type].str, " plugin ", tmp.name.str, " not supported by this version of the server", NullS); - report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, ENOEXEC, buf); + my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dl->str, ENOEXEC, buf); goto err; } @@ -1173,7 +1150,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, " is prohibited by --plugin-maturity=", plugin_maturity_names[plugin_maturity], NullS); - report_error(report, ER_CANT_OPEN_LIBRARY, dl->str, EPERM, buf); + my_error(ER_CANT_OPEN_LIBRARY, MyFlags, dl->str, EPERM, buf); goto err; } else if (plugin_maturity_map[plugin->maturity] < SERVER_MATURITY_LEVEL) @@ -1211,7 +1188,7 @@ err: DBUG_ASSERT(!name->str || !dupes); // dupes is ONLY for name->str == 0 if (errs == 0 && oks == 0 && !dupes) // no plugin was found - report_error(report, ER_CANT_FIND_DL_ENTRY, name->str); + my_error(ER_CANT_FIND_DL_ENTRY, MyFlags, name->str); plugin_dl_del(tmp.plugin_dl); DBUG_RETURN(errs > 0 || oks + dupes == 0); @@ -1870,11 +1847,11 @@ static void plugin_load(MEM_ROOT *tmp_root) the mutex here to satisfy the assert */ mysql_mutex_lock(&LOCK_plugin); - plugin_add(tmp_root, &name, &dl, REPORT_TO_LOG); + plugin_add(tmp_root, &name, &dl, MYF(ME_ERROR_LOG)); free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); mysql_mutex_unlock(&LOCK_plugin); } - if (error > 0) + if (unlikely(error > 0)) sql_print_error(ER_THD(new_thd, ER_GET_ERRNO), my_errno, table->file->table_type()); end_read_record(&read_record_info); @@ -1926,7 +1903,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list) free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); name.str= 0; // load everything if (plugin_add(tmp_root, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl, - REPORT_TO_LOG)) + MYF(ME_ERROR_LOG))) goto error; } else @@ -1934,7 +1911,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list) free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); mysql_mutex_lock(&LOCK_plugin); if (plugin_add(tmp_root, (LEX_CSTRING*) &name, (LEX_CSTRING*) &dl, - REPORT_TO_LOG)) + MYF(ME_ERROR_LOG))) goto error; } mysql_mutex_unlock(&LOCK_plugin); @@ -2126,7 +2103,7 @@ static bool finalize_install(THD *thd, TABLE *table, const LEX_CSTRING *name, { if (plugin_initialize(thd->mem_root, tmp, argc, argv, false)) { - report_error(REPORT_TO_USER, ER_CANT_INITIALIZE_UDF, name->str, + my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str, "Plugin initialization function failed."); tmp->state= PLUGIN_IS_DELETED; return 1; @@ -2154,7 +2131,7 @@ static bool finalize_install(THD *thd, TABLE *table, const LEX_CSTRING *name, files_charset_info); error= table->file->ha_write_row(table->record[0]); reenable_binlog(thd); - if (error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); tmp->state= PLUGIN_IS_DELETED; @@ -2189,7 +2166,7 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name, if (my_load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv, NULL)) { - report_error(REPORT_TO_USER, ER_PLUGIN_IS_NOT_LOADED, name->str); + my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), name->str); DBUG_RETURN(TRUE); } @@ -2218,8 +2195,8 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name, mysql_audit_acquire_plugins(thd, event_class_mask); mysql_mutex_lock(&LOCK_plugin); - error= plugin_add(thd->mem_root, name, &dl, REPORT_TO_USER); - if (error) + error= plugin_add(thd->mem_root, name, &dl, MYF(0)); + if (unlikely(error)) goto err; if (name->str) @@ -2235,7 +2212,7 @@ bool mysql_install_plugin(THD *thd, const LEX_CSTRING *name, } } - if (error) + if (unlikely(error)) { reap_needed= true; reap_plugins(); @@ -2298,7 +2275,7 @@ static bool do_uninstall(THD *thd, TABLE *table, const LEX_CSTRING *name) tmp_disable_binlog(thd); error= table->file->ha_delete_row(table->record[0]); reenable_binlog(thd); - if (error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); return 1; @@ -2330,6 +2307,16 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_CSTRING *name, if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) DBUG_RETURN(TRUE); + if (!table->key_info) + { + my_printf_error(ER_UNKNOWN_ERROR, + "The table %s.%s has no primary key. " + "Please check the table definition and " + "create the primary key accordingly.", MYF(0), + table->s->db.str, table->s->table_name.str); + DBUG_RETURN(TRUE); + } + /* Pre-acquire audit plugins for events that may potentially occur during [UN]INSTALL PLUGIN. @@ -2486,7 +2473,7 @@ bool plugin_dl_foreach(THD *thd, const LEX_CSTRING *dl, if (dl) { mysql_mutex_lock(&LOCK_plugin); - st_plugin_dl *plugin_dl= plugin_dl_add(dl, REPORT_TO_USER); + st_plugin_dl *plugin_dl= plugin_dl_add(dl, MYF(0)); mysql_mutex_unlock(&LOCK_plugin); if (!plugin_dl) @@ -2751,7 +2738,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var, goto err; result= find_set(typelib, str, length, NULL, &error, &error_len, ¬_used); - if (error_len) + if (unlikely(error_len)) goto err; } else @@ -2870,7 +2857,7 @@ sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length, if (!locked) mysql_mutex_unlock(&LOCK_plugin); - if (!throw_error && !var) + if (unlikely(!throw_error && !var)) my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (int) (length ? length : strlen(str)), (char*) str); DBUG_RETURN(var); @@ -4121,7 +4108,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, error= handle_options(argc, &argv, opts, mark_changed); (*argc)++; /* add back one for the program name */ - if (error) + if (unlikely(error)) { sql_print_error("Parsing options for plugin '%s' failed.", tmp->name.str); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 24f3cc66c6b..d4c96ebc535 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -380,16 +380,18 @@ static bool send_prep_stmt(Prepared_statement *stmt, uint columns) XXX: fix this nasty upcast from List<Item_param> to List<Item> */ error= my_net_write(net, buff, sizeof(buff)); - if (stmt->param_count && ! error) + if (stmt->param_count && likely(!error)) { error= thd->protocol_text.send_result_set_metadata((List<Item> *) &stmt->lex->param_list, Protocol::SEND_EOF); } - if (!error) + if (likely(!error)) + { /* Flag that a response has already been sent */ thd->get_stmt_da()->disable_status(); + } DBUG_RETURN(error); } @@ -427,7 +429,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, static ulong get_param_length(uchar **packet, ulong len) { - reg1 uchar *pos= *packet; + uchar *pos= *packet; if (len < 1) return 0; if (*pos < 251) @@ -1528,7 +1530,7 @@ static int mysql_test_select(Prepared_statement *stmt, It is not SELECT COMMAND for sure, so setup_tables will be called as usual, and we pass 0 as setup_tables_done_option */ - if (unit->prepare(thd, 0, 0)) + if (unit->prepare(unit->derived, 0, 0)) goto error; if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare()) { @@ -1699,7 +1701,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt, thd->lex->used_tables= 0; // Updated by setup_fields /* Calls JOIN::prepare */ - DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option)); + DBUG_RETURN(lex->unit.prepare(lex->unit.derived, 0, setup_tables_done_option)); } /** @@ -2202,6 +2204,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt, if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode, lex->ident.str, lex->insert_list, + lex->ha_rkey_mode, lex->select_lex.where))) DBUG_RETURN(1); @@ -2500,8 +2503,28 @@ static bool check_prepared_statement(Prepared_statement *stmt) break; } if (res == 0) - DBUG_RETURN(stmt->is_sql_prepare() ? - FALSE : (send_prep_stmt(stmt, 0) || thd->protocol->flush())); + { + if (!stmt->is_sql_prepare()) + { + if (lex->describe || lex->analyze_stmt) + { + if (!lex->result && + !(lex->result= new (stmt->mem_root) select_send(thd))) + DBUG_RETURN(TRUE); + List<Item> field_list; + thd->prepare_explain_fields(lex->result, &field_list, + lex->describe, lex->analyze_stmt); + res= send_prep_stmt(stmt, lex->result->field_count(field_list)) || + lex->result->send_result_set_metadata(field_list, + Protocol::SEND_EOF); + } + else + res= send_prep_stmt(stmt, 0); + if (!res) + thd->protocol->flush(); + } + DBUG_RETURN(FALSE); + } error: DBUG_RETURN(TRUE); } @@ -3530,7 +3553,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) #else param->set_longdata(thd->extra_data, thd->extra_length); #endif - if (thd->get_stmt_da()->is_error()) + if (unlikely(thd->get_stmt_da()->is_error())) { stmt->state= Query_arena::STMT_ERROR; stmt->last_errno= thd->get_stmt_da()->sql_errno(); @@ -3576,7 +3599,7 @@ bool Select_fetch_protocol_binary::send_eof() Don't send EOF if we're in error condition (which implies we've already sent or are sending an error) */ - if (thd->is_error()) + if (unlikely(thd->is_error())) return true; ::my_eof(thd); @@ -3662,7 +3685,7 @@ Execute_sql_statement::execute_server_code(THD *thd) error= parse_sql(thd, &parser_state, NULL) || thd->is_error(); - if (error) + if (unlikely(error)) goto end; thd->lex->set_trg_event_type_for_tables(); @@ -3673,7 +3696,7 @@ Execute_sql_statement::execute_server_code(THD *thd) thd->m_statement_psi= parent_locker; /* report error issued during command execution */ - if (error == 0 && thd->spcont == NULL) + if (likely(error == 0) && thd->spcont == NULL) general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length()); @@ -3888,7 +3911,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) if (! (lex= new (mem_root) st_lex_local)) DBUG_RETURN(TRUE); - stmt_lex= lex; + lex->stmt_lex= lex; if (set_db(&thd->db)) DBUG_RETURN(TRUE); @@ -3925,9 +3948,9 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) lex_start(thd); lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE; - error= parse_sql(thd, & parser_state, NULL) || - thd->is_error() || - init_param_array(this); + error= (parse_sql(thd, & parser_state, NULL) || + thd->is_error() || + init_param_array(this)); lex->set_trg_event_type_for_tables(); @@ -3959,10 +3982,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) Item_null objects. */ - if (error == 0) + if (likely(error == 0)) error= check_prepared_statement(this); - if (error) + if (unlikely(error)) { /* let the following code know we're not in PS anymore, @@ -4001,7 +4024,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= old_stmt_arena; - if (error == 0) + if (likely(error == 0)) { setup_set_params(); lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE; @@ -4131,7 +4154,7 @@ Prepared_statement::execute_loop(String *expanded_query, DBUG_ASSERT(thd->free_list == NULL); /* Check if we got an error when sending long data */ - if (state == Query_arena::STMT_ERROR) + if (unlikely(state == Query_arena::STMT_ERROR)) { my_message(last_errno, last_error, MYF(0)); return TRUE; @@ -4174,7 +4197,7 @@ reexecute: if (WSREP_ON) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); switch (thd->wsrep_conflict_state) { case CERT_FAILURE: @@ -4191,12 +4214,13 @@ reexecute: default: break; } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ - if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) && - error && !thd->is_fatal_error && !thd->killed && + if (unlikely(error) && + (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) && + !thd->is_fatal_error && !thd->killed && reprepare_observer.is_invalidated() && reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS) { @@ -4205,7 +4229,7 @@ reexecute: error= reprepare(); - if (! error) /* Success */ + if (likely(!error)) /* Success */ goto reexecute; } reset_stmt_params(this); @@ -4218,7 +4242,7 @@ my_bool bulk_parameters_set(THD *thd) DBUG_ENTER("bulk_parameters_set"); Prepared_statement *stmt= (Prepared_statement *) thd->bulk_param; - if (stmt && stmt->set_bulk_parameters(FALSE)) + if (stmt && unlikely(stmt->set_bulk_parameters(FALSE))) DBUG_RETURN(TRUE); DBUG_RETURN(FALSE); } @@ -4369,7 +4393,7 @@ reexecute: if (WSREP_ON) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); switch (thd->wsrep_conflict_state) { case CERT_FAILURE: @@ -4386,12 +4410,13 @@ reexecute: default: break; } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } #endif /* WITH_WSREP */ - if ((sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) && - error && !thd->is_fatal_error && !thd->killed && + if (unlikely(error) && + (sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) && + !thd->is_fatal_error && !thd->killed && reprepare_observer.is_invalidated() && reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS) { @@ -4400,7 +4425,7 @@ reexecute: error= reprepare(); - if (! error) /* Success */ + if (likely(!error)) /* Success */ goto reexecute; } } @@ -4475,8 +4500,8 @@ Prepared_statement::reprepare() status_var_increment(thd->status_var.com_stmt_reprepare); - if (mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name, TRUE, - &cur_db_changed)) + if (unlikely(mysql_opt_change_db(thd, &stmt_db_name, &saved_cur_db_name, + TRUE, &cur_db_changed))) return TRUE; sql_mode_t save_sql_mode= thd->variables.sql_mode; @@ -4489,7 +4514,7 @@ Prepared_statement::reprepare() if (cur_db_changed) mysql_change_db(thd, (LEX_CSTRING*) &saved_cur_db_name, TRUE); - if (! error) + if (likely(!error)) { swap_prepared_statement(©); swap_parameter_array(param_array, copy.param_array, param_count); @@ -4788,7 +4813,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) if (state == Query_arena::STMT_PREPARED && !qc_executed) state= Query_arena::STMT_EXECUTED; - if (error == 0 && this->lex->sql_command == SQLCOM_CALL) + if (likely(error == 0) && this->lex->sql_command == SQLCOM_CALL) { if (is_sql_prepare()) { @@ -4823,7 +4848,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) sub-statements inside stored procedures are not logged into the general log. */ - if (error == 0 && thd->spcont == NULL) + if (likely(error == 0 && thd->spcont == NULL)) general_log_write(thd, COM_STMT_EXECUTE, thd->query(), thd->query_length()); error: @@ -4851,7 +4876,7 @@ bool Prepared_statement::execute_immediate(const char *query, uint query_len) set_sql_prepare(); name= execute_immediate_stmt_name; // for DBUG_PRINT etc - if (prepare(query, query_len)) + if (unlikely(prepare(query, query_len))) DBUG_RETURN(true); if (param_count != thd->lex->prepared_stmt_params.elements) @@ -5224,7 +5249,7 @@ Protocol_local::store_string(const char *str, size_t length, src_cs != &my_charset_bin && dst_cs != &my_charset_bin) { - if (convert->copy(str, length, src_cs, dst_cs, &error_unused)) + if (unlikely(convert->copy(str, length, src_cs, dst_cs, &error_unused))) return TRUE; str= convert->ptr(); length= convert->length(); diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 7d2e1bae741..4e82b6a5d3a 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, Monty Program Ab. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 6c1a4a32fb4..9bcb9a30a4c 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -74,13 +74,13 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, If reload_acl_and_cache() is called from SIGHUP handler we have to allocate temporary THD for execution of acl_reload()/grant_reload(). */ - if (!thd && (thd= (tmp_thd= new THD(0)))) + if (unlikely(!thd) && (thd= (tmp_thd= new THD(0)))) { thd->thread_stack= (char*) &tmp_thd; thd->store_globals(); } - if (thd) + if (likely(thd)) { bool reload_acl_failed= acl_reload(thd); bool reload_grants_failed= grant_reload(thd); @@ -98,7 +98,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, } opt_noacl= 0; - if (tmp_thd) + if (unlikely(tmp_thd)) { delete tmp_thd; thd= 0; @@ -123,7 +123,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, } if (options & REFRESH_ERROR_LOG) - if (flush_error_log()) + if (unlikely(flush_error_log())) { /* When flush_error_log() failed, my_error() has not been called. diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 1095bb25d0b..0f7bb7748c1 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -173,14 +173,14 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) error= 1; } - if (!silent && !error) + if (likely(!silent && !error)) { binlog_error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - if (!binlog_error) + if (likely(!binlog_error)) my_ok(thd); } - if (!error) + if (likely(!error)) query_cache_invalidate3(thd, table_list, 0); err: @@ -223,7 +223,7 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table, new_alias= (lower_case_table_names == 2) ? &new_table->alias : &new_table->table_name; - if (is_temporary_table(new_table)) + if (thd->find_temporary_table(new_table, THD::TMP_TABLE_ANY)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias->str); DBUG_RETURN(1); // This can't be skipped @@ -332,7 +332,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, { my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db.str, old_alias.str); } - if (rc && !skip_error) + if (unlikely(rc && !skip_error)) DBUG_RETURN(1); DBUG_RETURN(0); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index e1d1190e58f..f01ec789186 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -374,7 +374,7 @@ static int send_file(THD *thd) We need net_flush here because the client will not know it needs to send us the file name until it has processed the load event entry */ - if (net_flush(net) || (packet_len = my_net_read(net)) == packet_error) + if (unlikely(net_flush(net) || (packet_len = my_net_read(net)) == packet_error)) { errmsg = "while reading file name"; goto err; @@ -1259,12 +1259,12 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name, goto end; } bzero((char*) &cache, sizeof(cache)); - if ((file= open_binlog(&cache, buf, &errormsg)) == (File)-1) + if (unlikely((file= open_binlog(&cache, buf, &errormsg)) == (File)-1)) goto end; errormsg= get_gtid_list_event(&cache, &glev); end_io_cache(&cache); mysql_file_close(file, MYF(MY_WME)); - if (errormsg) + if (unlikely(errormsg)) goto end; if (!glev || contains_all_slave_gtid(state, glev)) @@ -1371,14 +1371,14 @@ gtid_state_from_pos(const char *name, uint32 offset, String packet; Format_description_log_event *fdev= NULL; - if (gtid_state->load((const rpl_gtid *)NULL, 0)) + if (unlikely(gtid_state->load((const rpl_gtid *)NULL, 0))) { errormsg= "Internal error (out of memory?) initializing slave state " "while scanning binlog to find start position"; return errormsg; } - if ((file= open_binlog(&cache, name, &errormsg)) == (File)-1) + if (unlikely((file= open_binlog(&cache, name, &errormsg)) == (File)-1)) return errormsg; if (!(fdev= new Format_description_log_event(3))) @@ -1411,7 +1411,7 @@ gtid_state_from_pos(const char *name, uint32 offset, err= Log_event::read_log_event(&cache, &packet, fdev, opt_master_verify_checksum ? current_checksum_alg : BINLOG_CHECKSUM_ALG_OFF); - if (err) + if (unlikely(err)) { errormsg= "Could not read binlog while searching for slave start " "position on master"; @@ -1426,7 +1426,7 @@ gtid_state_from_pos(const char *name, uint32 offset, { Format_description_log_event *tmp; - if (found_format_description_event) + if (unlikely(found_format_description_event)) { errormsg= "Duplicate format description log event found while " "searching for old-style position in binlog"; @@ -1435,8 +1435,9 @@ gtid_state_from_pos(const char *name, uint32 offset, current_checksum_alg= get_checksum_alg(packet.ptr(), packet.length()); found_format_description_event= true; - if (!(tmp= new Format_description_log_event(packet.ptr(), packet.length(), - fdev))) + if (unlikely(!(tmp= new Format_description_log_event(packet.ptr(), + packet.length(), + fdev)))) { errormsg= "Corrupt Format_description event found or out-of-memory " "while searching for old-style position in binlog"; @@ -1459,7 +1460,8 @@ gtid_state_from_pos(const char *name, uint32 offset, goto end; } } - else if (typ != FORMAT_DESCRIPTION_EVENT && !found_format_description_event) + else if (unlikely(typ != FORMAT_DESCRIPTION_EVENT && + !found_format_description_event)) { errormsg= "Did not find format description log event while searching " "for old-style position in binlog"; @@ -1474,7 +1476,7 @@ gtid_state_from_pos(const char *name, uint32 offset, bool status; uint32 list_len; - if (found_gtid_list_event) + if (unlikely(found_gtid_list_event)) { errormsg= "Found duplicate Gtid_list_log_event while scanning binlog " "to find slave start position"; @@ -1483,7 +1485,7 @@ gtid_state_from_pos(const char *name, uint32 offset, status= Gtid_list_log_event::peek(packet.ptr(), packet.length(), current_checksum_alg, >id_list, &list_len, fdev); - if (status) + if (unlikely(status)) { errormsg= "Error reading Gtid_list_log_event while searching " "for old-style position in binlog"; @@ -1491,7 +1493,7 @@ gtid_state_from_pos(const char *name, uint32 offset, } err= gtid_state->load(gtid_list, list_len); my_free(gtid_list); - if (err) + if (unlikely(err)) { errormsg= "Internal error (out of memory?) initialising slave state " "while scanning binlog to find start position"; @@ -1499,7 +1501,7 @@ gtid_state_from_pos(const char *name, uint32 offset, } found_gtid_list_event= true; } - else if (!found_gtid_list_event) + else if (unlikely(!found_gtid_list_event)) { /* We did not find any Gtid_list_log_event, must be old binlog. */ goto end; @@ -1508,15 +1510,16 @@ gtid_state_from_pos(const char *name, uint32 offset, { rpl_gtid gtid; uchar flags2; - if (Gtid_log_event::peek(packet.ptr(), packet.length(), - current_checksum_alg, >id.domain_id, - >id.server_id, >id.seq_no, &flags2, fdev)) + if (unlikely(Gtid_log_event::peek(packet.ptr(), packet.length(), + current_checksum_alg, >id.domain_id, + >id.server_id, >id.seq_no, &flags2, + fdev))) { errormsg= "Corrupt gtid_log_event found while scanning binlog to find " "initial slave position"; goto end; } - if (gtid_state->update(>id)) + if (unlikely(gtid_state->update(>id))) { errormsg= "Internal error (out of memory?) updating slave state while " "scanning binlog to find start position"; @@ -1525,7 +1528,7 @@ gtid_state_from_pos(const char *name, uint32 offset, } } - if (!valid_pos) + if (unlikely(!valid_pos)) { errormsg= "Slave requested incorrect position in master binlog. " "Requested position %u in file '%s', but this position does not " @@ -2099,8 +2102,8 @@ static int init_binlog_sender(binlog_send_info *info, info->error= ER_UNKNOWN_ERROR; return 1; } - if ((error= check_slave_start_position(info, &info->errmsg, - &info->error_gtid))) + if (unlikely((error= check_slave_start_position(info, &info->errmsg, + &info->error_gtid)))) { info->error= error; return 1; @@ -2199,7 +2202,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, : BINLOG_CHECKSUM_ALG_OFF); linfo->pos= my_b_tell(log); - if (error) + if (unlikely(error)) { set_read_error(info, error); DBUG_RETURN(1); @@ -2333,7 +2336,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, : BINLOG_CHECKSUM_ALG_OFF); linfo->pos= my_b_tell(log); - if (error) + if (unlikely(error)) { set_read_error(info, error); DBUG_RETURN(1); @@ -2585,7 +2588,7 @@ static int send_events(binlog_send_info *info, IO_CACHE* log, LOG_INFO* linfo, : BINLOG_CHECKSUM_ALG_OFF); linfo->pos= my_b_tell(log); - if (error) + if (unlikely(error)) { set_read_error(info, error); return 1; @@ -2893,6 +2896,12 @@ err: thd->variables.max_allowed_packet= old_max_allowed_packet; delete info->fdev; + if (likely(info->error == 0)) + { + my_eof(thd); + DBUG_VOID_RETURN; + } + if ((info->error == ER_MASTER_FATAL_ERROR_READING_BINLOG || info->error == ER_SLAVE_SAME_ID) && binlog_open) { @@ -2954,17 +2963,10 @@ err: "mysql", rpl_gtid_slave_state_table_name.str); info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; } - else if (info->error != 0 && info->errmsg != NULL) + else if (info->errmsg != NULL) strcpy(info->error_text, info->errmsg); - if (info->error == 0) - { - my_eof(thd); - } - else - { - my_message(info->error, info->error_text, MYF(0)); - } + my_message(info->error, info->error_text, MYF(0)); DBUG_VOID_RETURN; } @@ -3283,9 +3285,9 @@ int reset_slave(THD *thd, Master_info* mi) } // delete relay logs, clear relay log coordinates - if ((error= purge_relay_logs(&mi->rli, thd, + if (unlikely((error= purge_relay_logs(&mi->rli, thd, 1 /* just reset */, - &errmsg))) + &errmsg)))) { sql_errno= ER_RELAY_LOG_FAIL; goto err; @@ -3343,7 +3345,7 @@ int reset_slave(THD *thd, Master_info* mi) repl_semisync_slave.reset_slave(mi); err: mi->unlock_slave_threads(); - if (error) + if (unlikely(error)) my_error(sql_errno, MYF(0), errmsg); DBUG_RETURN(error); } @@ -4042,7 +4044,7 @@ bool mysql_show_binlog_events(THD* thd) break; } - if (event_count < limit_end && log.error) + if (unlikely(event_count < limit_end && log.error)) { errmsg = "Wrong offset or I/O error"; mysql_mutex_unlock(log_lock); @@ -4223,7 +4225,7 @@ bool show_binlogs(THD* thd) if (protocol->write()) goto err; } - if(index_file->error == -1) + if (unlikely(index_file->error == -1)) goto err; mysql_bin_log.unlock_index(); my_eof(thd); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 958ab0201e0..fdd890795d9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -309,7 +309,7 @@ void dbug_serve_apcs(THD *thd, int n_calls) thd_proc_info(thd, "show_explain_trap"); my_sleep(30000); thd_proc_info(thd, save_proc_info); - if (thd->check_killed()) + if (unlikely(thd->check_killed(1))) break; } } @@ -351,7 +351,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, ulong setup_tables_done_option) { bool res; - register SELECT_LEX *select_lex = &lex->select_lex; + SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); MYSQL_SELECT_START(thd->query()); @@ -386,7 +386,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result, res|= thd->is_error(); if (unlikely(res)) result->abort_result_set(); - if (thd->killed == ABORT_QUERY && !thd->no_errors) + if (unlikely(thd->killed == ABORT_QUERY && !thd->no_errors)) { /* If LIMIT ROWS EXAMINED interrupted query execution, issue a warning, @@ -693,7 +693,7 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd) return false; } -void vers_select_conds_t::print(String *str, enum_query_type query_type) +void vers_select_conds_t::print(String *str, enum_query_type query_type) const { switch (type) { case SYSTEM_TIME_UNSPECIFIED: @@ -765,14 +765,14 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) { TABLE_LIST* derived= master_unit()->derived; // inner SELECT may not be a derived table (derived == NULL) - while (derived && outer_slex && !derived->vers_conditions) + while (derived && outer_slex && !derived->vers_conditions.is_set()) { derived= outer_slex->master_unit()->derived; outer_slex= outer_slex->outer_select(); } if (derived && outer_slex) { - DBUG_ASSERT(derived->vers_conditions); + DBUG_ASSERT(derived->vers_conditions.is_set()); outer_table= derived; } } @@ -791,13 +791,9 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) */ if (table->partition_names && table->table->part_info->vers_info) { - if (vers_conditions) + if (vers_conditions.is_set()) { -#define PART_VERS_ERR_MSG "%s PARTITION (%s)" - char buf[NAME_LEN*2 + sizeof(PART_VERS_ERR_MSG)]; - my_snprintf(buf, sizeof(buf), PART_VERS_ERR_MSG, table->alias.str, - table->partition_names->head()->c_ptr()); - my_error(ER_VERS_NOT_VERSIONED, MYF(0), buf); + my_error(ER_VERS_QUERY_IN_PARTITION, MYF(0), table->alias.str); DBUG_RETURN(-1); } else @@ -805,7 +801,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } #endif - if (outer_table && !vers_conditions) + if (outer_table && !vers_conditions.is_set()) { // propagate system_time from nearest outer SELECT_LEX vers_conditions= outer_table->vers_conditions; @@ -813,15 +809,15 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } // propagate system_time from sysvar - if (!vers_conditions) + if (!vers_conditions.is_set()) { if (vers_conditions.init_from_sysvar(thd)) DBUG_RETURN(-1); } - if (vers_conditions) + if (vers_conditions.is_set()) { - if (vers_conditions == SYSTEM_TIME_ALL) + if (vers_conditions.type == SYSTEM_TIME_ALL) continue; lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway @@ -837,13 +833,15 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) bool timestamps_only= table->table->versioned(VERS_TIMESTAMP); - if (vers_conditions) + if (vers_conditions.is_set()) { + thd->where= "FOR SYSTEM_TIME"; /* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires storing vers_conditions as Item and make some magic related to vers_system_time_t/VERS_TRX_ID at stage of fix_fields() (this is large refactoring). */ - vers_conditions.resolve_units(timestamps_only); + if (vers_conditions.resolve_units(thd)) + DBUG_RETURN(-1); if (timestamps_only && (vers_conditions.start.unit == VERS_TRX_ID || vers_conditions.end.unit == VERS_TRX_ID)) { @@ -852,10 +850,9 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) } } - Item *cond1= 0, *cond2= 0, *curr= 0; - // Temporary tables of can be created from INNODB tables and thus will - // have uint64 type of sys_trx_(start|end) field. - // They need special handling. + Item *cond1= NULL, *cond2= NULL, *cond3= NULL, *curr= NULL; + Item *point_in_time1= vers_conditions.start.item; + Item *point_in_time2= vers_conditions.end.item; TABLE *t= table->table; if (t->versioned(VERS_TIMESTAMP)) { @@ -869,19 +866,21 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) cond1= newx Item_func_eq(thd, row_end, curr); break; case SYSTEM_TIME_AS_OF: - cond1= newx Item_func_le(thd, row_start, vers_conditions.start.item); - cond2= newx Item_func_gt(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_le(thd, row_start, point_in_time1); + cond2= newx Item_func_gt(thd, row_end, point_in_time1); break; case SYSTEM_TIME_FROM_TO: - cond1= newx Item_func_lt(thd, row_start, vers_conditions.end.item); - cond2= newx Item_func_ge(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_lt(thd, row_start, point_in_time2); + cond2= newx Item_func_gt(thd, row_end, point_in_time1); + cond3= newx Item_func_lt(thd, point_in_time1, point_in_time2); break; case SYSTEM_TIME_BETWEEN: - cond1= newx Item_func_le(thd, row_start, vers_conditions.end.item); - cond2= newx Item_func_ge(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_le(thd, row_start, point_in_time2); + cond2= newx Item_func_gt(thd, row_end, point_in_time1); + cond3= newx Item_func_le(thd, point_in_time1, point_in_time2); break; case SYSTEM_TIME_BEFORE: - cond1= newx Item_func_lt(thd, row_end, vers_conditions.start.item); + cond1= newx Item_func_lt(thd, row_end, point_in_time1); break; default: DBUG_ASSERT(0); @@ -901,29 +900,33 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) break; case SYSTEM_TIME_AS_OF: trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID) - : vers_conditions.start.item; - cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start); - cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0); + ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID) + : point_in_time1; + cond1= newx Item_func_trt_trx_sees_eq(thd, trx_id0, row_start); + cond2= newx Item_func_trt_trx_sees(thd, row_end, trx_id0); break; case SYSTEM_TIME_FROM_TO: + cond3= newx Item_func_lt(thd, point_in_time1, point_in_time2); + /* fall through */ case SYSTEM_TIME_BETWEEN: trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID, true) - : vers_conditions.start.item; + ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true) + : point_in_time1; trx_id1= vers_conditions.end.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.end.item, TR_table::FLD_TRX_ID, false) - : vers_conditions.end.item; + ? newx Item_func_trt_id(thd, point_in_time2, TR_table::FLD_TRX_ID, false) + : point_in_time2; cond1= vers_conditions.type == SYSTEM_TIME_FROM_TO - ? newx Item_func_vtq_trx_sees(thd, trx_id1, row_start) - : newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start); - cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0); + ? newx Item_func_trt_trx_sees(thd, trx_id1, row_start) + : newx Item_func_trt_trx_sees_eq(thd, trx_id1, row_start); + cond2= newx Item_func_trt_trx_sees_eq(thd, row_end, trx_id0); + if (!cond3) + cond3= newx Item_func_le(thd, point_in_time1, point_in_time2); break; case SYSTEM_TIME_BEFORE: trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP - ? newx Item_func_vtq_id(thd, vers_conditions.start.item, TR_table::FLD_TRX_ID) - : vers_conditions.start.item; - cond1= newx Item_func_lt(thd, row_end, trx_id0); + ? newx Item_func_trt_id(thd, point_in_time1, TR_table::FLD_TRX_ID, true) + : point_in_time1; + cond1= newx Item_func_trt_trx_sees(thd, trx_id0, row_end); break; default: DBUG_ASSERT(0); @@ -933,6 +936,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables) if (cond1) { cond1= and_items(thd, cond2, cond1); + cond1= and_items(thd, cond3, cond1); table->on_expr= and_items(thd, table->on_expr, cond1); } @@ -1079,7 +1083,9 @@ JOIN::prepare(TABLE_LIST *tables_init, select_lex != select_lex->master_unit()->global_parameters()) real_og_num+= select_lex->order_list.elements; - if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num)) + DBUG_ASSERT(select_lex->hidden_bit_fields == 0); + if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num, + &select_lex->hidden_bit_fields)) DBUG_RETURN(-1); if (select_lex->setup_ref_array(thd, real_og_num)) DBUG_RETURN(-1); @@ -1140,7 +1146,7 @@ JOIN::prepare(TABLE_LIST *tables_init, having->check_cols(1))); select_lex->having_fix_field= 0; - if (having_fix_rc || thd->is_error()) + if (unlikely(having_fix_rc || thd->is_error())) DBUG_RETURN(-1); /* purecov: inspected */ thd->lex->allow_sum_func= save_allow_sum_func; @@ -1285,7 +1291,7 @@ JOIN::prepare(TABLE_LIST *tables_init, } procedure= setup_procedure(thd, proc_param, result, fields_list, &error); - if (error) + if (unlikely(error)) goto err; /* purecov: inspected */ if (procedure) { @@ -1390,16 +1396,28 @@ bool JOIN::build_explain() { create_explain_query_if_not_exists(thd->lex, thd->mem_root); have_query_plan= QEP_AVAILABLE; - if (save_explain_data(thd->lex->explain, false /* can overwrite */, + + /* + explain data must be created on the Explain_query::mem_root. Because it's + just a memroot, not an arena, explain data must not contain any Items + */ + MEM_ROOT *old_mem_root= thd->mem_root; + Item *old_free_list __attribute__((unused))= thd->free_list; + thd->mem_root= thd->lex->explain->mem_root; + bool res= save_explain_data(thd->lex->explain, false /* can overwrite */, need_tmp, !skip_sort_order && !no_order && (order || group_list), - select_distinct)) + select_distinct); + thd->mem_root= old_mem_root; + DBUG_ASSERT(thd->free_list == old_free_list); // no Items were created + if (res) return 1; + uint select_nr= select_lex->select_number; JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt(); for (uint i= 0; i < aggr_tables; i++, curr_tab++) { - if (select_nr == INT_MAX) + if (select_nr == INT_MAX) { /* this is a fake_select_lex of a union */ select_nr= select_lex->master_unit()->first_select()->select_number; @@ -1553,9 +1571,6 @@ JOIN::optimize_inner() eval_select_list_used_tables(); - if (optimize_constant_subqueries()) - DBUG_RETURN(1); - table_count= select_lex->leaf_tables.elements; if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ @@ -1596,7 +1611,11 @@ JOIN::optimize_inner() /* The following code will allocate the new items in a permanent MEMROOT for prepared statements and stored procedures. + + But first we need to ensure that thd->lex->explain is allocated + in the execution arena */ + create_explain_query_if_not_exists(thd->lex, thd->mem_root); Query_arena *arena, backup; arena= thd->activate_stmt_arena_if_needed(&backup); @@ -1605,8 +1624,12 @@ JOIN::optimize_inner() /* Convert all outer joins to inner joins if possible */ conds= simplify_joins(this, join_list, conds, TRUE, FALSE); - if (select_lex->save_leaf_tables(thd)) + if (thd->is_error() || select_lex->save_leaf_tables(thd)) + { + if (arena) + thd->restore_active_arena(arena, &backup); DBUG_RETURN(1); + } build_bitmap_for_nested_joins(join_list, 0); sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; @@ -1617,6 +1640,9 @@ JOIN::optimize_inner() thd->restore_active_arena(arena, &backup); } + if (optimize_constant_subqueries()) + DBUG_RETURN(1); + List<Item> eq_list; if (setup_degenerate_jtbm_semi_joins(this, join_list, eq_list)) @@ -1724,7 +1750,8 @@ JOIN::optimize_inner() if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE)) DBUG_RETURN(1); } - if (thd->is_error()) + + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from optimize_cond")); @@ -1735,7 +1762,7 @@ JOIN::optimize_inner() having= optimize_cond(this, having, join_list, TRUE, &having_value, &having_equal); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from optimize_cond")); @@ -1877,7 +1904,7 @@ JOIN::optimize_inner() group_list= remove_const(this, group_list, conds, rollup.state == ROLLUP::STATE_NONE, &simple_group); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -1887,13 +1914,26 @@ JOIN::optimize_inner() /* Calculate how to do the join */ THD_STAGE_INFO(thd, stage_statistics); result->prepare_to_read_rows(); - if (make_join_statistics(this, select_lex->leaf_tables, &keyuse) || - thd->is_fatal_error) + if (unlikely(make_join_statistics(this, select_lex->leaf_tables, + &keyuse)) || + unlikely(thd->is_fatal_error)) { DBUG_PRINT("error",("Error: make_join_statistics() failed")); DBUG_RETURN(1); } + /* + If a splittable materialized derived/view dt_i is embedded into + into another splittable materialized derived/view dt_o then + splitting plans for dt_i and dt_o are evaluated independently. + First the optimizer looks for the best splitting plan sp_i for dt_i. + It happens when non-splitting plans for dt_o are evaluated. + The cost of sp_i is considered as the cost of materialization of dt_i + when evaluating any splitting plan for dt_o. + */ + if (fix_all_splittings_in_plan()) + DBUG_RETURN(1); + setup_subq_exit: with_two_phase_optimization= check_two_phase_optimization(thd); if (with_two_phase_optimization) @@ -1917,7 +1957,7 @@ int JOIN::optimize_stage2() if (subq_exit_fl) goto setup_subq_exit; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) DBUG_RETURN(1); /* Generate an execution plan from the found optimal join order. */ @@ -1993,7 +2033,7 @@ int JOIN::optimize_stage2() select= make_select(*table, const_table_map, const_table_map, conds, (SORT_INFO*) 0, 1, &error); - if (error) + if (unlikely(error)) { /* purecov: inspected */ error= -1; /* purecov: inspected */ DBUG_PRINT("error",("Error: make_select() failed")); @@ -2016,7 +2056,7 @@ int JOIN::optimize_stage2() { conds= substitute_for_best_equal_field(thd, NO_PARTICULAR_TAB, conds, cond_equal, map2table); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from substitute_for_best_equal")); @@ -2042,7 +2082,7 @@ int JOIN::optimize_stage2() *tab->on_expr_ref, tab->cond_equal, map2table); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_PRINT("error",("Error from substitute_for_best_equal")); @@ -2072,7 +2112,7 @@ int JOIN::optimize_stage2() { ref_item= substitute_for_best_equal_field(thd, tab, ref_item, equals, map2table); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(1); if (first_inner) @@ -2142,7 +2182,7 @@ int JOIN::optimize_stage2() { ORDER *org_order= order; order=remove_const(this, order,conds,1, &simple_order); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -2304,7 +2344,7 @@ int JOIN::optimize_stage2() group_list= remove_const(this, group_list, conds, rollup.state == ROLLUP::STATE_NONE, &simple_group); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -2325,7 +2365,7 @@ int JOIN::optimize_stage2() { group_list= procedure->group= remove_const(this, procedure->group, conds, 1, &simple_group); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; DBUG_RETURN(1); @@ -2552,7 +2592,7 @@ int JOIN::optimize_stage2() ordered_index_usage= ordered_index_order_by; } } - } + } if (having) having_is_correlated= MY_TEST(having->used_tables() & OUTER_REF_TABLE_BIT); @@ -2694,6 +2734,25 @@ bool JOIN::add_having_as_table_cond(JOIN_TAB *tab) } +bool JOIN::add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *table_fields) +{ + /* + this will not walk into semi-join materialization nests but this is ok + because we will never need to save current rowids for those. + */ + for (JOIN_TAB *tab=join_tab; tab < cur; tab++) + { + if (!tab->keep_current_rowid) + continue; + Item *item= new (thd->mem_root) Item_temptable_rowid(tab->table); + item->fix_fields(thd, 0); + table_fields->push_back(item, thd->mem_root); + cur->tmp_table_param->func_count++; + } + return 0; +} + + /** Set info for aggregation tables @@ -3000,13 +3059,13 @@ bool JOIN::make_aggr_tables_info() (select_distinct && tmp_table_param.using_outer_summary_function)) { /* Must copy to another table */ DBUG_PRINT("info",("Creating group table")); - + calc_group_buffer(this, group_list); count_field_types(select_lex, &tmp_table_param, tmp_all_fields1, select_distinct && !group_list); - tmp_table_param.hidden_field_count= + tmp_table_param.hidden_field_count= tmp_all_fields1.elements - tmp_fields_list1.elements; - + curr_tab++; aggr_tables++; bzero(curr_tab, sizeof(JOIN_TAB)); @@ -3021,12 +3080,11 @@ bool JOIN::make_aggr_tables_info() if (join_tab->is_using_loose_index_scan()) tmp_table_param.precomputed_group_by= TRUE; - tmp_table_param.hidden_field_count= + tmp_table_param.hidden_field_count= curr_all_fields->elements - curr_fields_list->elements; ORDER *dummy= NULL; //TODO can use table->group here also - if (create_postjoin_aggr_table(curr_tab, - curr_all_fields, dummy, true, + if (create_postjoin_aggr_table(curr_tab, curr_all_fields, dummy, true, distinct, keep_row_order)) DBUG_RETURN(true); @@ -3162,7 +3220,7 @@ bool JOIN::make_aggr_tables_info() !join_tab || !join_tab-> is_using_agg_loose_index_scan())) DBUG_RETURN(true); - if (setup_sum_funcs(thd, sum_funcs) || thd->is_fatal_error) + if (unlikely(setup_sum_funcs(thd, sum_funcs) || thd->is_fatal_error)) DBUG_RETURN(true); } if (group_list || order) @@ -3252,7 +3310,7 @@ bool JOIN::make_aggr_tables_info() - duplicate value removal Both of these operations are done after window function computation step. */ - curr_tab= join_tab + exec_join_tab_cnt() + aggr_tables - 1; + curr_tab= join_tab + total_join_tab_cnt(); if (select_lex->window_funcs.elements) { if (!(curr_tab->window_funcs_step= new Window_funcs_computation)) @@ -3297,11 +3355,13 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields, */ ha_rows table_rows_limit= ((order == NULL || skip_sort_order) && !table_group && - !select_lex->with_sum_func) ? - select_limit : HA_POS_ERROR; + !select_lex->with_sum_func) ? select_limit + : HA_POS_ERROR; if (!(tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param))) DBUG_RETURN(true); + if (tmp_table_keep_current_rowid) + add_fields_for_current_rowid(tab, table_fields); tab->tmp_table_param->skip_create_table= true; TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields, table_group, distinct, @@ -3696,7 +3756,7 @@ bool JOIN::prepare_result(List<Item> **columns_list) select_lex->handle_derived(thd->lex, DT_CREATE)) goto err; - if (result->prepare2()) + if (result->prepare2(this)) goto err; if ((select_lex->options & OPTION_SCHEMA_TABLE) && @@ -3723,7 +3783,7 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite, bool distinct) { /* - If there is SELECT in this statemet with the same number it must be the + If there is SELECT in this statement with the same number it must be the same SELECT */ DBUG_ASSERT(select_lex->select_number == UINT_MAX || @@ -3833,7 +3893,7 @@ void JOIN::exec_inner() } columns_list= &procedure_fields_list; } - if (result->prepare2()) + if (result->prepare2(this)) DBUG_VOID_RETURN; if (!tables_list && (table_count || !select_lex->with_sum_func) && @@ -3877,7 +3937,7 @@ void JOIN::exec_inner() } else send_records= 0; - if (!error) + if (likely(!error)) { join_free(); // Unlock all cursors error= (int) result->send_eof(); @@ -3903,7 +3963,7 @@ void JOIN::exec_inner() /* We've called exec_const_cond->val_int(). This may have caused an error. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= thd->is_error(); DBUG_VOID_RETURN; @@ -3948,7 +4008,7 @@ void JOIN::exec_inner() while ((cur_const_item= const_item_it++)) { cur_const_item->val_str(); // This caches val_str() to Item::str_value - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= thd->is_error(); DBUG_VOID_RETURN; @@ -3982,7 +4042,7 @@ void JOIN::exec_inner() join_examined_rows= 0; /* XXX: When can we have here thd->is_error() not zero? */ - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= thd->is_error(); DBUG_VOID_RETURN; @@ -4190,7 +4250,7 @@ mysql_select(THD *thd, join->having_history= (join->having?join->having:join->tmp_having); } - if (thd->is_error()) + if (unlikely(thd->is_error())) goto err; join->exec(); @@ -4224,17 +4284,20 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, int error; DBUG_ENTER("get_quick_record_count"); uchar buff[STACK_BUFF_ALLOC]; - if (check_stack_overrun(thd, STACK_MIN_SIZE, buff)) + if (unlikely(check_stack_overrun(thd, STACK_MIN_SIZE, buff))) DBUG_RETURN(0); // Fatal error flag is set if (select) { select->head=table; table->reginfo.impossible_range=0; - if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, - limit, 0, FALSE, - TRUE /* remove_where_parts*/)) == 1) + if (likely((error= + select->test_quick_select(thd, *(key_map *)keys, + (table_map) 0, + limit, 0, FALSE, + TRUE /* remove_where_parts*/)) == + 1)) DBUG_RETURN(select->quick->records); - if (error == -1) + if (unlikely(error == -1)) { table->reginfo.impossible_range=1; DBUG_RETURN(0); @@ -4341,7 +4404,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, DBUG_EXECUTE_IF("bug11747970_raise_error", { join->thd->set_killed(KILL_QUERY_HARD); }); - if (error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); goto error; @@ -8597,7 +8660,7 @@ best_extension_by_limited_search(JOIN *join, dbug_serve_apcs(thd, 1); ); - if (thd->check_killed()) // Abort + if (unlikely(thd->check_killed())) // Abort DBUG_RETURN(TRUE); DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx, @@ -9393,7 +9456,7 @@ bool JOIN::get_best_combination() */ uint aggr_tables= (group_list ? 1 : 0) + (select_distinct ? - (tmp_table_param. using_outer_summary_function ? 2 : 1) : 0) + + (tmp_table_param.using_outer_summary_function ? 2 : 1) : 0) + (order ? 1 : 0) + (select_options & (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT) ? 1 : 0) ; @@ -9412,9 +9475,6 @@ bool JOIN::get_best_combination() full_join=0; hash_join= FALSE; - if (fix_all_splittings_in_plan()) - DBUG_RETURN(TRUE); - fix_semijoin_strategies_for_picked_join_order(this); JOIN_TAB_RANGE *root_range; @@ -9857,7 +9917,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, keyinfo->key_part[i].length, keyuse->val, FALSE); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(TRUE); tmp.copy(); j->ref.const_ref_part_map |= key_part_map(1) << i ; @@ -11335,9 +11395,9 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) DBUG_RETURN(NESTED_LOOP_OK); } fill_record(thd, table, table->field, sjm->sjm_table_cols, TRUE, FALSE); - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if ((error= table->file->ha_write_tmp_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) { /* create_myisam_from_heap will generate error if needed */ if (table->file->is_fatal_error(error, HA_CHECK_DUP) && @@ -13145,7 +13205,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, if (prev_ptr == &first_order) // Nothing to sort/group *simple_order=1; #ifndef DBUG_OFF - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) DBUG_PRINT("error",("Error from remove_const")); #endif DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order)); @@ -13251,7 +13311,7 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables, bool send_error= FALSE; if (send_row) send_error= result->send_data(fields) > 0; - if (!send_error) + if (likely(!send_error)) result->send_eof(); // Should be safe } DBUG_RETURN(0); @@ -16906,6 +16966,10 @@ setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps) temporary table @param table_alias possible name of the temporary table that can be used for name resolving; can be "". + @param do_not_open only create the TABLE object, do not + open the table in the engine + @param keep_row_order rows need to be read in the order they were + inserted, the engine should preserve this order */ TABLE * @@ -17216,9 +17280,10 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, */ item->marker == 4 || param->bit_fields_as_long, force_copy_fields); - if (!new_field) + + if (unlikely(!new_field)) { - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) goto err; // Got OOM continue; // Some kind of const item } @@ -17730,7 +17795,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, } } - if (thd->is_fatal_error) // If end of memory + if (unlikely(thd->is_fatal_error)) // If end of memory goto err; /* purecov: inspected */ share->db_record_offset= 1; table->used_for_duplicate_elimination= (param->sum_func_count == 0 && @@ -17934,9 +17999,10 @@ bool Virtual_tmp_table::sp_set_all_fields_from_item(THD *thd, Item *value) bool open_tmp_table(TABLE *table) { int error; - if ((error= table->file->ha_open(table, table->s->table_name.str, O_RDWR, - HA_OPEN_TMP_TABLE | - HA_OPEN_INTERNAL_TABLE))) + if (unlikely((error= table->file->ha_open(table, table->s->table_name.str, + O_RDWR, + HA_OPEN_TMP_TABLE | + HA_OPEN_INTERNAL_TABLE)))) { table->file->print_error(error, MYF(0)); /* purecov: inspected */ table->db_stat= 0; @@ -18130,14 +18196,14 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, } } - if ((error= maria_create(share->table_name.str, - file_type, - share->keys, &keydef, - (uint) (*recinfo-start_recinfo), - start_recinfo, - share->uniques, &uniquedef, - &create_info, - create_flags))) + if (unlikely((error= maria_create(share->table_name.str, + file_type, + share->keys, &keydef, + (uint) (*recinfo-start_recinfo), + start_recinfo, + share->uniques, &uniquedef, + &create_info, + create_flags)))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -18285,15 +18351,17 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, bzero((char*) &create_info,sizeof(create_info)); create_info.data_file_length= table->in_use->variables.tmp_disk_table_size; - if ((error=mi_create(share->table_name.str, share->keys, &keydef, - (uint) (*recinfo-start_recinfo), - start_recinfo, - share->uniques, &uniquedef, - &create_info, - HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE | - ((share->db_create_options & HA_OPTION_PACK_RECORD) ? - HA_PACK_RECORD : 0) - ))) + if (unlikely((error= mi_create(share->table_name.str, share->keys, &keydef, + (uint) (*recinfo-start_recinfo), + start_recinfo, + share->uniques, &uniquedef, + &create_info, + HA_CREATE_TMP_TABLE | + HA_CREATE_INTERNAL_TABLE | + ((share->db_create_options & + HA_OPTION_PACK_RECORD) ? + HA_PACK_RECORD : 0) + )))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; @@ -18347,11 +18415,11 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, share= *table->s; new_table.s= &share; new_table.s->db_plugin= ha_lock_engine(thd, TMP_ENGINE_HTON); - if (!(new_table.file= get_new_handler(&share, &new_table.mem_root, - new_table.s->db_type()))) + if (unlikely(!(new_table.file= get_new_handler(&share, &new_table.mem_root, + new_table.s->db_type())))) DBUG_RETURN(1); // End of memory - if (new_table.file->set_ha_share_ref(&share.ha_share)) + if (unlikely(new_table.file->set_ha_share_ref(&share.ha_share))) { delete new_table.file; DBUG_RETURN(1); @@ -18394,16 +18462,13 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table, DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;); if (write_err) goto err; - if (thd->check_killed()) - { - thd->send_kill_message(); + if (unlikely(thd->check_killed())) goto err_killed; - } } if (!new_table.no_rows && new_table.file->ha_end_bulk_insert()) goto err; /* copy row that filled HEAP table */ - if ((write_err=new_table.file->ha_write_tmp_row(table->record[0]))) + if (unlikely((write_err=new_table.file->ha_write_tmp_row(table->record[0])))) { if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || !ignore_last_dupp_key_error) @@ -18692,7 +18757,7 @@ do_select(JOIN *join, Procedure *procedure) (the join condition and piece of where clause relevant to this join table). */ - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) error= NESTED_LOOP_ERROR; } else @@ -18710,13 +18775,14 @@ do_select(JOIN *join, Procedure *procedure) error= NESTED_LOOP_NO_MORE_ROWS; else error= join->first_select(join,join_tab,0); - if (error >= NESTED_LOOP_OK && join->thd->killed != ABORT_QUERY) + if (error >= NESTED_LOOP_OK && likely(join->thd->killed != ABORT_QUERY)) error= join->first_select(join,join_tab,1); } join->thd->limit_found_rows= join->send_records - join->duplicate_rows; - if (error == NESTED_LOOP_NO_MORE_ROWS || join->thd->killed == ABORT_QUERY) + if (error == NESTED_LOOP_NO_MORE_ROWS || + unlikely(join->thd->killed == ABORT_QUERY)) error= NESTED_LOOP_OK; /* @@ -18763,7 +18829,7 @@ do_select(JOIN *join, Procedure *procedure) Sic: this branch works even if rc != 0, e.g. when send_data above returns an error. */ - if (join->result->send_eof()) + if (unlikely(join->result->send_eof())) rc= 1; // Don't send error DBUG_PRINT("info",("%ld records output", (long) join->send_records)); } @@ -18783,7 +18849,7 @@ do_select(JOIN *join, Procedure *procedure) int rr_sequential_and_unpack(READ_RECORD *info) { int error; - if ((error= rr_sequential(info))) + if (unlikely((error= rr_sequential(info)))) return error; for (Copy_field *cp= info->copy_field; cp != info->copy_field_end; cp++) @@ -18954,10 +19020,9 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) rc= sub_select(join, join_tab, end_of_records); DBUG_RETURN(rc); } - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { /* The user has aborted the execution of the query */ - join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); } if (!test_if_use_dynamic_range_scan(join_tab)) @@ -19190,10 +19255,10 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) error= info->read_record(); - if (skip_over && !error) + if (skip_over && likely(!error)) { - if(!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, - join_tab->loosescan_buf, join_tab->loosescan_key_len)) + if (!key_cmp(join_tab->table->key_info[join_tab->loosescan_key].key_part, + join_tab->loosescan_buf, join_tab->loosescan_key_len)) { /* This is the LooseScan action: skip over records with the same key @@ -19205,7 +19270,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records) skip_over= FALSE; } - if (join_tab->keep_current_rowid && !error) + if (join_tab->keep_current_rowid && likely(!error)) join_tab->table->file->position(join_tab->table->record[0]); rc= evaluate_join_record(join, join_tab, error); @@ -19250,13 +19315,13 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, " cond: %p error: %d alias %s", join, join_tab, select_cond, error, join_tab->table->alias.ptr())); - if (error > 0 || (join->thd->is_error())) // Fatal error + + if (error > 0 || unlikely(join->thd->is_error())) // Fatal error DBUG_RETURN(NESTED_LOOP_ERROR); if (error < 0) DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS); - if (join->thd->check_killed()) // Aborted by user + if (unlikely(join->thd->check_killed())) // Aborted by user { - join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ } @@ -19267,7 +19332,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, select_cond_result= MY_TEST(select_cond->val_int()); /* check for errors evaluating the condition */ - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); } @@ -19397,7 +19462,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, join->return_tab= return_tab; /* check for errors evaluating the condition */ - if (join->thd->is_error()) + if (unlikely(join->thd->is_error())) DBUG_RETURN(NESTED_LOOP_ERROR); if (join->return_tab < join_tab) @@ -19546,10 +19611,11 @@ int safe_index_read(JOIN_TAB *tab) { int error; TABLE *table= tab->table; - if ((error= table->file->ha_index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_KEY_EXACT))) + if (unlikely((error= + table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_KEY_EXACT)))) return report_error(table, error); return 0; } @@ -19597,7 +19663,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) } else if (tab->type == JT_SYSTEM) { - if ((error=join_read_system(tab))) + if (unlikely((error=join_read_system(tab)))) { // Info for DESCRIBE tab->info= ET_CONST_ROW_NOT_FOUND; /* Mark for EXPLAIN that the row was not found */ @@ -19623,7 +19689,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) } error=join_read_const(tab); table->file->ha_end_keyread(); - if (error) + if (unlikely(error)) { tab->info= ET_UNIQUE_ROW_NOT_FOUND; /* Mark for EXPLAIN that the row was not found */ @@ -19701,8 +19767,9 @@ join_read_system(JOIN_TAB *tab) int error; if (table->status & STATUS_GARBAGE) // If first read { - if ((error= table->file->ha_read_first_row(table->record[0], - table->s->primary_key))) + if (unlikely((error= + table->file->ha_read_first_row(table->record[0], + table->s->primary_key)))) { if (error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -19747,7 +19814,7 @@ join_read_const(JOIN_TAB *tab) make_prev_keypart_map(tab->ref.key_parts), HA_READ_KEY_EXACT); } - if (error) + if (unlikely(error)) { table->status= STATUS_NOT_FOUND; mark_as_null_row(tab->table); @@ -19803,7 +19870,7 @@ int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref) if (!table->file->inited) { error= table->file->ha_index_init(table_ref->key, tab ? tab->sorted : TRUE); - if (error) + if (unlikely(error)) { (void) report_error(table, error); return 1; @@ -19843,10 +19910,11 @@ int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref) table_ref->key_buff, make_prev_keypart_map(table_ref->key_parts), HA_READ_KEY_EXACT); - if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + if (unlikely(error) && + error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); - if (! error) + if (likely(!error)) { table_ref->has_record= TRUE; table_ref->use_count= 1; @@ -19907,16 +19975,19 @@ join_read_always_key(JOIN_TAB *tab) /* Initialize the index first */ if (!table->file->inited) { - if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + if (unlikely((error= table->file->ha_index_init(tab->ref.key, + tab->sorted)))) { (void) report_error(table, error); return 1; } } - if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) + if (unlikely(cp_buffer_from_ref(tab->join->thd, table, &tab->ref))) return -1; - if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts)))) + if (unlikely((error= + table->file->prepare_index_key_scan_map(tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts))))) { report_error(table,error); return -1; @@ -19946,23 +20017,26 @@ join_read_last_key(JOIN_TAB *tab) TABLE *table= tab->table; if (!table->file->inited && - (error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + unlikely((error= table->file->ha_index_init(tab->ref.key, tab->sorted)))) { (void) report_error(table, error); return 1; } - if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) + if (unlikely(cp_buffer_from_ref(tab->join->thd, table, &tab->ref))) return -1; - if ((error= table->file->prepare_index_key_scan_map(tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts)))) + if (unlikely((error= + table->file->prepare_index_key_scan_map(tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts)))) ) { report_error(table,error); return -1; } - if ((error= table->file->ha_index_read_map(table->record[0], - tab->ref.key_buff, - make_prev_keypart_map(tab->ref.key_parts), - HA_READ_PREFIX_LAST))) + if (unlikely((error= + table->file->ha_index_read_map(table->record[0], + tab->ref.key_buff, + make_prev_keypart_map(tab->ref.key_parts), + HA_READ_PREFIX_LAST)))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -19987,9 +20061,9 @@ join_read_next_same(READ_RECORD *info) TABLE *table= info->table; JOIN_TAB *tab=table->reginfo.join_tab; - if ((error= table->file->ha_index_next_same(table->record[0], - tab->ref.key_buff, - tab->ref.key_length))) + if (unlikely((error= table->file->ha_index_next_same(table->record[0], + tab->ref.key_buff, + tab->ref.key_length)))) { if (error != HA_ERR_END_OF_FILE) return report_error(table, error); @@ -20007,7 +20081,7 @@ join_read_prev_same(READ_RECORD *info) TABLE *table= info->table; JOIN_TAB *tab=table->reginfo.join_tab; - if ((error= table->file->ha_index_prev(table->record[0]))) + if (unlikely((error= table->file->ha_index_prev(table->record[0])))) return report_error(table, error); if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key, tab->ref.key_length)) @@ -20030,7 +20104,7 @@ join_init_quick_read_record(JOIN_TAB *tab) int read_first_record_seq(JOIN_TAB *tab) { - if (tab->read_record.table->file->ha_rnd_init_with_error(1)) + if (unlikely(tab->read_record.table->file->ha_rnd_init_with_error(1))) return 1; return tab->read_record.read_record(); } @@ -20153,9 +20227,10 @@ join_read_first(JOIN_TAB *tab) tab->read_record.record=table->record[0]; if (!table->file->inited) error= table->file->ha_index_init(tab->index, tab->sorted); - if (!error) + if (likely(!error)) error= table->file->prepare_index_scan(); - if (error || (error=tab->table->file->ha_index_first(tab->table->record[0]))) + if (unlikely(error) || + unlikely(error= tab->table->file->ha_index_first(tab->table->record[0]))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) report_error(table, error); @@ -20169,7 +20244,7 @@ static int join_read_next(READ_RECORD *info) { int error; - if ((error= info->table->file->ha_index_next(info->record))) + if (unlikely((error= info->table->file->ha_index_next(info->record)))) return report_error(info->table, error); return 0; @@ -20193,9 +20268,10 @@ join_read_last(JOIN_TAB *tab) tab->read_record.record=table->record[0]; if (!table->file->inited) error= table->file->ha_index_init(tab->index, 1); - if (!error) + if (likely(!error)) error= table->file->prepare_index_scan(); - if (error || (error= tab->table->file->ha_index_last(tab->table->record[0]))) + if (unlikely(error) || + unlikely(error= tab->table->file->ha_index_last(tab->table->record[0]))) DBUG_RETURN(report_error(table, error)); DBUG_RETURN(0); @@ -20206,7 +20282,7 @@ static int join_read_prev(READ_RECORD *info) { int error; - if ((error= info->table->file->ha_index_prev(info->record))) + if (unlikely((error= info->table->file->ha_index_prev(info->record)))) return report_error(info->table, error); return 0; } @@ -20227,7 +20303,7 @@ join_ft_read_first(JOIN_TAB *tab) table->file->ft_init(); - if ((error= table->file->ha_ft_read(table->record[0]))) + if (unlikely((error= table->file->ha_ft_read(table->record[0])))) return report_error(table, error); return 0; } @@ -20236,7 +20312,7 @@ static int join_ft_read_next(READ_RECORD *info) { int error; - if ((error= info->table->file->ha_ft_read(info->table->record[0]))) + if (unlikely((error= info->table->file->ha_ft_read(info->table->record[0])))) return report_error(info->table, error); return 0; } @@ -20266,7 +20342,7 @@ int join_read_next_same_or_null(READ_RECORD *info) { int error; - if ((error= join_read_next_same(info)) >= 0) + if (unlikely((error= join_read_next_same(info)) >= 0)) return error; JOIN_TAB *tab= info->table->reginfo.join_tab; @@ -20338,7 +20414,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { int error; /* result < 0 if row was not accepted and should not be counted */ - if ((error= join->result->send_data(*fields))) + if (unlikely((error= join->result->send_data(*fields)))) { if (error > 0) DBUG_RETURN(NESTED_LOOP_ERROR); @@ -20487,7 +20563,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->do_send_rows) { error=join->result->send_data(*fields); - if (error < 0) + if (unlikely(error < 0)) { /* Duplicate row, don't count */ join->duplicate_rows++; @@ -20497,13 +20573,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), join->send_records++; join->group_sent= true; } - if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && error <= 0)) { if (join->rollup_send_data((uint) (idx+1))) error= 1; } } - if (error > 0) + if (unlikely(error > 0)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if (end_of_records) DBUG_RETURN(NESTED_LOOP_OK); @@ -20573,14 +20649,14 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if (!join_tab->having || join_tab->having->val_int()) + if (likely(!join_tab->having || join_tab->having->val_int())) { int error; join->found_records++; if ((error= table->file->ha_write_tmp_row(table->record[0]))) { - if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) - goto end; + if (likely(!table->file->is_fatal_error(error, HA_CHECK_DUP))) + goto end; // Ignore duplicate keys bool is_duplicate; if (create_internal_tmp_table_from_heap(join->thd, table, join_tab->tmp_table_param->start_recinfo, @@ -20603,9 +20679,8 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } } end: - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { - join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ } DBUG_RETURN(NESTED_LOOP_OK); @@ -20662,8 +20737,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { /* Update old record */ restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error= table->file->ha_update_tmp_row(table->record[1], - table->record[0]))) + if (unlikely((error= table->file->ha_update_tmp_row(table->record[1], + table->record[0])))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ @@ -20672,9 +20747,10 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } init_tmptable_sum_functions(join->sum_funcs); - if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) + if (unlikely(copy_funcs(join_tab->tmp_table_param->items_to_copy, + join->thd))) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if ((error= table->file->ha_write_tmp_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) { if (create_internal_tmp_table_from_heap(join->thd, table, join_tab->tmp_table_param->start_recinfo, @@ -20682,7 +20758,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error /* Change method to update rows */ - if ((error= table->file->ha_index_init(0, 0))) + if (unlikely((error= table->file->ha_index_init(0, 0)))) { table->file->print_error(error, MYF(0)); DBUG_RETURN(NESTED_LOOP_ERROR); @@ -20692,9 +20768,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } join_tab->send_records++; end: - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { - join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ } DBUG_RETURN(NESTED_LOOP_OK); @@ -20719,32 +20794,31 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if (!(error= table->file->ha_write_tmp_row(table->record[0]))) + if (likely(!(error= table->file->ha_write_tmp_row(table->record[0])))) join_tab->send_records++; // New group else { - if ((int) table->file->get_dup_key(error) < 0) + if (unlikely((int) table->file->get_dup_key(error) < 0)) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } - if (table->file->ha_rnd_pos(table->record[1],table->file->dup_ref)) + if (unlikely(table->file->ha_rnd_pos(table->record[1],table->file->dup_ref))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } restore_record(table,record[1]); update_tmptable_sum_func(join->sum_funcs,table); - if ((error= table->file->ha_update_tmp_row(table->record[1], - table->record[0]))) + if (unlikely((error= table->file->ha_update_tmp_row(table->record[1], + table->record[0])))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ } } - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { - join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ } DBUG_RETURN(NESTED_LOOP_OK); @@ -20790,17 +20864,18 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (!join_tab->having || join_tab->having->val_int()) { int error= table->file->ha_write_tmp_row(table->record[0]); - if (error && + if (unlikely(error) && create_internal_tmp_table_from_heap(join->thd, table, join_tab->tmp_table_param->start_recinfo, &join_tab->tmp_table_param->recinfo, error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); } - if (join->rollup.state != ROLLUP::STATE_NONE) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE)) { - if (join->rollup_write_data((uint) (idx+1), - join_tab->tmp_table_param, table)) + if (unlikely(join->rollup_write_data((uint) (idx+1), + join_tab->tmp_table_param, + table))) { DBUG_RETURN(NESTED_LOOP_ERROR); } @@ -20819,23 +20894,24 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (idx < (int) join->send_group_parts) { copy_fields(join_tab->tmp_table_param); - if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) + if (unlikely(copy_funcs(join_tab->tmp_table_param->items_to_copy, + join->thd))) DBUG_RETURN(NESTED_LOOP_ERROR); - if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) + if (unlikely(init_sum_functions(join->sum_funcs, + join->sum_funcs_end[idx+1]))) DBUG_RETURN(NESTED_LOOP_ERROR); - if (join->procedure) + if (unlikely(join->procedure)) join->procedure->add(); goto end; } } - if (update_sum_func(join->sum_funcs)) + if (unlikely(update_sum_func(join->sum_funcs))) DBUG_RETURN(NESTED_LOOP_ERROR); - if (join->procedure) + if (unlikely(join->procedure)) join->procedure->add(); end: - if (join->thd->check_killed()) + if (unlikely(join->thd->check_killed())) { - join->thd->send_kill_message(); DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ } DBUG_RETURN(NESTED_LOOP_OK); @@ -22283,7 +22359,8 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort) { DBUG_ASSERT(tab->type == JT_REF || tab->type == JT_EQ_REF); // Update ref value - if ((cp_buffer_from_ref(thd, table, &tab->ref) && thd->is_fatal_error)) + if (unlikely(cp_buffer_from_ref(thd, table, &tab->ref) && + thd->is_fatal_error)) goto err; // out of memory } } @@ -22291,7 +22368,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort) /* Fill schema tables with data before filesort if it's necessary */ if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && - get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX)) + unlikely(get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))) goto err; if (table->s->tmp_table) @@ -22459,37 +22536,31 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, int error; DBUG_ENTER("remove_dup_with_compare"); - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) DBUG_RETURN(1); error= file->ha_rnd_next(record); for (;;) { - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); error=0; goto err; } - if (error) + if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - { - error= file->ha_rnd_next(record); - continue; - } if (error == HA_ERR_END_OF_FILE) break; goto err; } if (having && !having->val_int()) { - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; error= file->ha_rnd_next(record); continue; } - if (copy_blobs(first_field)) + if (unlikely(copy_blobs(first_field))) { my_message(ER_OUTOFMEMORY, ER_THD(thd,ER_OUTOFMEMORY), MYF(ME_FATALERROR)); @@ -22502,30 +22573,28 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, bool found=0; for (;;) { - if ((error= file->ha_rnd_next(record))) + if (unlikely((error= file->ha_rnd_next(record)))) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) break; goto err; } if (compare_record(table, first_field) == 0) { - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; } else if (!found) { found=1; - if ((error= file->remember_rnd_pos())) + if (unlikely((error= file->remember_rnd_pos()))) goto err; } } if (!found) break; // End of file /* Restart search on saved row */ - if ((error= file->restart_rnd_next(record))) + if (unlikely((error= file->restart_rnd_next(record)))) goto err; } @@ -22561,49 +22630,47 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, Field **ptr; DBUG_ENTER("remove_dup_with_hash_index"); - if (!my_multi_malloc(MYF(MY_WME), - &key_buffer, - (uint) ((key_length + extra_length) * - (long) file->stats.records), - &field_lengths, - (uint) (field_count*sizeof(*field_lengths)), - NullS)) + if (unlikely(!my_multi_malloc(MYF(MY_WME), + &key_buffer, + (uint) ((key_length + extra_length) * + (long) file->stats.records), + &field_lengths, + (uint) (field_count*sizeof(*field_lengths)), + NullS))) DBUG_RETURN(1); for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++) (*field_length++)= (*ptr)->sort_length(); - if (my_hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0, - key_length, (my_hash_get_key) 0, 0, 0)) + if (unlikely(my_hash_init(&hash, &my_charset_bin, + (uint) file->stats.records, 0, + key_length, (my_hash_get_key) 0, 0, 0))) { my_free(key_buffer); DBUG_RETURN(1); } - if ((error= file->ha_rnd_init(1))) + if (unlikely((error= file->ha_rnd_init(1)))) goto err; key_pos=key_buffer; for (;;) { uchar *org_key_pos; - if (thd->check_killed()) + if (unlikely(thd->check_killed())) { - thd->send_kill_message(); error=0; goto err; } - if ((error= file->ha_rnd_next(record))) + if (unlikely((error= file->ha_rnd_next(record)))) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) break; goto err; } if (having && !having->val_int()) { - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; continue; } @@ -22620,7 +22687,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, if (my_hash_search(&hash, org_key_pos, key_length)) { /* Duplicated found ; Remove the row */ - if ((error= file->ha_delete_row(record))) + if (unlikely((error= file->ha_delete_row(record)))) goto err; } else @@ -22641,7 +22708,7 @@ err: my_hash_free(&hash); file->extra(HA_EXTRA_NO_CACHE); (void) file->ha_rnd_end(); - if (error) + if (unlikely(error)) file->print_error(error,MYF(0)); DBUG_RETURN(1); } @@ -23337,13 +23404,10 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables, calc how big buffer we need for comparing group entries. */ -static void -calc_group_buffer(JOIN *join,ORDER *group) +void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group) { uint key_length=0, parts=0, null_parts=0; - if (group) - join->group= 1; for (; group ; group=group->next) { Item *group_item= *group->item; @@ -23413,9 +23477,16 @@ calc_group_buffer(JOIN *join,ORDER *group) if (group_item->maybe_null) null_parts++; } - join->tmp_table_param.group_length=key_length+null_parts; - join->tmp_table_param.group_parts=parts; - join->tmp_table_param.group_null_parts=null_parts; + param->group_length= key_length + null_parts; + param->group_parts= parts; + param->group_null_parts= null_parts; +} + +static void calc_group_buffer(JOIN *join, ORDER *group) +{ + if (group) + join->group= 1; + calc_group_buffer(&join->tmp_table_param, group); } @@ -24132,7 +24203,7 @@ copy_funcs(Item **func_ptr, const THD *thd) TODO: change it for a real status check when Item::val_xxx() are extended to return status code. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) return TRUE; } return FALSE; @@ -24166,7 +24237,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) value), thd->mem_root); } - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(TRUE); if (!cond->fixed) { @@ -24658,7 +24729,8 @@ int JOIN::rollup_write_data(uint idx, TMP_TABLE_PARAM *tmp_table_param_arg, TABL item->save_in_result_field(1); } copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]); - if ((write_error= table_arg->file->ha_write_tmp_row(table_arg->record[0]))) + if (unlikely((write_error= + table_arg->file->ha_write_tmp_row(table_arg->record[0])))) { if (create_internal_tmp_table_from_heap(thd, table_arg, tmp_table_param_arg->start_recinfo, @@ -24756,7 +24828,7 @@ int print_explain_message_line(select_result_sink *result, else item_list.push_back(item_null, mem_root); - if (thd->is_fatal_error || result->send_data(item_list)) + if (unlikely(thd->is_fatal_error) || unlikely(result->send_data(item_list))) return 1; return 0; } @@ -24827,9 +24899,9 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, if (filesort) { if (!(eta->pre_join_sort= - new Explain_aggr_filesort(thd->mem_root, - thd->lex->analyze_stmt, - filesort))) + new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, + thd->lex->analyze_stmt, + filesort))) return 1; } @@ -25267,7 +25339,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) { // Each aggregate means a temp.table prev_node= node; - if (!(node= new Explain_aggr_tmp_table)) + if (!(node= new (thd->mem_root) Explain_aggr_tmp_table)) return 1; node->child= prev_node; @@ -25288,7 +25360,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) if (join_tab->distinct) { prev_node= node; - if (!(node= new Explain_aggr_remove_dups)) + if (!(node= new (thd->mem_root) Explain_aggr_remove_dups)) return 1; node->child= prev_node; } @@ -25296,7 +25368,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) if (join_tab->filesort) { Explain_aggr_filesort *eaf = - new Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort); + new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort); if (!eaf) return 1; prev_node= node; @@ -25590,7 +25662,8 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) unit->fake_select_lex->type= unit_operation_text[unit->common_op()]; unit->fake_select_lex->options|= SELECT_DESCRIBE; } - if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE))) + if (!(res= unit->prepare(unit->derived, result, + SELECT_NO_UNLOCK | SELECT_DESCRIBE))) res= unit->exec(); } else @@ -26156,7 +26229,7 @@ bool JOIN::change_result(select_result *new_result, select_result *old_result) { result= new_result; if (result->prepare(fields_list, select_lex->master_unit()) || - result->prepare2()) + result->prepare2(this)) DBUG_RETURN(true); /* purecov: inspected */ DBUG_RETURN(false); } @@ -26987,22 +27060,20 @@ ulong check_selectivity(THD *thd, } it.rewind(); - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) DBUG_RETURN(0); do { error= file->ha_rnd_next(record); - if (thd->killed) + if (unlikely(thd->killed)) { thd->send_kill_message(); count= 0; goto err; } - if (error) + if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - continue; if (error == HA_ERR_END_OF_FILE) break; goto err; @@ -27154,11 +27225,11 @@ AGGR_OP::end_send() else error= join_tab->read_record.read_record(); - if (error > 0 || (join->thd->is_error())) // Fatal error + if (unlikely(error > 0 || (join->thd->is_error()))) // Fatal error rc= NESTED_LOOP_ERROR; else if (error < 0) break; - else if (join->thd->killed) // Aborted by user + else if (unlikely(join->thd->killed)) // Aborted by user { join->thd->send_kill_message(); rc= NESTED_LOOP_KILLED; diff --git a/sql/sql_select.h b/sql/sql_select.h index 95b2d34c631..4140a0293f8 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -470,7 +470,7 @@ typedef struct st_join_table { Window_funcs_computation* window_funcs_step; /** - List of topmost expressions in the select list. The *next* JOIN TAB + List of topmost expressions in the select list. The *next* JOIN_TAB in the plan should use it to obtain correct values. Same applicable to all_fields. These lists are needed because after tmp tables functions will be turned to fields. These variables are pointing to @@ -1438,6 +1438,9 @@ public: enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE, QEP_DELETED} have_query_plan; + // if keep_current_rowid=true, whether they should be saved in temporary table + bool tmp_table_keep_current_rowid; + /* Additional WHERE and HAVING predicates to be considered for IN=>EXISTS subquery transformation of a JOIN object. @@ -1548,6 +1551,7 @@ public: pushdown_query= 0; original_join_tab= 0; explain= NULL; + tmp_table_keep_current_rowid= 0; all_fields= fields_arg; if (&fields_list != &fields_arg) /* Avoid valgrind-warning */ @@ -1577,6 +1581,15 @@ public: /* Number of tables actually joined at the top level */ uint exec_join_tab_cnt() { return tables_list ? top_join_tab_count : 0; } + /* + Number of tables in the join which also includes the temporary tables + created for GROUP BY, DISTINCT , WINDOW FUNCTION etc. + */ + uint total_join_tab_cnt() + { + return exec_join_tab_cnt() + aggr_tables - 1; + } + int prepare(TABLE_LIST *tables, uint wind_num, COND *conds, uint og_num, ORDER *order, bool skip_order_by, ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select, @@ -1774,6 +1787,7 @@ private: void cleanup_item_list(List<Item> &items) const; bool add_having_as_table_cond(JOIN_TAB *tab); bool make_aggr_tables_info(); + bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields); }; enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS}; @@ -2370,6 +2384,7 @@ int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table, #define RATIO_TO_PACK_ROWS 2 #define MIN_STRING_LENGTH_TO_PACK_ROWS 10 +void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group); TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ORDER *group, bool distinct, bool save_sum_fields, ulonglong select_options, ha_rows rows_limit, diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index 18f0028908f..21a8781087f 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -341,7 +341,7 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *org_table_list) MYSQL_OPEN_HAS_MDL_LOCK); thd->open_options&= ~HA_OPEN_FOR_CREATE; thd->m_reprepare_observer= save_reprepare_observer; - if (error) + if (unlikely(error)) { lex->restore_backup_query_tables_list(&query_tables_list_backup); thd->restore_backup_open_tables_state(&open_tables_backup); @@ -459,7 +459,10 @@ int SEQUENCE::read_initial_values(TABLE *table) mdl_requests.push_front(&mdl_request); if (thd->mdl_context.acquire_locks(&mdl_requests, thd->variables.lock_wait_timeout)) + { + write_unlock(table); DBUG_RETURN(HA_ERR_LOCK_WAIT_TIMEOUT); + } } save_lock_type= table->reginfo.lock_type; table->reginfo.lock_type= TL_READ; @@ -468,10 +471,11 @@ int SEQUENCE::read_initial_values(TABLE *table) { if (mdl_lock_used) thd->mdl_context.release_lock(mdl_request.ticket); + write_unlock(table); DBUG_RETURN(HA_ERR_LOCK_WAIT_TIMEOUT); } DBUG_ASSERT(table->reginfo.lock_type == TL_READ); - if (!(error= read_stored_values(table))) + if (likely(!(error= read_stored_values(table)))) initialized= SEQ_READY_TO_USE; mysql_unlock_tables(thd, lock); if (mdl_lock_used) @@ -510,7 +514,7 @@ int SEQUENCE::read_stored_values(TABLE *table) error= table->file->ha_read_first_row(table->record[0], MAX_KEY); tmp_restore_column_map(table->read_set, save_read_set); - if (error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); DBUG_RETURN(error); @@ -560,8 +564,7 @@ void sequence_definition::adjust_values(longlong next_value) else { next_free_value+= to_add; - DBUG_ASSERT(next_free_value % real_increment == offset && - next_free_value >= reserved_until); + DBUG_ASSERT(next_free_value % real_increment == offset); } } } @@ -592,7 +595,7 @@ int sequence_definition::write_initial_sequence(TABLE *table) table->s->sequence->initialized= SEQUENCE::SEQ_UNINTIALIZED; reenable_binlog(thd); table->write_set= save_write_set; - if (error) + if (unlikely(error)) table->file->print_error(error, MYF(0)); else { @@ -634,7 +637,7 @@ int sequence_definition::write(TABLE *table, bool all_fields) table->read_set= table->write_set= &table->s->all_set; table->file->column_bitmaps_signal(); store_fields(table); - if ((error= table->file->ha_write_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_row(table->record[0])))) table->file->print_error(error, MYF(0)); table->rpl_write_set= save_rpl_write_set; table->read_set= save_read_set; @@ -741,7 +744,7 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error) DBUG_RETURN(next_value(table, 1, error)); } - if ((*error= write(table, 0))) + if (unlikely((*error= write(table, 0)))) { reserved_until= org_reserved_until; next_free_value= res_value; @@ -893,7 +896,7 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) trapped_errors= no_such_table_handler.safely_trapped_errors(); thd->pop_internal_handler(); } - if (error) + if (unlikely(error)) { if (trapped_errors) { @@ -949,7 +952,7 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) } table->s->sequence->write_lock(table); - if (!(error= new_seq->write(table, 1))) + if (likely(!(error= new_seq->write(table, 1)))) { /* Store the sequence values in table share */ table->s->sequence->copy(new_seq); @@ -961,9 +964,9 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) error= 1; if (trans_commit_implicit(thd)) error= 1; - if (!error) + if (likely(!error)) error= write_bin_log(thd, 1, thd->query(), thd->query_length()); - if (!error) + if (likely(!error)) my_ok(thd); end: diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 353d1f551a5..da2a91e5880 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -256,7 +256,8 @@ bool servers_reload(THD *thd) tables[0].init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_SERVERS_NAME, 0, TL_READ); - if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) + if (unlikely(open_and_lock_tables(thd, tables, FALSE, + MYSQL_LOCK_IGNORE_TIMEOUT))) { /* Execution might have been interrupted; only print the error message @@ -395,11 +396,11 @@ insert_server(THD *thd, FOREIGN_SERVER *server) goto end; /* insert the server into the table */ - if ((error= insert_server_record(table, server))) + if (unlikely(error= insert_server_record(table, server))) goto end; /* insert the server into the cache */ - if ((error= insert_server_record_into_cache(server))) + if (unlikely((error= insert_server_record_into_cache(server)))) goto end; end: @@ -542,10 +543,12 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server) system_charset_info); /* read index until record is that specified in server_name */ - if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if (unlikely((error= + table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]-> + ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)))) { /* if not found, err */ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) @@ -559,12 +562,8 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server) DBUG_PRINT("info",("record for server '%s' not found!", server->server_name)); /* write/insert the new server */ - if ((error=table->file->ha_write_row(table->record[0]))) - { + if (unlikely(error=table->file->ha_write_row(table->record[0]))) table->file->print_error(error, MYF(0)); - } - else - error= 0; } else error= ER_FOREIGN_SERVER_EXISTS; @@ -608,10 +607,11 @@ static int drop_server_internal(THD *thd, LEX_SERVER_OPTIONS *server_options) tables.init_one_table(&MYSQL_SCHEMA_NAME, &MYSQL_SERVERS_NAME, 0, TL_WRITE); /* hit the memory hit first */ - if ((error= delete_server_record_in_cache(server_options))) + if (unlikely((error= delete_server_record_in_cache(server_options)))) goto end; - if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) + if (unlikely(!(table= open_ltable(thd, &tables, TL_WRITE, + MYSQL_LOCK_IGNORE_TIMEOUT)))) { error= my_errno; goto end; @@ -744,7 +744,7 @@ int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered) goto end; } - if ((error= update_server_record(table, altered))) + if (unlikely((error= update_server_record(table, altered)))) goto end; error= update_server_record_in_cache(existing, altered); @@ -892,10 +892,12 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server) server->server_name_length, system_charset_info); - if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - ~(longlong)0, - HA_READ_KEY_EXACT))) + if (unlikely((error= + table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]-> + ptr, + ~(longlong)0, + HA_READ_KEY_EXACT)))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) table->file->print_error(error, MYF(0)); @@ -907,9 +909,9 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server) /* ok, so we can update since the record exists in the table */ store_record(table,record[1]); store_server_fields(table, server); - if ((error=table->file->ha_update_row(table->record[1], - table->record[0])) && - error != HA_ERR_RECORD_IS_THE_SAME) + if (unlikely((error=table->file->ha_update_row(table->record[1], + table->record[0])) && + error != HA_ERR_RECORD_IS_THE_SAME)) { DBUG_PRINT("info",("problems with ha_update_row %d", error)); goto end; @@ -950,10 +952,12 @@ delete_server_record(TABLE *table, LEX_CSTRING *name) /* set the field that's the PK to the value we're looking for */ table->field[0]->store(name->str, name->length, system_charset_info); - if ((error= table->file->ha_index_read_idx_map(table->record[0], 0, - (uchar *)table->field[0]->ptr, - HA_WHOLE_KEY, - HA_READ_KEY_EXACT))) + if (unlikely((error= + table->file->ha_index_read_idx_map(table->record[0], 0, + (uchar *)table->field[0]-> + ptr, + HA_WHOLE_KEY, + HA_READ_KEY_EXACT)))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) table->file->print_error(error, MYF(0)); @@ -962,7 +966,7 @@ delete_server_record(TABLE *table, LEX_CSTRING *name) } else { - if ((error= table->file->ha_delete_row(table->record[0]))) + if (unlikely((error= table->file->ha_delete_row(table->record[0])))) table->file->print_error(error, MYF(0)); } @@ -1001,7 +1005,7 @@ int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options) { if (thd->lex->create_info.or_replace()) { - if ((error= drop_server_internal(thd, server_options))) + if (unlikely((error= drop_server_internal(thd, server_options)))) goto end; } else if (thd->lex->create_info.if_not_exists()) @@ -1032,7 +1036,7 @@ int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options) end: mysql_rwlock_unlock(&THR_LOCK_servers); - if (error) + if (unlikely(error)) { DBUG_PRINT("info", ("problem creating server <%s>", server_options->server_name.str)); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 38a13c49278..f8702657be7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1076,13 +1076,7 @@ find_files(THD *thd, Dynamic_array<LEX_CSTRING*> *files, LEX_CSTRING *db, if (ha_discover_table_names(thd, db, dirp, &tl, false)) goto err; } -#if MYSQL_VERSION_ID < 100300 - /* incomplete optimization, but a less drastic change in GA version */ - if (!thd->lex->select_lex.order_list.elements && - !thd->lex->select_lex.group_list.elements) -#else if (is_show_command(thd)) -#endif tl.sort(); #ifndef DBUG_OFF else @@ -1267,7 +1261,7 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL) || mysql_handle_derived(thd->lex, DT_INIT | DT_PREPARE); thd->pop_internal_handler(); - if (open_error && (thd->killed || thd->is_error())) + if (unlikely(open_error && (thd->killed || thd->is_error()))) goto exit; } @@ -3821,17 +3815,19 @@ bool schema_table_store_record(THD *thd, TABLE *table) { int error; - if (thd->killed) + if (unlikely(thd->killed)) { thd->send_kill_message(); return 1; } - if ((error= table->file->ha_write_tmp_row(table->record[0]))) + if (unlikely((error= table->file->ha_write_tmp_row(table->record[0])))) { TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param; - if (create_internal_tmp_table_from_heap(thd, table, param->start_recinfo, - ¶m->recinfo, error, 0, NULL)) + if (unlikely(create_internal_tmp_table_from_heap(thd, table, + param->start_recinfo, + ¶m->recinfo, error, 0, + NULL))) return 1; } @@ -4596,7 +4592,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, else { char buf[NAME_CHAR_LEN + 1]; - if (thd->is_error()) + if (unlikely(thd->is_error())) get_table_engine_for_i_s(thd, buf, table_list, &db_name, &table_name); result= schema_table->process_table(thd, table_list, @@ -4678,13 +4674,14 @@ static int fill_schema_table_names(THD *thd, TABLE_LIST *tables, else table->field[3]->store(STRING_WITH_LEN("ERROR"), cs); - if (thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE) + if (unlikely(thd->is_error() && + thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE)) { thd->clear_error(); return 0; } } - if (schema_table_store_record(thd, table)) + if (unlikely(schema_table_store_record(thd, table))) return 1; return 0; } @@ -5010,7 +5007,7 @@ public: if (*level != Sql_condition::WARN_LEVEL_ERROR) return false; - if (!thd->get_stmt_da()->is_error()) + if (likely(!thd->get_stmt_da()->is_error())) thd->get_stmt_da()->set_error_status(sql_errno, msg, sqlstate, *cond_hdl); return true; // handled! } @@ -5135,9 +5132,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) Dynamic_array<LEX_CSTRING*> table_names; int res= make_table_name_list(thd, &table_names, lex, &plan->lookup_field_vals, db_name); - if (res == 2) /* Not fatal error, continue */ + if (unlikely(res == 2)) /* Not fatal error, continue */ continue; - if (res) + if (unlikely(res)) goto err; for (size_t i=0; i < table_names.elements(); i++) @@ -5496,13 +5493,13 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, /* Collect table info from the storage engine */ - if(file) + if (file) { /* If info() fails, then there's nothing else to do */ - if ((info_error= file->info(HA_STATUS_VARIABLE | - HA_STATUS_TIME | - HA_STATUS_VARIABLE_EXTRA | - HA_STATUS_AUTO)) != 0) + if (unlikely((info_error= file->info(HA_STATUS_VARIABLE | + HA_STATUS_TIME | + HA_STATUS_VARIABLE_EXTRA | + HA_STATUS_AUTO)) != 0)) { file->print_error(info_error, MYF(0)); goto err; @@ -5601,7 +5598,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables, } err: - if (res || info_error) + if (unlikely(res || info_error)) { /* If an error was encountered, push a warning, set the TABLE COMMENT @@ -5635,8 +5632,6 @@ err: static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, uint offset) { - bool is_blob; - int decimals, field_length; const char *tmp_buff; char column_type_buff[MAX_FIELD_WIDTH]; String column_type(column_type_buff, sizeof(column_type_buff), cs); @@ -5662,22 +5657,18 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, (tmp_buff ? (uint)(tmp_buff - column_type.ptr()) : column_type.length()), cs); - is_blob= (field->type() == MYSQL_TYPE_BLOB); - if (field->has_charset() || is_blob || - field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type - field->real_type() == MYSQL_TYPE_STRING) // For binary type - { - uint32 octet_max_length= field->max_display_length(); - if (is_blob && octet_max_length != (uint32) UINT_MAX32) - octet_max_length /= field->charset()->mbmaxlen; - longlong char_max_len= is_blob ? - (longlong) octet_max_length / field->charset()->mbminlen : - (longlong) octet_max_length / field->charset()->mbmaxlen; + Information_schema_character_attributes cattr= + field->information_schema_character_attributes(); + if (cattr.has_char_length()) + { /* CHARACTER_MAXIMUM_LENGTH column*/ - table->field[offset + 1]->store(char_max_len, TRUE); + table->field[offset + 1]->store((longlong) cattr.char_length(), true); table->field[offset + 1]->set_notnull(); + } + if (cattr.has_octet_length()) + { /* CHARACTER_OCTET_LENGTH column */ - table->field[offset + 2]->store((longlong) octet_max_length, TRUE); + table->field[offset + 2]->store((longlong) cattr.octet_length(), true); table->field[offset + 2]->set_notnull(); } @@ -5686,35 +5677,10 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, They are set to -1 if they should not be set (we should return NULL) */ - field_length= -1; - decimals= field->decimals(); + Information_schema_numeric_attributes num= + field->information_schema_numeric_attributes(); + switch (field->type()) { - case MYSQL_TYPE_NEWDECIMAL: - field_length= ((Field_new_decimal*) field)->precision; - break; - case MYSQL_TYPE_DECIMAL: - field_length= field->field_length - (decimals ? 2 : 1); - break; - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_INT24: - field_length= field->max_display_length() - 1; - break; - case MYSQL_TYPE_LONGLONG: - field_length= field->max_display_length() - - ((field->flags & UNSIGNED_FLAG) ? 0 : 1); - break; - case MYSQL_TYPE_BIT: - field_length= field->max_display_length(); - decimals= -1; // return NULL - break; - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - field_length= field->field_length; - if (decimals == NOT_FIXED_DEC) - decimals= -1; // return NULL - break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: @@ -5727,15 +5693,15 @@ static void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs, } /* NUMERIC_PRECISION column */ - if (field_length >= 0) + if (num.has_precision()) { - table->field[offset + 3]->store((longlong) field_length, TRUE); + table->field[offset + 3]->store((longlong) num.precision(), true); table->field[offset + 3]->set_notnull(); /* NUMERIC_SCALE column */ - if (decimals >= 0) + if (num.has_scale()) { - table->field[offset + 4]->store((longlong) decimals, TRUE); + table->field[offset + 4]->store((longlong) num.scale(), true); table->field[offset + 4]->set_notnull(); } } @@ -6564,7 +6530,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS rather than in SHOW KEYS */ - if (thd->is_error()) + if (unlikely(thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -6792,7 +6758,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, if (schema_table_store_record(thd, table)) DBUG_RETURN(1); - if (res && thd->is_error()) + if (unlikely(res && thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -6828,7 +6794,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, DBUG_ENTER("get_schema_constraints_record"); if (res) { - if (thd->is_error()) + if (unlikely(thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -6962,7 +6928,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, */ if (res) { - if (thd->is_error()) + if (unlikely(thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -7026,7 +6992,7 @@ static int get_schema_key_column_usage_record(THD *thd, DBUG_ENTER("get_schema_key_column_usage_record"); if (res) { - if (thd->is_error()) + if (unlikely(thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -7313,7 +7279,7 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, if (res) { - if (thd->is_error()) + if (unlikely(thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -7725,8 +7691,9 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; OPEN_TABLE_LIST *open_list; - if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db.str, wild)) - && thd->is_fatal_error) + if (unlikely(!(open_list= list_open_tables(thd, thd->lex->select_lex.db.str, + wild))) && + unlikely(thd->is_fatal_error)) DBUG_RETURN(1); for (; open_list ; open_list=open_list->next) @@ -7736,7 +7703,7 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) table->field[1]->store(open_list->table, strlen(open_list->table), cs); table->field[2]->store((longlong) open_list->in_use, TRUE); table->field[3]->store((longlong) open_list->locked, TRUE); - if (schema_table_store_record(thd, table)) + if (unlikely(schema_table_store_record(thd, table))) DBUG_RETURN(1); } DBUG_RETURN(0); @@ -7865,7 +7832,7 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, if (res) { - if (thd->is_error()) + if (unlikely(thd->is_error())) push_warning(thd, Sql_condition::WARN_LEVEL_WARN, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); @@ -8811,7 +8778,7 @@ bool get_schema_tables_result(JOIN *join, } } thd->pop_internal_handler(); - if (thd->is_error()) + if (unlikely(thd->is_error())) { /* This hack is here, because I_S code uses thd->clear_error() a lot. @@ -10310,14 +10277,14 @@ static void get_cs_converted_string_value(THD *thd, try_val.copy(input_str->ptr(), input_str->length(), cs, thd->variables.character_set_client, &try_conv_error); - if (!try_conv_error) + if (likely(!try_conv_error)) { String val; uint conv_error= 0; val.copy(input_str->ptr(), input_str->length(), cs, system_charset_info, &conv_error); - if (!conv_error) + if (likely(!conv_error)) { append_unescaped(output_str, val.ptr(), val.length()); return; diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc index e1d9dcad57b..7a28ba65ba2 100644 --- a/sql/sql_signal.cc +++ b/sql/sql_signal.cc @@ -319,7 +319,7 @@ int Sql_cmd_common_signal::eval_signal_informations(THD *thd, Sql_condition *con The various item->val_xxx() methods don't return an error code, but flag thd in case of failure. */ - if (! thd->is_error()) + if (likely(!thd->is_error())) result= 0; end: diff --git a/sql/sql_sort.h b/sql/sql_sort.h index d57239671a8..c29bf1440c9 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -100,12 +100,12 @@ public: int merge_many_buff(Sort_param *param, uchar *sort_buffer, BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file); -uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, - uint sort_length); -int merge_buffers(Sort_param *param,IO_CACHE *from_file, - IO_CACHE *to_file, uchar *sort_buffer, - BUFFPEK *lastbuff,BUFFPEK *Fb, - BUFFPEK *Tb,int flag); +ulong read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, + uint sort_length); +bool merge_buffers(Sort_param *param,IO_CACHE *from_file, + IO_CACHE *to_file, uchar *sort_buffer, + BUFFPEK *lastbuff,BUFFPEK *Fb, + BUFFPEK *Tb,int flag); int merge_index(Sort_param *param, uchar *sort_buffer, BUFFPEK *buffpek, uint maxbuffer, IO_CACHE *tempfile, IO_CACHE *outfile); diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index e62a49f71ea..4edcb779379 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1517,7 +1517,8 @@ public: ~Stat_table_write_iter() { - cleanup(); + /* Ensure that cleanup has been run */ + DBUG_ASSERT(rowid_buf == 0); } }; @@ -1799,6 +1800,7 @@ private: public: bool is_single_comp_pk; + bool is_partial_fields_present; Index_prefix_calc(THD *thd, TABLE *table, KEY *key_info) : index_table(table), index_info(key_info) @@ -1810,7 +1812,7 @@ public: prefixes= 0; LINT_INIT_STRUCT(calc_state); - is_single_comp_pk= FALSE; + is_partial_fields_present= is_single_comp_pk= FALSE; uint pk= table->s->primary_key; if ((uint) (table->key_info - key_info) == pk && table->key_info[pk].user_defined_key_parts == 1) @@ -1832,7 +1834,10 @@ public: calculating the values of 'avg_frequency' for prefixes. */ if (!key_info->key_part[i].field->part_of_key.is_set(keyno)) + { + is_partial_fields_present= TRUE; break; + } if (!(state->last_prefix= new (thd->mem_root) Cached_item_field(thd, @@ -2617,7 +2622,7 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index) DBUG_ENTER("collect_statistics_for_index"); /* No statistics for FULLTEXT indexes. */ - if (key_info->flags & HA_FULLTEXT) + if (key_info->flags & (HA_FULLTEXT|HA_SPATIAL)) DBUG_RETURN(rc); Index_prefix_calc index_prefix_calc(thd, table, key_info); @@ -2631,7 +2636,13 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index) DBUG_RETURN(rc); } - table->file->ha_start_keyread(index); + /* + Request "only index read" in case of absence of fields which are + partially in the index to avoid problems with partitioning (for example) + which want to get whole field value. + */ + if (!index_prefix_calc.is_partial_fields_present) + table->file->ha_start_keyread(index); table->file->ha_index_init(index, TRUE); rc= table->file->ha_index_first(table->record[0]); while (rc != HA_ERR_END_OF_FILE) @@ -2743,11 +2754,7 @@ int collect_statistics_for_table(THD *thd, TABLE *table) break; if (rc) - { - if (rc == HA_ERR_RECORD_DELETED) - continue; break; - } for (field_ptr= table->field; *field_ptr; field_ptr++) { @@ -3990,11 +3997,11 @@ bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table) { DBUG_ASSERT(db->str && table->str); - if (!cmp(db, &MYSQL_SCHEMA_NAME)) + if (!my_strcasecmp(table_alias_charset, db->str, MYSQL_SCHEMA_NAME.str)) { for (uint i= 0; i < STATISTICS_TABLES; i ++) { - if (cmp(table, &stat_table_name[i]) == 0) + if (!my_strcasecmp(table_alias_charset, table->str, stat_table_name[i].str)) return true; } } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 390abe36b6c..5d5cc90431b 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -240,8 +240,17 @@ bool String::copy(const char *str,size_t arg_length, CHARSET_INFO *cs) { if (alloc(arg_length)) return TRUE; - DBUG_ASSERT(arg_length <= UINT_MAX32); - if ((str_length=(uint32)arg_length)) + DBUG_ASSERT(arg_length < UINT_MAX32); + if (Ptr == str && arg_length == uint32(str_length)) + { + /* + This can happen in some cases. This code is here mainly to avoid + warnings from valgrind, but can also be an indication of error. + */ + DBUG_PRINT("warning", ("Copying string on itself: %p %zu", + str, arg_length)); + } + else if ((str_length=uint32(arg_length))) memcpy(Ptr,str,arg_length); Ptr[arg_length]=0; str_charset=cs; @@ -667,8 +676,8 @@ int String::strstr(const String &s,uint32 offset) if (!s.length()) return ((int) offset); // Empty string is always found - register const char *str = Ptr+offset; - register const char *search=s.ptr(); + const char *str = Ptr+offset; + const char *search=s.ptr(); const char *end=Ptr+str_length-s.length()+1; const char *search_end=s.ptr()+s.length(); skip: @@ -676,7 +685,7 @@ skip: { if (*str++ == *search) { - register char *i,*j; + char *i,*j; i=(char*) str; j=(char*) search+1; while (j != search_end) if (*i++ != *j++) goto skip; @@ -697,8 +706,8 @@ int String::strrstr(const String &s,uint32 offset) { if (!s.length()) return offset; // Empty string is always found - register const char *str = Ptr+offset-1; - register const char *search=s.ptr()+s.length()-1; + const char *str = Ptr+offset-1; + const char *search=s.ptr()+s.length()-1; const char *end=Ptr+s.length()-2; const char *search_end=s.ptr()-1; @@ -707,7 +716,7 @@ skip: { if (*str-- == *search) { - register char *i,*j; + char *i,*j; i=(char*) str; j=(char*) search-1; while (j != search_end) if (*i-- != *j--) goto skip; diff --git a/sql/sql_string.h b/sql/sql_string.h index 37531429f8d..d110e10647a 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -190,7 +190,7 @@ public: { /* never called */ } static void operator delete[](void *ptr, size_t size) { TRASH_FREE(ptr, size); } - static void operator delete[](void *ptr, MEM_ROOT *mem_root) + static void operator delete[](void *, MEM_ROOT *) { /* never called */ } ~String() { free(); } @@ -402,9 +402,10 @@ public: if (ALIGN_SIZE(arg_length+1) < Alloced_length) { char *new_ptr; - if (!(new_ptr=(char*) - my_realloc(Ptr, arg_length,MYF((thread_specific ? - MY_THREAD_SPECIFIC : 0))))) + if (unlikely(!(new_ptr=(char*) + my_realloc(Ptr, + arg_length,MYF((thread_specific ? + MY_THREAD_SPECIFIC : 0)))))) { Alloced_length = 0; real_alloc(arg_length); @@ -455,7 +456,7 @@ public: CHARSET_INFO *fromcs, const char *src, size_t src_length, size_t nchars, String_copier *copier) { - if (alloc(tocs->mbmaxlen * src_length)) + if (unlikely(alloc(tocs->mbmaxlen * src_length))) return true; str_length= copier->well_formed_copy(tocs, Ptr, Alloced_length, fromcs, src, (uint)src_length, (uint)nchars); @@ -511,7 +512,7 @@ public: } else { - if (realloc_with_extra(str_length + 1)) + if (unlikely(realloc_with_extra(str_length + 1))) return 1; Ptr[str_length++]=chr; } @@ -521,8 +522,8 @@ public: { for (const char *src_end= src + srclen ; src != src_end ; src++) { - if (append(_dig_vec_lower[((uchar) *src) >> 4]) || - append(_dig_vec_lower[((uchar) *src) & 0x0F])) + if (unlikely(append(_dig_vec_lower[((uchar) *src) >> 4])) || + unlikely(append(_dig_vec_lower[((uchar) *src) & 0x0F]))) return true; } return false; @@ -628,7 +629,7 @@ public: { char *buff= Ptr + str_length; char *end= ll2str(i, buff, radix, 0); - str_length+= (int) (end-buff); + str_length+= uint32(end-buff); } /* Inline (general) functions used by the protocol functions */ @@ -638,7 +639,7 @@ public: uint32 new_length= arg_length + str_length; if (new_length > Alloced_length) { - if (realloc(new_length + step_alloc)) + if (unlikely(realloc(new_length + step_alloc))) return 0; } uint32 old_length= str_length; @@ -650,7 +651,8 @@ public: inline bool append(const char *s, uint32 arg_length, uint32 step_alloc) { uint32 new_length= arg_length + str_length; - if (new_length > Alloced_length && realloc(new_length + step_alloc)) + if (new_length > Alloced_length && + unlikely(realloc(new_length + step_alloc))) return TRUE; memcpy(Ptr+str_length, s, arg_length); str_length+= arg_length; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 448d095c876..6835d92773c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, MariaDB Corporation. + Copyright (c) 2010, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,8 +29,7 @@ #include "lock.h" // mysql_unlock_tables #include "strfunc.h" // find_type2, find_set #include "sql_truncate.h" // regenerate_locked_table -#include "sql_partition.h" // mem_alloc_error, - // generate_partition_syntax, +#include "sql_partition.h" // generate_partition_syntax, // partition_info // NOT_A_PARTITION_ID #include "sql_db.h" // load_db_opt_by_name @@ -115,7 +114,7 @@ static char* add_identifier(THD* thd, char *to_p, const char * end_p, res= strconvert(&my_charset_filename, conv_name, name_len, system_charset_info, conv_string, FN_REFLEN, &errors); - if (!res || errors) + if (unlikely(!res || errors)) { DBUG_PRINT("error", ("strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors)); conv_name= name; @@ -128,7 +127,9 @@ static char* add_identifier(THD* thd, char *to_p, const char * end_p, conv_name_end= conv_string + res; } - quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '`'; + quote= (likely(thd) ? + get_quote_char_for_identifier(thd, conv_name, res - 1) : + '`'); if (quote != EOF && (end_p - to_p > 2)) { @@ -390,7 +391,7 @@ uint filename_to_tablename(const char *from, char *to, size_t to_length, res= strconvert(&my_charset_filename, from, FN_REFLEN, system_charset_info, to, to_length, &errors); - if (errors) // Old 5.0 name + if (unlikely(errors)) // Old 5.0 name { res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) - to); @@ -1144,11 +1145,8 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) } hton= plugin_data(plugin, handlerton*); file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton); - if (!file) - { - mem_alloc_error(sizeof(handler)); + if (unlikely(!file)) goto error; - } } switch (ddl_log_entry->action_type) { @@ -1160,7 +1158,8 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) if (frm_action) { strxmov(to_path, ddl_log_entry->name, reg_ext, NullS); - if ((error= mysql_file_delete(key_file_frm, to_path, MYF(MY_WME)))) + if (unlikely((error= mysql_file_delete(key_file_frm, to_path, + MYF(MY_WME))))) { if (my_errno != ENOENT) break; @@ -1172,7 +1171,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) } else { - if ((error= file->ha_delete_table(ddl_log_entry->name))) + if (unlikely((error= file->ha_delete_table(ddl_log_entry->name)))) { if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE) break; @@ -1425,19 +1424,19 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, + (2*FN_REFLEN)], (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (3*FN_REFLEN)])); - if (write_ddl_log_file_entry((*active_entry)->entry_pos)) + if (unlikely(write_ddl_log_file_entry((*active_entry)->entry_pos))) { error= TRUE; sql_print_error("Failed to write entry_no = %u", (*active_entry)->entry_pos); } - if (write_header && !error) + if (write_header && likely(!error)) { (void) sync_ddl_log_no_lock(); if (write_ddl_log_header()) error= TRUE; } - if (error) + if (unlikely(error)) release_ddl_log_memory_entry(*active_entry); DBUG_RETURN(error); } @@ -1868,8 +1867,10 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) lpt->create_info->tmp_table(), frm.str, frm.length); my_free(const_cast<uchar*>(frm.str)); - if (error || lpt->table->file->ha_create_partitioning_metadata(shadow_path, - NULL, CHF_CREATE_FLAG)) + if (unlikely(error) || + unlikely(lpt->table->file-> + ha_create_partitioning_metadata(shadow_path, + NULL, CHF_CREATE_FLAG))) { mysql_file_delete(key_file_frm, shadow_frm_name, MYF(0)); error= 1; @@ -2127,7 +2128,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists, false, drop_sequence, false, false); thd->pop_internal_handler(); - if (error) + if (unlikely(error)) DBUG_RETURN(TRUE); my_ok(thd); DBUG_RETURN(FALSE); @@ -2524,26 +2525,26 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, */ (void) mysql_file_delete(key_file_frm, path, MYF(0)); } - else if (mysql_file_delete(key_file_frm, path, - MYF(MY_WME))) + else if (unlikely(mysql_file_delete(key_file_frm, path, + MYF(MY_WME)))) { frm_delete_error= my_errno; DBUG_ASSERT(frm_delete_error); } } - if (!error) + if (likely(!error)) { int trigger_drop_error= 0; - if (!frm_delete_error) + if (likely(!frm_delete_error)) { non_tmp_table_deleted= TRUE; trigger_drop_error= Table_triggers_list::drop_all_triggers(thd, &db, &table->table_name); } - if (trigger_drop_error || + if (unlikely(trigger_drop_error) || (frm_delete_error && frm_delete_error != ENOENT)) error= 1; else if (frm_delete_error && if_exists) @@ -3190,8 +3191,10 @@ bool Column_definition::prepare_stage1_string(THD *thd, Convert the default value from client character set into the column character set if necessary. We can only do this for constants as we have not yet run fix_fields. + But not for blobs, as they will be stored as SQL expressions, not + written down into the record image. */ - if (default_value && + if (!(flags & BLOB_FLAG) && default_value && default_value->expr->basic_const_item() && charset != default_value->expr->collation.collation) { @@ -4487,12 +4490,10 @@ handler *mysql_create_frm_image(THD *thd, db_options= create_info->table_options_with_row_type(); - if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, - create_info->db_type))) - { - mem_alloc_error(sizeof(handler)); + if (unlikely(!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, + create_info->db_type)))) DBUG_RETURN(NULL); - } + #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info= thd->work_part_info; @@ -4505,11 +4506,9 @@ handler *mysql_create_frm_image(THD *thd, object with the default settings. */ thd->work_part_info= part_info= new partition_info(); - if (!part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!part_info)) goto err; - } + file->set_auto_partitions(part_info); part_info->default_engine_type= create_info->db_type; part_info->is_auto_partitioned= TRUE; @@ -4680,12 +4679,9 @@ handler *mysql_create_frm_image(THD *thd, engines in partition clauses. */ delete file; - if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, - engine_type))) - { - mem_alloc_error(sizeof(handler)); + if (unlikely(!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, + engine_type)))) DBUG_RETURN(NULL); - } } } /* @@ -4767,7 +4763,7 @@ err: @retval 0 OK @retval 1 error - @retval -1 table existed but IF EXISTS was used + @retval -1 table existed but IF NOT EXISTS was used */ static @@ -4809,10 +4805,14 @@ int create_table_impl(THD *thd, create_info->data_file_name= create_info->index_file_name= 0; } else - if (error_if_data_home_dir(create_info->data_file_name, "DATA DIRECTORY") || - error_if_data_home_dir(create_info->index_file_name, "INDEX DIRECTORY")|| - check_partition_dirs(thd->lex->part_info)) - goto err; + { + if (unlikely(error_if_data_home_dir(create_info->data_file_name, + "DATA DIRECTORY")) || + unlikely(error_if_data_home_dir(create_info->index_file_name, + "INDEX DIRECTORY")) || + unlikely(check_partition_dirs(thd->lex->part_info))) + goto err; + } alias= const_cast<LEX_CSTRING*>(table_case_name(create_info, table_name)); @@ -5044,6 +5044,12 @@ warn: /** Simple wrapper around create_table_impl() to be used in various version of CREATE TABLE statement. + + @result + 1 unspefied error + 2 error; Don't log create statement + 0 ok + -1 Table was used with IF NOT EXISTS and table existed (warning, not error) */ int mysql_create_table_no_lock(THD *thd, @@ -5090,6 +5096,24 @@ int mysql_create_table_no_lock(THD *thd, else table_list->table= 0; res= sequence_insert(thd, thd->lex, table_list); + if (res) + { + DBUG_ASSERT(thd->is_error()); + /* Drop the table as it wasn't completely done */ + if (!mysql_rm_table_no_locks(thd, table_list, 1, + create_info->tmp_table(), + false, true /* Sequence*/, + true /* Don't log_query */, + true /* Don't free locks */ )) + { + /* + From the user point of view, the table creation failed + We return 2 to indicate that this statement doesn't have + to be logged. + */ + res= 2; + } + } } return res; @@ -5173,7 +5197,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, This should always work as we have a meta lock on the table. */ thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables); - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) { thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); result= 1; @@ -5195,9 +5219,10 @@ err: thd->transaction.stmt.mark_created_temp_table(); /* Write log if no error or if we already deleted a table */ - if (!result || thd->log_current_statement) + if (likely(!result) || thd->log_current_statement) { - if (result && create_info->table_was_deleted && pos_in_locked_tables) + if (unlikely(result) && create_info->table_was_deleted && + pos_in_locked_tables) { /* Possible locked table was dropped. We should remove meta data locks @@ -5205,7 +5230,7 @@ err: */ thd->locked_tables_list.unlock_locked_table(thd, mdl_ticket); } - else if (!result && create_info->tmp_table() && create_info->table) + else if (likely(!result) && create_info->tmp_table() && create_info->table) { /* Remember that tmp table creation was logged so that we know if @@ -5213,8 +5238,8 @@ err: */ create_info->table->s->table_creation_was_logged= 1; } - if (write_bin_log(thd, result ? FALSE : TRUE, thd->query(), - thd->query_length(), is_trans)) + if (unlikely(write_bin_log(thd, result ? FALSE : TRUE, thd->query(), + thd->query_length(), is_trans))) result= 1; } DBUG_RETURN(result); @@ -5439,9 +5464,9 @@ mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db, error= my_errno; (void) file->ha_create_partitioning_metadata(to, from, CHF_RENAME_FLAG); } - else if (!file || !(error=file->ha_rename_table(from_base, to_base))) + else if (!file || likely(!(error=file->ha_rename_table(from_base, to_base)))) { - if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext)) + if (!(flags & NO_FRM_RENAME) && unlikely(rename_file_ext(from,to,reg_ext))) { error=my_errno; if (file) @@ -5454,10 +5479,14 @@ mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db, } } delete file; - if (error == HA_ERR_WRONG_COMMAND) - my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); - else if (error) - my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); + + if (unlikely(error)) + { + if (error == HA_ERR_WRONG_COMMAND) + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE"); + else + my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); + } else if (!(flags & FN_IS_TMP)) mysql_audit_rename_table(thd, old_db, old_name, new_db, new_name); @@ -5502,7 +5531,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *pos_in_locked_tables= 0; Alter_info local_alter_info; Alter_table_ctx local_alter_ctx; // Not used - bool res= TRUE; + int res= 1; bool is_trans= FALSE; bool do_logging= FALSE; uint not_used; @@ -5625,7 +5654,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, This should always work as we have a meta lock on the table. */ thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables); - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) { thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); res= 1; // We got an error @@ -5807,12 +5836,15 @@ err: */ log_drop_table(thd, &table->db, &table->table_name, create_info->tmp_table()); } - else if (write_bin_log(thd, res ? FALSE : TRUE, thd->query(), - thd->query_length(), is_trans)) + else if (res != 2) // Table was not dropped + { + if (write_bin_log(thd, res ? FALSE : TRUE, thd->query(), + thd->query_length(), is_trans)) res= 1; + } } - DBUG_RETURN(res); + DBUG_RETURN(res != 0); } @@ -5859,7 +5891,7 @@ int mysql_discard_or_import_tablespace(THD *thd, THD_STAGE_INFO(thd, stage_end); - if (error) + if (unlikely(error)) goto err; /* @@ -5870,15 +5902,15 @@ int mysql_discard_or_import_tablespace(THD *thd, /* The ALTER TABLE is always in its own transaction */ error= trans_commit_stmt(thd); - if (trans_commit_implicit(thd)) + if (unlikely(trans_commit_implicit(thd))) error=1; - if (!error) + if (likely(!error)) error= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); err: thd->tablespace_op=FALSE; - if (error == 0) + if (likely(error == 0)) { my_ok(thd); DBUG_RETURN(0); @@ -6007,7 +6039,7 @@ drop_create_field: break; } } - if (*f_ptr == NULL) + if (unlikely(*f_ptr == NULL)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_BAD_FIELD_ERROR, @@ -6043,7 +6075,7 @@ drop_create_field: acol->name, (*f_ptr)->field_name.str) == 0) break; } - if (*f_ptr == NULL) + if (unlikely(*f_ptr == NULL)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_BAD_FIELD_ERROR, @@ -6063,10 +6095,28 @@ drop_create_field: List_iterator<Alter_drop> drop_it(alter_info->drop_list); Alter_drop *drop; bool remove_drop; + ulonglong left_flags= 0; while ((drop= drop_it++)) { + ulonglong cur_flag= 0; + switch (drop->type) { + case Alter_drop::COLUMN: + cur_flag= ALTER_PARSER_DROP_COLUMN; + break; + case Alter_drop::FOREIGN_KEY: + cur_flag= ALTER_DROP_FOREIGN_KEY; + break; + case Alter_drop::KEY: + cur_flag= ALTER_DROP_INDEX; + break; + default: + break; + } if (!drop->drop_if_exists) + { + left_flags|= cur_flag; continue; + } remove_drop= TRUE; if (drop->type == Alter_drop::COLUMN) { @@ -6158,12 +6208,15 @@ drop_create_field: ER_THD(thd, ER_CANT_DROP_FIELD_OR_KEY), drop->type_name(), drop->name); drop_it.remove(); - if (alter_info->drop_list.is_empty()) - alter_info->flags&= ~(ALTER_PARSER_DROP_COLUMN | - ALTER_DROP_INDEX | - ALTER_DROP_FOREIGN_KEY); } + else + left_flags|= cur_flag; } + /* Reset state to what's left in drop list */ + alter_info->flags&= ~(ALTER_PARSER_DROP_COLUMN | + ALTER_DROP_INDEX | + ALTER_DROP_FOREIGN_KEY); + alter_info->flags|= left_flags; } /* ALTER TABLE ADD KEY IF NOT EXISTS */ @@ -6277,8 +6330,9 @@ remove_key: } } } - + #ifdef WITH_PARTITION_STORAGE_ENGINE + DBUG_ASSERT(thd->work_part_info == 0); partition_info *tab_part_info= table->part_info; thd->work_part_info= thd->lex->part_info; if (tab_part_info) @@ -7216,18 +7270,20 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); } - if (error == HA_ERR_WRONG_COMMAND) + if (unlikely(error)) { - THD *thd= table->in_use; - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_ILLEGAL_HA, ER_THD(thd, ER_ILLEGAL_HA), - table->file->table_type(), - table->s->db.str, table->s->table_name.str); - error= 0; + if (error == HA_ERR_WRONG_COMMAND) + { + THD *thd= table->in_use; + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_ILLEGAL_HA, ER_THD(thd, ER_ILLEGAL_HA), + table->file->table_type(), + table->s->db.str, table->s->table_name.str); + error= 0; + } + else + table->file->print_error(error, MYF(0)); } - else if (error) - table->file->print_error(error, MYF(0)); - DBUG_RETURN(error); } @@ -7365,8 +7421,11 @@ static bool mysql_inplace_alter_table(THD *thd, exclusive lock is required for duration of the whole statement. */ if (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK || - ((inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE || - inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE) && + ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || + inplace_supported == HA_ALTER_INPLACE_COPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_INSTANT) && (thd->locked_tables_mode == LTM_LOCK_TABLES || thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)) || alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE) @@ -7390,8 +7449,11 @@ static bool mysql_inplace_alter_table(THD *thd, */ reopen_tables= true; } - else if (inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE || - inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE) + else if (inplace_supported == HA_ALTER_INPLACE_COPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK || + inplace_supported == HA_ALTER_INPLACE_INSTANT) { /* Storage engine has requested exclusive lock only for prepare phase @@ -7436,7 +7498,9 @@ static bool mysql_inplace_alter_table(THD *thd, DBUG_ASSERT(0); // fall through case HA_ALTER_INPLACE_NO_LOCK: - case HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE: + case HA_ALTER_INPLACE_INSTANT: + case HA_ALTER_INPLACE_COPY_NO_LOCK: + case HA_ALTER_INPLACE_NOCOPY_NO_LOCK: switch (alter_info->requested_lock) { case Alter_info::ALTER_TABLE_LOCK_DEFAULT: case Alter_info::ALTER_TABLE_LOCK_NONE: @@ -7448,8 +7512,9 @@ static bool mysql_inplace_alter_table(THD *thd, } break; case HA_ALTER_INPLACE_EXCLUSIVE_LOCK: - case HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE: case HA_ALTER_INPLACE_SHARED_LOCK: + case HA_ALTER_INPLACE_COPY_LOCK: + case HA_ALTER_INPLACE_NOCOPY_LOCK: break; } @@ -7464,19 +7529,23 @@ static bool mysql_inplace_alter_table(THD *thd, necessary only for prepare phase (unless we are not under LOCK TABLES) and user has not explicitly requested exclusive lock. */ - if ((inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE || - inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE) && + if ((inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || + inplace_supported == HA_ALTER_INPLACE_COPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK) && !(thd->locked_tables_mode == LTM_LOCK_TABLES || thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) && (alter_info->requested_lock != Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE)) { /* If storage engine or user requested shared lock downgrade to SNW. */ - if (inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE || + if (inplace_supported == HA_ALTER_INPLACE_COPY_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_LOCK || alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED) table->mdl_ticket->downgrade_lock(MDL_SHARED_NO_WRITE); else { - DBUG_ASSERT(inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE); + DBUG_ASSERT(inplace_supported == HA_ALTER_INPLACE_COPY_NO_LOCK || + inplace_supported == HA_ALTER_INPLACE_NOCOPY_NO_LOCK); table->mdl_ticket->downgrade_lock(MDL_SHARED_UPGRADABLE); } } @@ -7633,7 +7702,7 @@ static bool mysql_inplace_alter_table(THD *thd, HA_EXTRA_PREPARE_FOR_RENAME : HA_EXTRA_NOT_USED, NULL); - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); /* QQ; do something about metadata locks ? */ } @@ -7888,6 +7957,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (field->default_value) field->default_value->expr->walk(&Item::rename_fields_processor, 1, &column_rename_param); + table->m_needs_reopen= 1; // because new column name is on thd->mem_root } /* Check if field is changed */ @@ -8007,7 +8077,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, break; } - if (find && !find->field) + if (likely(find && !find->field)) find_it.remove(); else { @@ -8078,7 +8148,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, &find->field_name)) break; } - if (!find) + if (unlikely(!find)) { my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after.str, table->s->table_name.str); @@ -8112,13 +8182,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, alter_it.remove(); } } - if (alter_info->alter_list.elements) + if (unlikely(alter_info->alter_list.elements)) { my_error(ER_BAD_FIELD_ERROR, MYF(0), alter_info->alter_list.head()->name, table->s->table_name.str); goto err; } - if (!new_create_list.elements) + if (unlikely(!new_create_list.elements)) { my_message(ER_CANT_REMOVE_ALL_FIELDS, ER_THD(thd, ER_CANT_REMOVE_ALL_FIELDS), @@ -8594,7 +8664,7 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table, table->file->get_parent_foreign_key_list(thd, &fk_parent_key_list); /* OOM when building list. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(true); /* @@ -8689,7 +8759,7 @@ static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table, table->file->get_foreign_key_list(thd, &fk_child_key_list); /* OOM when building list. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) DBUG_RETURN(true); /* @@ -8783,7 +8853,7 @@ simple_tmp_rename_or_index_change(THD *thd, TABLE_LIST *table_list, keys_onoff); } - if (!error && alter_ctx->is_table_renamed()) + if (likely(!error) && alter_ctx->is_table_renamed()) { THD_STAGE_INFO(thd, stage_rename); @@ -8796,20 +8866,17 @@ simple_tmp_rename_or_index_change(THD *thd, TABLE_LIST *table_list, &alter_ctx->new_alias); } - if (!error) + if (likely(!error)) { - int res= 0; /* We do not replicate alter table statement on temporary tables under ROW-based replication. */ if (!thd->is_current_stmt_binlog_format_row()) { - res= write_bin_log(thd, true, thd->query(), thd->query_length()); + error= write_bin_log(thd, true, thd->query(), thd->query_length()) != 0; } - if (res != 0) - error= true; - else + if (likely(!error)) my_ok(thd); } @@ -8858,7 +8925,7 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, keys_onoff); } - if (!error && alter_ctx->is_table_renamed()) + if (likely(!error) && alter_ctx->is_table_renamed()) { THD_STAGE_INFO(thd, stage_rename); handlerton *old_db_type= table->s->db_type(); @@ -8898,11 +8965,11 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, } } - if (!error) + if (likely(!error)) { error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - if (!error) + if (likely(!error)) my_ok(thd); } table_list->table= NULL; // For query cache @@ -8963,7 +9030,8 @@ simple_rename_or_index_change(THD *thd, TABLE_LIST *table_list, based on information about the table changes from fill_alter_inplace_info(). */ -bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *new_name, +bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, + const LEX_CSTRING *new_name, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, Alter_info *alter_info, @@ -8971,6 +9039,10 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n { DBUG_ENTER("mysql_alter_table"); +#ifdef WITH_PARTITION_STORAGE_ENGINE + thd->work_part_info= 0; // Used by partitioning +#endif + /* Check if we attempt to alter mysql.slow_log or mysql.general_log table and return an error if @@ -9065,7 +9137,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n };); #endif // WITH_WSREP - if (error) + if (unlikely(error)) DBUG_RETURN(true); table->use_all_columns(); @@ -9386,7 +9458,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n supports auto-partitioning as such engines can do some changes using in-place API. */ - if ((thd->variables.old_alter_table && + if ((thd->variables.alter_algorithm == Alter_info::ALTER_TABLE_ALGORITHM_COPY && alter_info->requested_algorithm != Alter_info::ALTER_TABLE_ALGORITHM_INPLACE) || is_inplace_alter_impossible(table, create_info, alter_info) @@ -9511,7 +9583,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n &key_info, &key_count, &frm); reenable_binlog(thd); thd->abort_on_warning= false; - if (error) + if (unlikely(error)) { my_free(const_cast<uchar*>(frm.str)); DBUG_RETURN(true); @@ -9594,74 +9666,32 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n goto err_new_table_cleanup; thd->count_cuted_fields= CHECK_FIELD_IGNORE; + if (alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_NONE) + ha_alter_info.online= true; // Ask storage engine whether to use copy or in-place enum_alter_inplace_result inplace_supported= table->file->check_if_supported_inplace_alter(altered_table, &ha_alter_info); - switch (inplace_supported) { - case HA_ALTER_INPLACE_EXCLUSIVE_LOCK: - // If SHARED lock and no particular algorithm was requested, use COPY. - if (alter_info->requested_lock == - Alter_info::ALTER_TABLE_LOCK_SHARED && - alter_info->requested_algorithm == - Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT) - { - use_inplace= false; - } - // Otherwise, if weaker lock was requested, report errror. - else if (alter_info->requested_lock == - Alter_info::ALTER_TABLE_LOCK_NONE || - alter_info->requested_lock == - Alter_info::ALTER_TABLE_LOCK_SHARED) - { - ha_alter_info.report_unsupported_error("LOCK=NONE/SHARED", - "LOCK=EXCLUSIVE"); - thd->drop_temporary_table(altered_table, NULL, false); - goto err_new_table_cleanup; - } - break; - case HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE: - case HA_ALTER_INPLACE_SHARED_LOCK: - // If weaker lock was requested, report errror. - if (alter_info->requested_lock == - Alter_info::ALTER_TABLE_LOCK_NONE) - { - ha_alter_info.report_unsupported_error("LOCK=NONE", "LOCK=SHARED"); - thd->drop_temporary_table(altered_table, NULL, false); - goto err_new_table_cleanup; - } - break; - case HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE: - case HA_ALTER_INPLACE_NO_LOCK: - break; - case HA_ALTER_INPLACE_NOT_SUPPORTED: - // If INPLACE was requested, report error. - if (alter_info->requested_algorithm == - Alter_info::ALTER_TABLE_ALGORITHM_INPLACE) - { - ha_alter_info.report_unsupported_error("ALGORITHM=INPLACE", - "ALGORITHM=COPY"); - thd->drop_temporary_table(altered_table, NULL, false); - goto err_new_table_cleanup; - } - // COPY with LOCK=NONE is not supported, no point in trying. - if (alter_info->requested_lock == - Alter_info::ALTER_TABLE_LOCK_NONE) - { - ha_alter_info.report_unsupported_error("LOCK=NONE", "LOCK=SHARED"); - thd->drop_temporary_table(altered_table, NULL, false); - goto err_new_table_cleanup; - } - // Otherwise use COPY - use_inplace= false; - break; - case HA_ALTER_ERROR: - default: + if (alter_info->supports_algorithm(thd, inplace_supported, &ha_alter_info) || + alter_info->supports_lock(thd, inplace_supported, &ha_alter_info)) + { thd->drop_temporary_table(altered_table, NULL, false); goto err_new_table_cleanup; } + // If SHARED lock and no particular algorithm was requested, use COPY. + if (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK && + alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED && + alter_info->requested_algorithm == + Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT && + thd->variables.alter_algorithm == + Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT) + use_inplace= false; + + if (inplace_supported == HA_ALTER_INPLACE_NOT_SUPPORTED) + use_inplace= false; + if (use_inplace) { table->s->frm_image= &frm; @@ -9967,7 +9997,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *n end_inplace: - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) goto err_with_mdl_after_alter; THD_STAGE_INFO(thd, stage_end); @@ -10018,8 +10048,8 @@ err_new_table_cleanup: the table to be altered isn't empty. Report error here. */ - if (alter_ctx.error_if_not_empty && - thd->get_stmt_da()->current_row_for_warning()) + if (unlikely(alter_ctx.error_if_not_empty && + thd->get_stmt_da()->current_row_for_warning())) { const char *f_val= 0; enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE; @@ -10083,9 +10113,7 @@ bool mysql_trans_prepare_alter_copy_data(THD *thd) This needs to be done before external_lock. */ - if (ha_enable_transaction(thd, FALSE)) - DBUG_RETURN(TRUE); - DBUG_RETURN(FALSE); + DBUG_RETURN(ha_enable_transaction(thd, FALSE) != 0); } @@ -10138,6 +10166,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, List<Item> fields; List<Item> all_fields; bool auto_increment_field_copied= 0; + bool cleanup_done= 0; bool init_read_record_done= 0; sql_mode_t save_sql_mode= thd->variables.sql_mode; ulonglong prev_insert_id, time_to_report_progress; @@ -10153,18 +10182,31 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, /* Two or 3 stages; Sorting, copying data and update indexes */ thd_progress_init(thd, 2 + MY_TEST(order)); - if (mysql_trans_prepare_alter_copy_data(thd)) + if (!(copy= new (thd->mem_root) Copy_field[to->s->fields])) DBUG_RETURN(-1); - if (!(copy= new (thd->mem_root) Copy_field[to->s->fields])) - DBUG_RETURN(-1); /* purecov: inspected */ + if (mysql_trans_prepare_alter_copy_data(thd)) + { + delete [] copy; + DBUG_RETURN(-1); + } /* We need external lock before we can disable/enable keys */ if (to->file->ha_external_lock(thd, F_WRLCK)) + { + /* Undo call to mysql_trans_prepare_alter_copy_data() */ + ha_enable_transaction(thd, TRUE); + delete [] copy; DBUG_RETURN(-1); + } alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff); + /* Set read map for all fields in from table */ + from->default_column_bitmaps(); + bitmap_set_all(from->read_set); + from->file->column_bitmaps_signal(); + /* We can abort alter table for any table type */ thd->abort_on_warning= !ignore && thd->is_strict_mode(); @@ -10172,7 +10214,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, to->file->extra(HA_EXTRA_PREPARE_FOR_ALTER_TABLE); to->file->ha_start_bulk_insert(from->file->stats.records, ignore ? 0 : HA_CREATE_UNIQUE_INDEX_BY_SORT); - List_iterator<Create_field> it(create); Create_field *def; copy_end=copy; @@ -10285,15 +10326,15 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, if (!ignore) /* for now, InnoDB needs the undo log for ALTER IGNORE */ to->file->extra(HA_EXTRA_BEGIN_ALTER_COPY); - while (!(error= info.read_record())) + while (likely(!(error= info.read_record()))) { - if (thd->killed) + if (unlikely(thd->killed)) { thd->send_kill_message(); error= 1; break; } - if (++thd->progress.counter >= time_to_report_progress) + if (unlikely(++thd->progress.counter >= time_to_report_progress)) { time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10; thd_progress_report(thd, thd->progress.counter, @@ -10301,7 +10342,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, } /* Return error if source table isn't empty. */ - if (alter_ctx->error_if_not_empty) + if (unlikely(alter_ctx->error_if_not_empty)) { error= 1; break; @@ -10343,7 +10384,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, /* This will set thd->is_error() if fatal failure */ if (to->verify_constraints(ignore) == VIEW_CHECK_SKIP) continue; - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; break; @@ -10353,7 +10394,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, error= to->file->ha_write_row(to->record[0]); to->auto_increment_field_not_null= FALSE; - if (error) + if (unlikely(error)) { if (to->file->is_fatal_error(error, HA_CHECK_DUP)) { @@ -10365,7 +10406,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, else { /* Duplicate key error. */ - if (alter_ctx->fk_error_if_delete_row) + if (unlikely(alter_ctx->fk_error_if_delete_row)) { /* We are trying to omit a row from the table which serves as parent @@ -10421,7 +10462,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, /* We are going to drop the temporary table */ to->file->extra(HA_EXTRA_PREPARE_FOR_DROP); } - if (to->file->ha_end_bulk_insert() && error <= 0) + if (unlikely(to->file->ha_end_bulk_insert()) && error <= 0) { /* Give error, if not already given */ if (!thd->is_error()) @@ -10430,9 +10471,11 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, } if (!ignore) to->file->extra(HA_EXTRA_END_ALTER_COPY); + + cleanup_done= 1; to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - if (mysql_trans_commit_alter_copy_data(thd)) + if (unlikely(mysql_trans_commit_alter_copy_data(thd))) error= 1; err: @@ -10447,6 +10490,15 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, *copied= found_count; *deleted=delete_count; to->file->ha_release_auto_increment(); + + if (!cleanup_done) + { + /* This happens if we get an error during initialzation of data */ + DBUG_ASSERT(error); + to->file->ha_end_bulk_insert(); + ha_enable_transaction(thd, TRUE); + } + if (to->file->ha_external_lock(thd,F_UNLCK)) error=1; if (error < 0 && !from->s->tmp_table && @@ -10623,8 +10675,6 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, int error= t->file->ha_rnd_next(t->record[0]); if (unlikely(error)) { - if (error == HA_ERR_RECORD_DELETED) - continue; break; } if (t->s->null_bytes) diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc index 93a3007d1ea..d97d50912e6 100644 --- a/sql/sql_tablespace.cc +++ b/sql/sql_tablespace.cc @@ -46,21 +46,16 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) if (hton->alter_tablespace) { - if ((error= hton->alter_tablespace(hton, thd, ts_info))) + if (unlikely((error= hton->alter_tablespace(hton, thd, ts_info)))) { if (error == 1) - { DBUG_RETURN(1); - } if (error == HA_ADMIN_NOT_IMPLEMENTED) - { my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), ""); - } else - { my_error(error, MYF(0)); - } + DBUG_RETURN(error); } } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 4c1e2a51fbf..6961f821a0a 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2004, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -430,7 +431,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) /* We don't allow creating triggers on tables in the 'mysql' schema */ - if (create && !my_strcasecmp(system_charset_info, "mysql", tables->db.str)) + if (create && lex_string_eq(&tables->db, STRING_WITH_LEN("mysql"))) { my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0)); DBUG_RETURN(TRUE); @@ -588,7 +589,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) Ignore the return value for now. It's better to keep master/slave in consistent state. */ - if (thd->locked_tables_list.reopen_tables(thd)) + if (thd->locked_tables_list.reopen_tables(thd, false)) thd->clear_error(); /* @@ -623,6 +624,7 @@ end: #endif /* WITH_WSREP */ } + /** Build stmt_query to write it in the bin-log, the statement to write in the trigger file and the trigger definer. @@ -1190,6 +1192,12 @@ Table_triggers_list::~Table_triggers_list() } } } + + /* Free blobs used in insert */ + if (record0_field) + for (Field **fld_ptr= record0_field; *fld_ptr; fld_ptr++) + (*fld_ptr)->free(); + if (record1_field) for (Field **fld_ptr= record1_field; *fld_ptr; fld_ptr++) delete *fld_ptr; @@ -1240,6 +1248,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) return 1; f->flags= (*fld)->flags; + f->invisible= (*fld)->invisible; f->null_ptr= null_ptr; f->null_bit= null_bit; if (null_bit == 128) @@ -1368,12 +1377,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, List_iterator_fast<LEX_CSTRING> it_connection_cl_name(trigger_list->connection_cl_names); List_iterator_fast<LEX_CSTRING> it_db_cl_name(trigger_list->db_cl_names); List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times); - LEX *old_lex= thd->lex, *old_stmt_lex= thd->stmt_lex; + LEX *old_lex= thd->lex; LEX lex; sp_rcontext *save_spcont= thd->spcont; sql_mode_t save_sql_mode= thd->variables.sql_mode; - thd->lex= thd->stmt_lex= &lex; + thd->lex= &lex; save_db= thd->db; thd->reset_db(db); @@ -1475,7 +1484,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, &lex.trg_chistics.anchor_trigger_name, trigger); - if (parse_error) + if (unlikely(parse_error)) { LEX_CSTRING *name; @@ -1489,10 +1498,10 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, DBUG_ASSERT(lex.sphead == 0); lex_end(&lex); - if ((name= error_handler.get_trigger_name())) + if (likely((name= error_handler.get_trigger_name()))) { - if (!(make_lex_string(&trigger->name, name->str, - name->length, &table->mem_root))) + if (unlikely(!(make_lex_string(&trigger->name, name->str, + name->length, &table->mem_root)))) goto err_with_lex_cleanup; } trigger->definer= ((!trg_definer || !trg_definer->length) ? @@ -1590,7 +1599,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, } thd->reset_db(&save_db); thd->lex= old_lex; - thd->stmt_lex= old_stmt_lex; thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; @@ -1604,7 +1612,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, err_with_lex_cleanup: lex_end(&lex); thd->lex= old_lex; - thd->stmt_lex= old_stmt_lex; thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; thd->reset_db(&save_db); @@ -1613,7 +1620,7 @@ err_with_lex_cleanup: } error: - if (!thd->is_error()) + if (unlikely(!thd->is_error())) { /* We don't care about this error message much because .TRG files will @@ -1889,7 +1896,7 @@ change_table_name_in_triggers(THD *thd, thd->variables.sql_mode= save_sql_mode; - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) return TRUE; /* OOM */ if (save_trigger_file(thd, new_db_name, new_table_name)) @@ -2101,9 +2108,9 @@ bool Table_triggers_list::change_table_name(THD *thd, const LEX_CSTRING *db, goto end; } } - if (table.triggers->change_table_name_in_triggers(thd, db, new_db, - old_alias, - new_table)) + if (unlikely(table.triggers->change_table_name_in_triggers(thd, db, new_db, + old_alias, + new_table))) { result= 1; goto end; @@ -2247,7 +2254,7 @@ add_tables_and_routines_for_triggers(THD *thd, { sp_head *trigger= triggers->body; - if (!triggers->body) // Parse error + if (unlikely(!triggers->body)) // Parse error continue; MDL_key key(MDL_key::TRIGGER, trigger->m_db.str, trigger->m_name.str); diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 2ddb4bc042c..cf91d6d2189 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, 2015, Oracle and/or its affiliates. - Copyright (c) 2013, 2015, MariaDB + Copyright (c) 2012, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -139,7 +139,7 @@ fk_truncate_illegal_if_parent(THD *thd, TABLE *table) table->file->get_parent_foreign_key_list(thd, &fk_list); /* Out of memory when building list. */ - if (thd->is_error()) + if (unlikely(thd->is_error())) return TRUE; it.init(fk_list); @@ -240,7 +240,7 @@ Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref, DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG); error= table_ref->table->file->ha_truncate(); - if (error) + if (unlikely(error)) { table_ref->table->file->print_error(error, MYF(0)); /* @@ -302,7 +302,7 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref, table_ref->table_name.str, FALSE))) DBUG_RETURN(TRUE); - *hton_can_recreate= ha_check_storage_engine_flag(table->s->db_type(), + *hton_can_recreate= ha_check_storage_engine_flag(table->file->ht, HTON_CAN_RECREATE); table_ref->mdl_request.ticket= table->mdl_ticket; } @@ -427,8 +427,11 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref) */ error= dd_recreate_table(thd, table_ref->db.str, table_ref->table_name.str); - if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd)) - thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); + if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd, false)) + { + thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); + error=1; + } /* No need to binlog a failed truncate-by-recreate. */ binlog_stmt= !error; @@ -447,7 +450,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref) query must be written to the binary log. The only exception is a unimplemented truncate method. */ - if (error == TRUNCATE_OK || error == TRUNCATE_FAILED_BUT_BINLOG) + if (unlikely(error == TRUNCATE_OK || error == TRUNCATE_FAILED_BUT_BINLOG)) binlog_stmt= true; else binlog_stmt= false; @@ -500,4 +503,3 @@ bool Sql_cmd_truncate_table::execute(THD *thd) DBUG_RETURN(res); } - diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 7004c32e602..188ba8c4629 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -221,6 +221,12 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, uint cnt= first_elem->elements; Type_holder *holders; + if (cnt == 0) + { + my_error(ER_EMPTY_ROW_IN_TVC, MYF(0)); + DBUG_RETURN(true); + } + if (fix_fields_for_tvc(thd, li)) DBUG_RETURN(true); @@ -249,7 +255,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, sl->item_list.push_back(new_holder); } - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(true); // out of memory result= tmp_result; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 0c9dc57dcd3..07a5fea6551 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -161,15 +161,6 @@ void Temporal_with_date::make_from_item(THD *thd, Item *item, sql_mode_t flags) } -void Type_std_attributes::set(const Field *field) -{ - decimals= field->decimals(); - unsigned_flag= MY_TEST(field->flags & UNSIGNED_FLAG); - collation.set(field->charset(), field->derivation(), field->repertoire()); - fix_char_length(field->char_length()); -} - - uint Type_std_attributes::count_max_decimals(Item **item, uint nitems) { uint res= 0; @@ -476,6 +467,20 @@ const Name Type_handler_datetime_common::m_name_datetime(STRING_WITH_LEN("datetime")), Type_handler_timestamp_common::m_name_timestamp(STRING_WITH_LEN("timestamp")); + +const Type_limits_int + Type_handler_tiny::m_limits_sint8= Type_limits_sint8(), + Type_handler_tiny::m_limits_uint8= Type_limits_uint8(), + Type_handler_short::m_limits_sint16= Type_limits_sint16(), + Type_handler_short::m_limits_uint16= Type_limits_uint16(), + Type_handler_int24::m_limits_sint24= Type_limits_sint24(), + Type_handler_int24::m_limits_uint24= Type_limits_uint24(), + Type_handler_long::m_limits_sint32= Type_limits_sint32(), + Type_handler_long::m_limits_uint32= Type_limits_uint32(), + Type_handler_longlong::m_limits_sint64= Type_limits_sint64(), + Type_handler_longlong::m_limits_uint64= Type_limits_uint64(); + + /***************************************************************************/ const Type_handler *Type_handler_null::type_handler_for_comparison() const @@ -696,9 +701,7 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h) Item_result a= cmp_type(); Item_result b= h->cmp_type(); - if (m_vers_trx_id && (a == STRING_RESULT || b == STRING_RESULT)) - m_type_handler= &type_handler_datetime; - else if (a == STRING_RESULT && b == STRING_RESULT) + if (a == STRING_RESULT && b == STRING_RESULT) m_type_handler= &type_handler_long_blob; else if (a == INT_RESULT && b == INT_RESULT) m_type_handler= &type_handler_longlong; @@ -2506,6 +2509,14 @@ uint32 Type_handler_bit::max_display_length(const Item *item) const return item->max_length; } + +uint32 Type_handler_general_purpose_int::max_display_length(const Item *item) + const +{ + return type_limits_int_by_unsigned_flag(item->unsigned_flag)->char_length(); +} + + /*************************************************************************/ int Type_handler_time_common::Item_save_in_field(Item *item, Field *field, @@ -6285,4 +6296,61 @@ bool Type_handler_geometry:: } #endif +bool Type_handler::Vers_history_point_resolve_unit(THD *thd, + Vers_history_point *point) + const +{ + /* + Disallow using non-relevant data types in history points. + Even expressions with explicit TRANSACTION or TIMESTAMP units. + */ + point->bad_expression_data_type_error(name().ptr()); + return true; +} + + +bool Type_handler_typelib:: + Vers_history_point_resolve_unit(THD *thd, + Vers_history_point *point) const +{ + /* + ENUM/SET have dual type properties (string and numeric). + Require explicit CAST to avoid ambiguity. + */ + point->bad_expression_data_type_error(name().ptr()); + return true; +} + + +bool Type_handler_general_purpose_int:: + Vers_history_point_resolve_unit(THD *thd, + Vers_history_point *point) const +{ + return point->resolve_unit_trx_id(thd); +} + + +bool Type_handler_bit:: + Vers_history_point_resolve_unit(THD *thd, + Vers_history_point *point) const +{ + return point->resolve_unit_trx_id(thd); +} + + +bool Type_handler_temporal_result:: + Vers_history_point_resolve_unit(THD *thd, + Vers_history_point *point) const +{ + return point->resolve_unit_timestamp(thd); +} + + +bool Type_handler_general_purpose_string:: + Vers_history_point_resolve_unit(THD *thd, + Vers_history_point *point) const +{ + return point->resolve_unit_timestamp(thd); +} + /***************************************************************************/ diff --git a/sql/sql_type.h b/sql/sql_type.h index b9d739be8b9..ad554a91024 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -73,6 +73,7 @@ class handler; struct Schema_specification_st; struct TABLE; struct SORT_FIELD_ATTR; +class Vers_history_point; /** @@ -618,7 +619,6 @@ public: { *this= other; } - void set(const Field *field); uint32 max_char_length() const { return max_length / collation.collation->mbmaxlen; } void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs) @@ -951,6 +951,74 @@ public: }; +class Information_schema_numeric_attributes +{ + enum enum_attr + { + ATTR_NONE= 0, + ATTR_PRECISION= 1, + ATTR_SCALE= 2, + ATTR_PRECISION_AND_SCALE= (ATTR_PRECISION|ATTR_SCALE) + }; + uint m_precision; + uint m_scale; + enum_attr m_available_attributes; +public: + Information_schema_numeric_attributes() + :m_precision(0), m_scale(0), + m_available_attributes(ATTR_NONE) + { } + Information_schema_numeric_attributes(uint precision) + :m_precision(precision), m_scale(0), + m_available_attributes(ATTR_PRECISION) + { } + Information_schema_numeric_attributes(uint precision, uint scale) + :m_precision(precision), m_scale(scale), + m_available_attributes(ATTR_PRECISION_AND_SCALE) + { } + bool has_precision() const { return m_available_attributes & ATTR_PRECISION; } + bool has_scale() const { return m_available_attributes & ATTR_SCALE; } + uint precision() const + { + DBUG_ASSERT(has_precision()); + return (uint) m_precision; + } + uint scale() const + { + DBUG_ASSERT(has_scale()); + return (uint) m_scale; + } +}; + + +class Information_schema_character_attributes +{ + uint32 m_octet_length; + uint32 m_char_length; + bool m_is_set; +public: + Information_schema_character_attributes() + :m_octet_length(0), m_char_length(0), m_is_set(false) + { } + Information_schema_character_attributes(uint32 octet_length, + uint32 char_length) + :m_octet_length(octet_length), m_char_length(char_length), m_is_set(true) + { } + bool has_octet_length() const { return m_is_set; } + bool has_char_length() const { return m_is_set; } + uint32 octet_length() const + { + DBUG_ASSERT(has_octet_length()); + return m_octet_length; + } + uint char_length() const + { + DBUG_ASSERT(has_char_length()); + return m_char_length; + } +}; + + class Type_handler { protected: @@ -1430,6 +1498,9 @@ public: Item_func_div_fix_length_and_dec(Item_func_div *func) const= 0; virtual bool Item_func_mod_fix_length_and_dec(Item_func_mod *func) const= 0; + + virtual bool + Vers_history_point_resolve_unit(THD *thd, Vers_history_point *point) const; }; @@ -1932,6 +2003,131 @@ public: }; +class Type_limits_int +{ +private: + uint32 m_precision; + uint32 m_char_length; +public: + Type_limits_int(uint32 prec, uint32 nchars) + :m_precision(prec), m_char_length(nchars) + { } + uint32 precision() const { return m_precision; } + uint32 char_length() const { return m_char_length; } +}; + + +/* + UNDIGNED TINYINT: 0..255 digits=3 nchars=3 + SIGNED TINYINT : -128..127 digits=3 nchars=4 +*/ +class Type_limits_uint8: public Type_limits_int +{ +public: + Type_limits_uint8() + :Type_limits_int(MAX_TINYINT_WIDTH, MAX_TINYINT_WIDTH) + { } +}; + + +class Type_limits_sint8: public Type_limits_int +{ +public: + Type_limits_sint8() + :Type_limits_int(MAX_TINYINT_WIDTH, MAX_TINYINT_WIDTH + 1) + { } +}; + + +/* + UNDIGNED SMALLINT: 0..65535 digits=5 nchars=5 + SIGNED SMALLINT: -32768..32767 digits=5 nchars=6 +*/ +class Type_limits_uint16: public Type_limits_int +{ +public: + Type_limits_uint16() + :Type_limits_int(MAX_SMALLINT_WIDTH, MAX_SMALLINT_WIDTH) + { } +}; + + +class Type_limits_sint16: public Type_limits_int +{ +public: + Type_limits_sint16() + :Type_limits_int(MAX_SMALLINT_WIDTH, MAX_SMALLINT_WIDTH + 1) + { } +}; + + +/* + MEDIUMINT UNSIGNED 0 .. 16777215 digits=8 char_length=8 + MEDIUMINT SIGNED: -8388608 .. 8388607 digits=7 char_length=8 +*/ +class Type_limits_uint24: public Type_limits_int +{ +public: + Type_limits_uint24() + :Type_limits_int(MAX_MEDIUMINT_WIDTH, MAX_MEDIUMINT_WIDTH) + { } +}; + + +class Type_limits_sint24: public Type_limits_int +{ +public: + Type_limits_sint24() + :Type_limits_int(MAX_MEDIUMINT_WIDTH - 1, MAX_MEDIUMINT_WIDTH) + { } +}; + + +/* + UNSIGNED INT: 0..4294967295 digits=10 nchars=10 + SIGNED INT: -2147483648..2147483647 digits=10 nchars=11 +*/ +class Type_limits_uint32: public Type_limits_int +{ +public: + Type_limits_uint32() + :Type_limits_int(MAX_INT_WIDTH, MAX_INT_WIDTH) + { } +}; + + + +class Type_limits_sint32: public Type_limits_int +{ +public: + Type_limits_sint32() + :Type_limits_int(MAX_INT_WIDTH, MAX_INT_WIDTH + 1) + { } +}; + + +/* + UNSIGNED BIGINT: 0..18446744073709551615 digits=20 nchars=20 + SIGNED BIGINT: -9223372036854775808..9223372036854775807 digits=19 nchars=20 +*/ +class Type_limits_uint64: public Type_limits_int +{ +public: + Type_limits_uint64(): Type_limits_int(MAX_BIGINT_WIDTH, MAX_BIGINT_WIDTH) + { } +}; + + +class Type_limits_sint64: public Type_limits_int +{ +public: + Type_limits_sint64() + :Type_limits_int(MAX_BIGINT_WIDTH - 1, MAX_BIGINT_WIDTH) + { } +}; + + + class Type_handler_int_result: public Type_handler_numeric { public: @@ -2007,6 +2203,10 @@ class Type_handler_general_purpose_int: public Type_handler_int_result { public: bool type_can_have_auto_increment_attribute() const { return true; } + virtual const Type_limits_int * + type_limits_int_by_unsigned_flag(bool unsigned_flag) const= 0; + uint32 max_display_length(const Item *item) const; + bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; }; @@ -2076,6 +2276,7 @@ public: bool Item_func_mul_fix_length_and_dec(Item_func_mul *) const; bool Item_func_div_fix_length_and_dec(Item_func_div *) const; bool Item_func_mod_fix_length_and_dec(Item_func_mod *) const; + bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; }; @@ -2200,6 +2401,7 @@ class Type_handler_general_purpose_string: public Type_handler_string_result { public: bool is_general_purpose_string_type() const { return true; } + bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; }; @@ -2226,11 +2428,16 @@ public: class Type_handler_tiny: public Type_handler_general_purpose_int { static const Name m_name_tiny; + static const Type_limits_int m_limits_sint8; + static const Type_limits_int m_limits_uint8; public: virtual ~Type_handler_tiny() {} const Name name() const { return m_name_tiny; } enum_field_types field_type() const { return MYSQL_TYPE_TINY; } - uint32 max_display_length(const Item *item) const { return 4; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint8 : &m_limits_sint8; + } uint32 calc_pack_length(uint32 length) const { return 1; } bool Item_send(Item *item, Protocol *protocol, st_value *buf) const { @@ -2262,6 +2469,8 @@ public: class Type_handler_short: public Type_handler_general_purpose_int { static const Name m_name_short; + static const Type_limits_int m_limits_sint16; + static const Type_limits_int m_limits_uint16; public: virtual ~Type_handler_short() {} const Name name() const { return m_name_short; } @@ -2270,7 +2479,10 @@ public: { return Item_send_short(item, protocol, buf); } - uint32 max_display_length(const Item *item) const { return 6; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint16 : &m_limits_sint16; + } uint32 calc_pack_length(uint32 length) const { return 2; } Field *make_conversion_table_field(TABLE *TABLE, uint metadata, const Field *target) const; @@ -2298,13 +2510,15 @@ public: class Type_handler_long: public Type_handler_general_purpose_int { static const Name m_name_int; + static const Type_limits_int m_limits_sint32; + static const Type_limits_int m_limits_uint32; public: virtual ~Type_handler_long() {} const Name name() const { return m_name_int; } enum_field_types field_type() const { return MYSQL_TYPE_LONG; } - uint32 max_display_length(const Item *item) const + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const { - return MY_INT32_NUM_DECIMAL_DIGITS; + return unsigned_fl ? &m_limits_uint32 : &m_limits_sint32; } uint32 calc_pack_length(uint32 length) const { return 4; } bool Item_send(Item *item, Protocol *protocol, st_value *buf) const @@ -2347,11 +2561,16 @@ public: class Type_handler_longlong: public Type_handler_general_purpose_int { static const Name m_name_longlong; + static const Type_limits_int m_limits_sint64; + static const Type_limits_int m_limits_uint64; public: virtual ~Type_handler_longlong() {} const Name name() const { return m_name_longlong; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } - uint32 max_display_length(const Item *item) const { return 20; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint64 : &m_limits_sint64; + } uint32 calc_pack_length(uint32 length) const { return 8; } Item *create_typecast_item(THD *thd, Item *item, const Type_cast_attributes &attr) const; @@ -2398,6 +2617,8 @@ public: class Type_handler_int24: public Type_handler_general_purpose_int { static const Name m_name_mediumint; + static const Type_limits_int m_limits_sint24; + static const Type_limits_int m_limits_uint24; public: virtual ~Type_handler_int24() {} const Name name() const { return m_name_mediumint; } @@ -2406,7 +2627,10 @@ public: { return Item_send_long(item, protocol, buf); } - uint32 max_display_length(const Item *item) const { return 8; } + const Type_limits_int *type_limits_int_by_unsigned_flag(bool unsigned_fl) const + { + return unsigned_fl ? &m_limits_uint24 : &m_limits_sint24; + } uint32 calc_pack_length(uint32 length) const { return 3; } Field *make_conversion_table_field(TABLE *, uint metadata, const Field *target) const; @@ -2509,6 +2733,7 @@ public: const Bit_addr &bit, const Column_definition_attributes *attr, uint32 flags) const; + bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; }; @@ -3455,6 +3680,7 @@ public: const; void Item_param_set_param_func(Item_param *param, uchar **pos, ulong len) const; + bool Vers_history_point_resolve_unit(THD *thd, Vers_history_point *p) const; }; @@ -3534,16 +3760,15 @@ public: class Type_handler_hybrid_field_type { const Type_handler *m_type_handler; - bool m_vers_trx_id; bool aggregate_for_min_max(const Type_handler *other); public: Type_handler_hybrid_field_type(); Type_handler_hybrid_field_type(const Type_handler *handler) - :m_type_handler(handler), m_vers_trx_id(false) + :m_type_handler(handler) { } Type_handler_hybrid_field_type(const Type_handler_hybrid_field_type *other) - :m_type_handler(other->m_type_handler), m_vers_trx_id(other->m_vers_trx_id) + :m_type_handler(other->m_type_handler) { } void swap(Type_handler_hybrid_field_type &other) { diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 3eb50d45b42..9a036156de6 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -252,7 +252,7 @@ void udf_init() } } } - if (error > 0) + if (unlikely(error > 0)) sql_print_error("Got unknown error: %d", my_errno); end_read_record(&read_record_info); table->m_needs_reopen= TRUE; // Force close to free memory @@ -453,7 +453,7 @@ static int mysql_drop_function_internal(THD *thd, udf_func *udf, TABLE *table) HA_READ_KEY_EXACT)) { int error; - if ((error= table->file->ha_delete_row(table->record[0]))) + if (unlikely((error= table->file->ha_delete_row(table->record[0])))) table->file->print_error(error, MYF(0)); } DBUG_RETURN(0); @@ -513,7 +513,7 @@ int mysql_create_function(THD *thd,udf_func *udf) { if (thd->lex->create_info.or_replace()) { - if ((error= mysql_drop_function_internal(thd, u_d, table))) + if (unlikely((error= mysql_drop_function_internal(thd, u_d, table)))) goto err; } else if (thd->lex->create_info.if_not_exists()) @@ -569,7 +569,7 @@ int mysql_create_function(THD *thd,udf_func *udf) /* create entry in mysql.func table */ /* Allow creation of functions even if we can't open func table */ - if (!table) + if (unlikely(!table)) goto err; table->use_all_columns(); restore_record(table, s->default_values); // Default values for fields @@ -578,9 +578,9 @@ int mysql_create_function(THD *thd,udf_func *udf) table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), system_charset_info); if (table->s->fields >= 4) // If not old func format table->field[3]->store((longlong) u_d->type, TRUE); - error = table->file->ha_write_row(table->record[0]); + error= table->file->ha_write_row(table->record[0]); - if (error) + if (unlikely(error)) { my_error(ER_ERROR_ON_WRITE, MYF(0), "mysql.func", error); del_udf(u_d); @@ -591,7 +591,7 @@ done: mysql_rwlock_unlock(&THR_LOCK_udf); /* Binlog the create function. */ - if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + if (unlikely(write_bin_log(thd, TRUE, thd->query(), thd->query_length()))) DBUG_RETURN(1); DBUG_RETURN(0); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 0149c2848c2..a1963c33a42 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -36,7 +36,7 @@ bool mysql_union(THD *thd, LEX *lex, select_result *result, { DBUG_ENTER("mysql_union"); bool res; - if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | + if (!(res= unit->prepare(unit->derived, result, SELECT_NO_UNLOCK | setup_tables_done_option))) res= unit->exec(); res|= unit->cleanup(); @@ -126,7 +126,7 @@ int select_unit::send_data(List<Item> &values) } else fill_record(thd, table, table->field, values, TRUE, FALSE); - if (thd->is_error()) + if (unlikely(thd->is_error())) { rc= 1; goto end; @@ -146,7 +146,8 @@ int select_unit::send_data(List<Item> &values) { case UNION_TYPE: { - if ((write_err= table->file->ha_write_tmp_row(table->record[0]))) + if (unlikely((write_err= + table->file->ha_write_tmp_row(table->record[0])))) { if (write_err == HA_ERR_FOUND_DUPP_KEY) { @@ -235,7 +236,7 @@ int select_unit::send_data(List<Item> &values) rc= 0; end: - if (not_reported_error) + if (unlikely(not_reported_error)) { DBUG_ASSERT(rc); table->file->print_error(not_reported_error, MYF(0)); @@ -267,32 +268,26 @@ bool select_unit::send_eof() handler *file= table->file; int error; - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) return 1; do { - error= file->ha_rnd_next(table->record[0]); - if (error) + if (unlikely(error= file->ha_rnd_next(table->record[0]))) { if (error == HA_ERR_END_OF_FILE) { error= 0; break; } - if (unlikely(error == HA_ERR_RECORD_DELETED)) - { - error= 0; - continue; - } break; } if (table->field[0]->val_int() != curr_step) error= file->ha_delete_tmp_row(table->record[0]); - } while (!error); + } while (likely(!error)); file->ha_rnd_end(); - if (error) + if (unlikely(error)) table->file->print_error(error, MYF(0)); return(MY_TEST(error)); @@ -325,7 +320,7 @@ int select_union_recursive::send_data(List<Item> &values) bool select_unit::flush() { int error; - if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) + if (unlikely((error=table->file->extra(HA_EXTRA_NO_CACHE)))) { table->file->print_error(error, MYF(0)); return 1; @@ -413,19 +408,13 @@ select_union_recursive::create_result_table(THD *thd_arg, if (! (incr_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, (ORDER*) 0, false, 1, options, HA_POS_ERROR, &empty_clex_str, - !create_table, keep_row_order))) + true, keep_row_order))) return true; incr_table->keys_in_use_for_query.clear_all(); for (uint i=0; i < table->s->fields; i++) incr_table->field[i]->flags &= ~PART_KEY_FLAG; - if (create_table) - { - incr_table->file->extra(HA_EXTRA_WRITE_CACHE); - incr_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - } - TABLE *rec_table= 0; if (! (rec_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, (ORDER*) 0, false, 1, @@ -469,8 +458,11 @@ void select_union_recursive::cleanup() if (incr_table) { - incr_table->file->extra(HA_EXTRA_RESET_STATE); - incr_table->file->ha_delete_all_rows(); + if (incr_table->is_created()) + { + incr_table->file->extra(HA_EXTRA_RESET_STATE); + incr_table->file->ha_delete_all_rows(); + } free_tmp_table(thd, incr_table); } @@ -507,14 +499,14 @@ void select_union_recursive::cleanup() bool select_union_direct::change_result(select_result *new_result) { result= new_result; - return (result->prepare(unit->types, unit) || result->prepare2()); + return (result->prepare(unit->types, unit) || result->prepare2(NULL)); } bool select_union_direct::postponed_prepare(List<Item> &types) { if (result != NULL) - return (result->prepare(types, unit) || result->prepare2()); + return (result->prepare(types, unit) || result->prepare2(NULL)); else return false; } @@ -555,7 +547,7 @@ int select_union_direct::send_data(List<Item> &items) send_records++; fill_record(thd, table, table->field, items, true, false); - if (thd->is_error()) + if (unlikely(thd->is_error())) return true; /* purecov: inspected */ return result->send_data(unit->item_list); @@ -678,7 +670,7 @@ bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl, sl->with_wild= 0; last_procedure= join->procedure; - if (saved_error || (saved_error= thd_arg->is_fatal_error)) + if (unlikely(saved_error || (saved_error= thd_arg->is_fatal_error))) DBUG_RETURN(true); /* Remove all references from the select_lex_units to the subqueries that @@ -796,29 +788,40 @@ bool st_select_lex_unit::join_union_item_types(THD *thd_arg, join_union_type_attributes(thd_arg, holders, count)) DBUG_RETURN(true); + bool is_recursive= with_element && with_element->is_recursive; types.empty(); List_iterator_fast<Item> it(first_sl->item_list); Item *item_tmp; for (uint pos= 0; (item_tmp= it++); pos++) { + /* + SQL standard requires forced nullability only for + recursive columns. However type aggregation in our + implementation so far does not differentiate between + recursive and non-recursive columns of a recursive CTE. + TODO: this should be fixed. + */ + bool pos_maybe_null= is_recursive ? true : holders[pos].get_maybe_null(); + /* Error's in 'new' will be detected after loop */ types.push_back(new (thd_arg->mem_root) Item_type_holder(thd_arg, item_tmp, holders[pos].type_handler(), &holders[pos]/*Type_all_attributes*/, - holders[pos].get_maybe_null())); + pos_maybe_null)); } - if (thd_arg->is_fatal_error) + if (unlikely(thd_arg->is_fatal_error)) DBUG_RETURN(true); // out of memory DBUG_RETURN(false); } -bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, +bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, + select_result *sel_result, ulong additional_options) { - SELECT_LEX *lex_select_save= thd_arg->lex->current_select; + SELECT_LEX *lex_select_save= thd->lex->current_select; SELECT_LEX *sl, *first_sl= first_select(); bool is_recursive= with_element && with_element->is_recursive; bool is_rec_result_table_created= false; @@ -829,9 +832,25 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, bool instantiate_tmp_table= false; bool single_tvc= !first_sl->next_select() && first_sl->tvc; DBUG_ENTER("st_select_lex_unit::prepare"); - DBUG_ASSERT(thd == thd_arg); DBUG_ASSERT(thd == current_thd); + if (is_recursive && (sl= first_sl->next_select())) + { + SELECT_LEX *next_sl; + for ( ; ; sl= next_sl) + { + next_sl= sl->next_select(); + if (!next_sl) + break; + if (next_sl->with_all_modifier != sl->with_all_modifier) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), + "mix of ALL and DISTINCT UNION operations in recursive CTE spec"); + DBUG_RETURN(TRUE); + } + } + } + describe= additional_options & SELECT_DESCRIBE; /* @@ -881,7 +900,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, prepared= 1; saved_error= FALSE; - thd_arg->lex->current_select= sl= first_sl; + thd->lex->current_select= sl= first_sl; found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; is_union_select= is_unit_op() || fake_select_lex || single_tvc; @@ -910,7 +929,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, while (last->next_select()) last= last->next_select(); if (!(tmp_result= union_result= - new (thd_arg->mem_root) select_union_direct(thd_arg, sel_result, + new (thd->mem_root) select_union_direct(thd, sel_result, last))) goto err; /* purecov: inspected */ fake_select_lex= NULL; @@ -919,13 +938,24 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, else { if (!is_recursive) - union_result= new (thd_arg->mem_root) select_unit(thd_arg); + union_result= new (thd->mem_root) select_unit(thd); else { with_element->rec_result= - new (thd_arg->mem_root) select_union_recursive(thd_arg); + new (thd->mem_root) select_union_recursive(thd); union_result= with_element->rec_result; - fake_select_lex= NULL; + if (fake_select_lex) + { + if (fake_select_lex->order_list.first || + fake_select_lex->explicit_limit) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), + "global ORDER_BY/LIMIT in recursive CTE spec"); + goto err; + } + fake_select_lex->cleanup(); + fake_select_lex= NULL; + } } if (!(tmp_result= union_result)) goto err; /* purecov: inspected */ @@ -941,10 +971,10 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (sl->tvc) { - if (sl->tvc->prepare(thd_arg, sl, tmp_result, this)) + if (sl->tvc->prepare(thd, sl, tmp_result, this)) goto err; } - else if (prepare_join(thd_arg, first_sl, tmp_result, additional_options, + else if (prepare_join(thd, first_sl, tmp_result, additional_options, is_union_select)) goto err; types= first_sl->item_list; @@ -955,10 +985,10 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (sl->tvc) { - if (sl->tvc->prepare(thd_arg, sl, tmp_result, this)) + if (sl->tvc->prepare(thd, sl, tmp_result, this)) goto err; } - else if (prepare_join(thd_arg, sl, tmp_result, additional_options, + else if (prepare_join(thd, sl, tmp_result, additional_options, is_union_select)) goto err; @@ -978,7 +1008,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (with_element) { - if (derived->with->rename_columns_of_derived_unit(thd, this)) + if (derived_arg->with->rename_columns_of_derived_unit(thd, this)) goto err; if (check_duplicate_names(thd, sl->item_list, 0)) goto err; @@ -989,7 +1019,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (first_sl->item_list.elements != sl->item_list.elements) { my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, - ER_THD(thd_arg, ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), + ER_THD(thd, ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0)); goto err; } @@ -998,25 +1028,25 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (!with_element->is_anchor(sl)) sl->uncacheable|= UNCACHEABLE_UNITED; - if(!is_rec_result_table_created && - (!sl->next_select() || - sl->next_select() == with_element->first_recursive)) + if (!is_rec_result_table_created && + (!sl->next_select() || + sl->next_select() == with_element->first_recursive)) { ulonglong create_options; - create_options= (first_sl->options | thd_arg->variables.option_bits | + create_options= (first_sl->options | thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS); // Join data types for all non-recursive parts of a recursive UNION if (join_union_item_types(thd, types, union_part_count + 1)) goto err; if (union_result->create_result_table(thd, &types, MY_TEST(union_distinct), - create_options, &derived->alias, - false, + create_options, + &derived_arg->alias, false, instantiate_tmp_table, false, 0)) goto err; - if (!derived->table) - derived->table= derived->derived_result->table= + if (!derived_arg->table) + derived_arg->table= derived_arg->derived_result->table= with_element->rec_result->rec_tables.head(); with_element->mark_as_with_prepared_anchor(); is_rec_result_table_created= true; @@ -1087,7 +1117,7 @@ cont: } - create_options= (first_sl->options | thd_arg->variables.option_bits | + create_options= (first_sl->options | thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS); /* Force the temporary table to be a MyISAM table if we're going to use @@ -1115,7 +1145,7 @@ cont: Query_arena *arena, backup_arena; arena= thd->activate_stmt_arena_if_needed(&backup_arena); - intersect_mark= new (thd_arg->mem_root) Item_int(thd, 0); + intersect_mark= new (thd->mem_root) Item_int(thd, 0); if (arena) thd->restore_active_arena(arena, &backup_arena); @@ -1137,7 +1167,7 @@ cont: hidden); if (intersect_mark) types.pop(); - if (error) + if (unlikely(error)) goto err; } if (fake_select_lex && !fake_select_lex->first_cond_optimization) @@ -1159,7 +1189,7 @@ cont: result_table_list.maybe_null_exec= save_maybe_null; } - thd_arg->lex->current_select= lex_select_save; + thd->lex->current_select= lex_select_save; if (!item_list.elements) { Query_arena *arena, backup_arena; @@ -1174,7 +1204,7 @@ cont: if (arena) thd->restore_active_arena(arena, &backup_arena); - if (saved_error) + if (unlikely(saved_error)) goto err; if (fake_select_lex != NULL && @@ -1199,7 +1229,7 @@ cont: */ fake_select_lex->item_list= item_list; - thd_arg->lex->current_select= fake_select_lex; + thd->lex->current_select= fake_select_lex; /* We need to add up n_sum_items in order to make the correct @@ -1227,12 +1257,12 @@ cont: } } - thd_arg->lex->current_select= lex_select_save; + thd->lex->current_select= lex_select_save; - DBUG_RETURN(saved_error || thd_arg->is_fatal_error); + DBUG_RETURN(saved_error || thd->is_fatal_error); err: - thd_arg->lex->current_select= lex_select_save; + thd->lex->current_select= lex_select_save; (void) cleanup(); DBUG_RETURN(TRUE); } @@ -1323,7 +1353,7 @@ bool st_select_lex_unit::optimize() saved_error= sl->join->optimize(); } - if (saved_error) + if (unlikely(saved_error)) { thd->lex->current_select= lex_select_save; DBUG_RETURN(saved_error); @@ -1361,7 +1391,7 @@ bool st_select_lex_unit::exec() if (!saved_error && !was_executed) save_union_explain(thd->lex->explain); - if (saved_error) + if (unlikely(saved_error)) DBUG_RETURN(saved_error); if (union_result) @@ -1426,7 +1456,7 @@ bool st_select_lex_unit::exec() saved_error= sl->join->optimize(); } } - if (!saved_error) + if (likely(!saved_error)) { records_at_start= table->file->stats.records; if (sl->tvc) @@ -1437,7 +1467,7 @@ bool st_select_lex_unit::exec() { // This is UNION DISTINCT, so there should be a fake_select_lex DBUG_ASSERT(fake_select_lex != NULL); - if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL)) + if (unlikely(table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))) DBUG_RETURN(TRUE); table->no_keyread=1; } @@ -1446,7 +1476,7 @@ bool st_select_lex_unit::exec() offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() : 0); - if (!saved_error) + if (likely(!saved_error)) { examined_rows+= thd->get_examined_row_count(); thd->set_examined_row_count(0); @@ -1457,7 +1487,7 @@ bool st_select_lex_unit::exec() } } } - if (saved_error) + if (unlikely(saved_error)) { thd->lex->current_select= lex_select_save; DBUG_RETURN(saved_error); @@ -1466,7 +1496,7 @@ bool st_select_lex_unit::exec() { /* Needed for the following test and for records_at_start in next loop */ int error= table->file->info(HA_STATUS_VARIABLE); - if(error) + if (unlikely(error)) { table->file->print_error(error, MYF(0)); DBUG_RETURN(1); @@ -1512,7 +1542,8 @@ bool st_select_lex_unit::exec() */ thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX; - if (fake_select_lex != NULL && !thd->is_fatal_error) // Check if EOM + // Check if EOM + if (fake_select_lex != NULL && likely(!thd->is_fatal_error)) { /* Send result to 'result' */ saved_error= true; @@ -1531,8 +1562,9 @@ bool st_select_lex_unit::exec() don't let it allocate the join. Perhaps this is because we need some special parameter values passed to join constructor? */ - if (!(fake_select_lex->join= new JOIN(thd, item_list, - fake_select_lex->options, result))) + if (unlikely(!(fake_select_lex->join= + new JOIN(thd, item_list, fake_select_lex->options, + result)))) { fake_select_lex->table_list.empty(); goto err; @@ -1598,7 +1630,7 @@ bool st_select_lex_unit::exec() } fake_select_lex->table_list.empty(); - if (!saved_error) + if (likely(!saved_error)) { thd->limit_found_rows = (ulonglong)table->file->stats.records + add_rows; thd->inc_examined_row_count(examined_rows); @@ -1659,16 +1691,24 @@ bool st_select_lex_unit::exec_recursive() if (!was_executed) save_union_explain(thd->lex->explain); - if ((saved_error= incr_table->file->ha_delete_all_rows())) - goto err; - if (with_element->level == 0) { + if (!incr_table->is_created() && + instantiate_tmp_table(incr_table, + tmp_table_param->keyinfo, + tmp_table_param->start_recinfo, + &tmp_table_param->recinfo, + 0)) + DBUG_RETURN(1); + incr_table->file->extra(HA_EXTRA_WRITE_CACHE); + incr_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); start= first_select(); if (with_element->with_anchor) end= with_element->first_recursive; } - + else if (unlikely((saved_error= incr_table->file->ha_delete_all_rows()))) + goto err; + for (st_select_lex *sl= start ; sl != end; sl= sl->next_select()) { if (with_element->level) @@ -1693,17 +1733,17 @@ bool st_select_lex_unit::exec_recursive() sl->join->exec(); saved_error= sl->join->error; } - if (!saved_error) + if (likely(!saved_error)) { examined_rows+= thd->get_examined_row_count(); thd->set_examined_row_count(0); - if (union_result->flush()) + if (unlikely(union_result->flush())) { thd->lex->current_select= lex_select_save; DBUG_RETURN(1); } } - if (saved_error) + if (unlikely(saved_error)) { thd->lex->current_select= lex_select_save; goto err; @@ -1869,7 +1909,7 @@ bool st_select_lex_unit::change_result(select_result_interceptor *new_result, List<Item> *st_select_lex_unit::get_column_types(bool for_cursor) { SELECT_LEX *sl= first_select(); - bool is_procedure= MY_TEST(sl->join->procedure); + bool is_procedure= !sl->tvc && sl->join->procedure ; if (is_procedure) { @@ -1904,6 +1944,7 @@ bool st_select_lex::cleanup() cleanup_order(order_list.first); cleanup_order(group_list.first); + cleanup_ftfuncs(this); if (join) { @@ -1919,6 +1960,7 @@ bool st_select_lex::cleanup() } inner_refs_list.empty(); exclude_from_table_unique_test= FALSE; + hidden_bit_fields= 0; DBUG_RETURN(error); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 38638d3aa1d..13019cd4359 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -231,7 +231,7 @@ static void prepare_record_for_error_message(int error, TABLE *table) Get the number of the offended index. We will see MAX_KEY if the engine cannot determine the affected index. */ - if ((keynr= table->file->get_dup_key(error)) >= MAX_KEY) + if (unlikely((keynr= table->file->get_dup_key(error)) >= MAX_KEY)) DBUG_VOID_RETURN; /* Create unique_map with all fields used by that index. */ @@ -471,8 +471,8 @@ int mysql_update(THD *thd, set_statistics_for_table(thd, table); select= make_select(table, 0, 0, conds, (SORT_INFO*) 0, 0, &error); - if (error || !limit || thd->is_error() || - (select && select->check_quick(thd, safe_update, limit))) + if (unlikely(error || !limit || thd->is_error() || + (select && select->check_quick(thd, safe_update, limit)))) { query_plan.set_impossible_where(); if (thd->lex->describe || thd->lex->analyze_stmt) @@ -506,7 +506,7 @@ int mysql_update(THD *thd, goto err; } } - if (init_ftfuncs(thd, select_lex, 1)) + if (unlikely(init_ftfuncs(thd, select_lex, 1))) goto err; table->mark_columns_needed_for_update(); @@ -724,7 +724,7 @@ int mysql_update(THD *thd, error= init_read_record_idx(&info, thd, table, 1, query_plan.index, reverse); - if (error) + if (unlikely(error)) { close_cached_file(&tempfile); goto err; @@ -733,7 +733,7 @@ int mysql_update(THD *thd, THD_STAGE_INFO(thd, stage_searching_rows_for_update); ha_rows tmp_limit= limit; - while (!(error=info.read_record()) && !thd->killed) + while (likely(!(error=info.read_record())) && likely(!thd->killed)) { explain->buf_tracker.on_record_read(); thd->inc_examined_row_count(1); @@ -744,8 +744,8 @@ int mysql_update(THD *thd, explain->buf_tracker.on_record_after_where(); table->file->position(table->record[0]); - if (my_b_write(&tempfile,table->file->ref, - table->file->ref_length)) + if (unlikely(my_b_write(&tempfile,table->file->ref, + table->file->ref_length))) { error=1; /* purecov: inspected */ break; /* purecov: inspected */ @@ -763,7 +763,7 @@ int mysql_update(THD *thd, error since in this case the transaction might have been rolled back already. */ - if (error < 0) + if (unlikely(error < 0)) { /* Fatal error from select->skip_record() */ error= 1; @@ -773,7 +773,7 @@ int mysql_update(THD *thd, table->file->unlock_row(); } } - if (thd->killed && !error) + if (unlikely(thd->killed) && !error) error= 1; // Aborted limit= tmp_limit; table->file->try_semi_consistent_read(0); @@ -790,14 +790,15 @@ int mysql_update(THD *thd, } else { - select= new SQL_SELECT; + if (!(select= new SQL_SELECT)) + goto err; select->head=table; } - if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) - error=1; /* purecov: inspected */ - select->file=tempfile; // Read row ptrs from this file - if (error >= 0) + if (unlikely(reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))) + error= 1; /* purecov: inspected */ + select->file= tempfile; // Read row ptrs from this file + if (unlikely(error >= 0)) goto err; table->file->ha_end_keyread(); @@ -831,7 +832,7 @@ update_begin: /* Direct updating is supported */ DBUG_PRINT("info", ("Using direct update")); table->reset_default_fields(); - if (!(error= table->file->ha_direct_update_rows(&updated))) + if (unlikely(!(error= table->file->ha_direct_update_rows(&updated)))) error= -1; found= updated; goto update_end; @@ -942,11 +943,11 @@ update_begin: error= table->file->ha_update_row(table->record[1], table->record[0]); } - if (error == HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error == HA_ERR_RECORD_IS_THE_SAME)) { error= 0; } - else if (!error) + else if (likely(!error)) { if (has_vers_fields && table->versioned()) { @@ -956,14 +957,15 @@ update_begin: error= vers_insert_history_row(table); restore_record(table, record[2]); } - if (!error) + if (likely(!error)) updated_sys_ver++; } - if (!error) + if (likely(!error)) updated++; } - if (error && (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL))) + if (unlikely(error) && + (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL))) { /* If (ignore && error is ignorable) we don't have to @@ -982,8 +984,8 @@ update_begin: } if (table->triggers && - table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, - TRG_ACTION_AFTER, TRUE)) + unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE))) { error= 1; break; @@ -1036,7 +1038,7 @@ update_begin: Don't try unlocking the row if skip_record reported an error since in this case the transaction might have been rolled back already. */ - else if (!thd->is_error()) + else if (likely(!thd->is_error())) table->file->unlock_row(); else { @@ -1044,7 +1046,7 @@ update_begin: break; } thd->get_stmt_da()->inc_current_row_for_warning(); - if (thd->is_error()) + if (unlikely(thd->is_error())) { error= 1; break; @@ -1069,7 +1071,7 @@ update_begin: };); error= (killed_status == NOT_KILLED)? error : 1; - if (error && + if (likely(error) && will_batch && (loc_error= table->file->exec_bulk_update(&dup_key_found))) /* @@ -1127,12 +1129,12 @@ update_end: Sometimes we want to binlog even if we updated no rows, in case user used it to be sure master and slave are in same state. */ - if ((error < 0) || thd->transaction.stmt.modified_non_trans_table) + if (likely(error < 0) || thd->transaction.stmt.modified_non_trans_table) { if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) { int errcode= 0; - if (error < 0) + if (likely(error < 0)) thd->clear_error(); else errcode= query_error_code(thd, killed_status == NOT_KILLED); @@ -1161,7 +1163,7 @@ update_end: id= thd->arg_of_last_insert_id_function ? thd->first_successful_insert_id_in_prev_stmt : 0; - if (error < 0 && !thd->lex->analyze_stmt) + if (likely(error < 0) && likely(!thd->lex->analyze_stmt)) { char buff[MYSQL_ERRMSG_SIZE]; if (!table->versioned(VERS_TIMESTAMP)) @@ -1187,7 +1189,7 @@ update_end: *found_return= found; *updated_return= updated; - if (thd->lex->analyze_stmt) + if (unlikely(thd->lex->analyze_stmt)) goto emit_explain_and_leave; DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0); @@ -1207,7 +1209,7 @@ produce_explain_and_leave: We come here for various "degenerate" query plans: impossible WHERE, no-partitions-used, impossible-range, etc. */ - if (!query_plan.save_explain_update_data(query_plan.mem_root, thd)) + if (unlikely(!query_plan.save_explain_update_data(query_plan.mem_root, thd))) goto err; emit_explain_and_leave: @@ -1863,7 +1865,7 @@ int multi_update::prepare(List<Item> ¬_used_values, bitmap_union(table->read_set, &table->tmp_set); } } - if (error) + if (unlikely(error)) DBUG_RETURN(1); /* @@ -1907,14 +1909,14 @@ int multi_update::prepare(List<Item> ¬_used_values, table_count); values_for_table= (List_item **) thd->alloc(sizeof(List_item *) * table_count); - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(1); for (i=0 ; i < table_count ; i++) { fields_for_table[i]= new List_item; values_for_table[i]= new List_item; } - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(1); /* Split fields into fields_for_table[] and values_by_table[] */ @@ -1926,7 +1928,7 @@ int multi_update::prepare(List<Item> ¬_used_values, fields_for_table[offset]->push_back(item, thd->mem_root); values_for_table[offset]->push_back(value, thd->mem_root); } - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) DBUG_RETURN(1); /* Allocate copy fields */ @@ -2058,7 +2060,8 @@ multi_update::initialize_tables(JOIN *join) TABLE_LIST *table_ref; DBUG_ENTER("initialize_tables"); - if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join)) + if (unlikely((thd->variables.option_bits & OPTION_SAFE_UPDATES) && + error_if_full_join(join))) DBUG_RETURN(1); main_table=join->join_tab->table; table_to_update= 0; @@ -2164,22 +2167,12 @@ loop_end: tbl->prepare_for_position(); join->map2table[tbl->tablenr]->keep_current_rowid= true; - Field_string *field= new Field_string(tbl->file->ref_length, 0, - &field_name, - &my_charset_bin); - if (!field) - DBUG_RETURN(1); - field->init(tbl); - /* - The field will be converted to varstring when creating tmp table if - table to be updated was created by mysql 4.1. Deny this. - */ - field->can_alter_field_type= 0; - Item_field *ifield= new (thd->mem_root) Item_field(join->thd, (Field *) field); - if (!ifield) + Item_temptable_rowid *item= + new (thd->mem_root) Item_temptable_rowid(tbl); + if (!item) DBUG_RETURN(1); - ifield->maybe_null= 0; - if (temp_fields.push_back(ifield, thd->mem_root)) + item->fix_fields(thd, 0); + if (temp_fields.push_back(item, thd->mem_root)) DBUG_RETURN(1); } while ((tbl= tbl_it++)); @@ -2190,10 +2183,10 @@ loop_end: group.direction= ORDER::ORDER_ASC; group.item= (Item**) temp_fields.head_ref(); - tmp_param->quick_group=1; - tmp_param->field_count=temp_fields.elements; - tmp_param->group_parts=1; - tmp_param->group_length= table->file->ref_length; + tmp_param->quick_group= 1; + tmp_param->field_count= temp_fields.elements; + tmp_param->func_count= temp_fields.elements - 1; + calc_group_buffer(tmp_param, &group); /* small table, ignore SQL_BIG_TABLES */ my_bool save_big_tables= thd->variables.big_tables; thd->variables.big_tables= FALSE; @@ -2205,10 +2198,66 @@ loop_end: DBUG_RETURN(1); tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE); } + join->tmp_table_keep_current_rowid= TRUE; DBUG_RETURN(0); } +static TABLE *item_rowid_table(Item *item) +{ + if (item->type() != Item::FUNC_ITEM) + return NULL; + Item_func *func= (Item_func *)item; + if (func->functype() != Item_func::TEMPTABLE_ROWID) + return NULL; + Item_temptable_rowid *itr= (Item_temptable_rowid *)func; + return itr->table; +} + + +/* + multi_update stores a rowid and new field values for every updated row in a + temporary table (one temporary table per updated table). These rowids are + obtained via Item_temptable_rowid's by calling handler::position(). But if + the join is resolved via a temp table, rowids cannot be obtained from + handler::position() in the multi_update::send_data(). So, they're stored in + the join's temp table (JOIN::add_fields_for_current_rowid()) and here we + replace Item_temptable_rowid's (that would've done handler::position()) with + Item_field's (that will simply take the corresponding field value from the + temp table). +*/ +int multi_update::prepare2(JOIN *join) +{ + if (!join->need_tmp || !join->tmp_table_keep_current_rowid) + return 0; + + // there cannot be many tmp tables in multi-update + JOIN_TAB *tmptab= join->join_tab + join->exec_join_tab_cnt(); + + for (Item **it= tmptab->tmp_table_param->items_to_copy; *it ; it++) + { + TABLE *tbl= item_rowid_table(*it); + if (!tbl) + continue; + for (uint i= 0; i < table_count; i++) + { + for (Item **it2= tmp_table_param[i].items_to_copy; *it2; it2++) + { + if (item_rowid_table(*it2) != tbl) + continue; + Item *fld= new (thd->mem_root) + Item_field(thd, (*it)->get_tmp_table_field()); + if (!fld) + return 1; + fld->set_result_field((*it2)->get_tmp_table_field()); + *it2= fld; + } + } + } + return 0; +} + + multi_update::~multi_update() { TABLE_LIST *table; @@ -2295,7 +2344,8 @@ int multi_update::send_data(List<Item> ¬_used_values) { int error; - if (table->default_field && table->update_default_fields(1, ignore)) + if (table->default_field && + unlikely(table->update_default_fields(1, ignore))) DBUG_RETURN(1); if ((error= cur_table->view_check_option(thd, ignore)) != @@ -2304,10 +2354,10 @@ int multi_update::send_data(List<Item> ¬_used_values) found--; if (error == VIEW_CHECK_SKIP) continue; - else if (error == VIEW_CHECK_ERROR) + else if (unlikely(error == VIEW_CHECK_ERROR)) DBUG_RETURN(1); } - if (!updated++) + if (unlikely(!updated++)) { /* Inform the main table that we are going to update the table even @@ -2316,8 +2366,8 @@ int multi_update::send_data(List<Item> ¬_used_values) */ main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE); } - if ((error=table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely((error=table->file->ha_update_row(table->record[1], + table->record[0]))) && error != HA_ERR_RECORD_IS_THE_SAME) { updated--; @@ -2340,7 +2390,7 @@ int multi_update::send_data(List<Item> ¬_used_values) } else { - if (error == HA_ERR_RECORD_IS_THE_SAME) + if (unlikely(error == HA_ERR_RECORD_IS_THE_SAME)) { error= 0; updated--; @@ -2372,55 +2422,42 @@ int multi_update::send_data(List<Item> ¬_used_values) } } if (table->triggers && - table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, - TRG_ACTION_AFTER, TRUE)) + unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE))) DBUG_RETURN(1); } else { int error; TABLE *tmp_table= tmp_tables[offset]; - /* - For updatable VIEW store rowid of the updated table and - rowids of tables used in the CHECK OPTION condition. - */ - uint field_num= 0; - List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables); - /* Set first tbl = table and then tbl to tables from tbl_it */ - TABLE *tbl= table; - do - { - tbl->file->position(tbl->record[0]); - memcpy((char*) tmp_table->field[field_num]->ptr, - (char*) tbl->file->ref, tbl->file->ref_length); - /* - For outer joins a rowid field may have no NOT_NULL_FLAG, - so we have to reset NULL bit for this field. - (set_notnull() resets NULL bit only if available). - */ - tmp_table->field[field_num]->set_notnull(); - field_num++; - } while ((tbl= tbl_it++)); - + if (copy_funcs(tmp_table_param[offset].items_to_copy, thd)) + DBUG_RETURN(1); /* Store regular updated fields in the row. */ + DBUG_ASSERT(1 + unupdated_check_opt_tables.elements == + tmp_table_param[offset].func_count); fill_record(thd, tmp_table, tmp_table->field + 1 + unupdated_check_opt_tables.elements, *values_for_table[offset], TRUE, FALSE); /* Write row, ignoring duplicated updates to a row */ error= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]); - if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE) + found++; + if (unlikely(error)) { - if (error && - create_internal_tmp_table_from_heap(thd, tmp_table, - tmp_table_param[offset].start_recinfo, - &tmp_table_param[offset].recinfo, - error, 1, NULL)) + found--; + if (error != HA_ERR_FOUND_DUPP_KEY && + error != HA_ERR_FOUND_DUPP_UNIQUE) { - do_update= 0; - DBUG_RETURN(1); // Not a table_is_full error + if (create_internal_tmp_table_from_heap(thd, tmp_table, + tmp_table_param[offset].start_recinfo, + &tmp_table_param[offset].recinfo, + error, 1, NULL)) + { + do_update= 0; + DBUG_RETURN(1); // Not a table_is_full error + } + found++; } - found++; } } } @@ -2431,8 +2468,8 @@ int multi_update::send_data(List<Item> ¬_used_values) void multi_update::abort_result_set() { /* the error was handled or nothing deleted and no side effects return */ - if (error_handled || - (!thd->transaction.stmt.modified_non_trans_table && !updated)) + if (unlikely(error_handled || + (!thd->transaction.stmt.modified_non_trans_table && !updated))) return; /* Something already updated so we have to invalidate cache */ @@ -2522,7 +2559,7 @@ int multi_update::do_updates() org_updated= updated; tmp_table= tmp_tables[cur_table->shared]; tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache - if ((local_error= table->file->ha_rnd_init(0))) + if (unlikely((local_error= table->file->ha_rnd_init(0)))) { err_table= table; goto err; @@ -2545,7 +2582,7 @@ int multi_update::do_updates() check_opt_it.rewind(); while(TABLE *tbl= check_opt_it++) { - if ((local_error= tbl->file->ha_rnd_init(1))) + if (unlikely((local_error= tbl->file->ha_rnd_init(1)))) { err_table= tbl; goto err; @@ -2569,7 +2606,7 @@ int multi_update::do_updates() } copy_field_end=copy_field_ptr; - if ((local_error= tmp_table->file->ha_rnd_init(1))) + if (unlikely((local_error= tmp_table->file->ha_rnd_init(1)))) { err_table= tmp_table; goto err; @@ -2584,12 +2621,11 @@ int multi_update::do_updates() thd->fatal_error(); goto err2; } - if ((local_error= tmp_table->file->ha_rnd_next(tmp_table->record[0]))) + if (unlikely((local_error= + tmp_table->file->ha_rnd_next(tmp_table->record[0])))) { if (local_error == HA_ERR_END_OF_FILE) break; - if (local_error == HA_ERR_RECORD_DELETED) - continue; // May happen on dup key err_table= tmp_table; goto err; } @@ -2600,9 +2636,10 @@ int multi_update::do_updates() uint field_num= 0; do { - if ((local_error= - tbl->file->ha_rnd_pos(tbl->record[0], - (uchar *) tmp_table->field[field_num]->ptr))) + uchar *ref= + ((Field_varstring *) tmp_table->field[field_num])->get_data(); + if (unlikely((local_error= + tbl->file->ha_rnd_pos(tbl->record[0], ref)))) { err_table= tbl; goto err; @@ -2611,8 +2648,8 @@ int multi_update::do_updates() } while ((tbl= check_opt_it++)); if (table->vfield && - table->update_virtual_fields(table->file, - VCOL_UPDATE_INDEXED_FOR_UPDATE)) + unlikely(table->update_virtual_fields(table->file, + VCOL_UPDATE_INDEXED_FOR_UPDATE))) goto err2; table->status|= STATUS_UPDATED; @@ -2646,7 +2683,7 @@ int multi_update::do_updates() { if (error == VIEW_CHECK_SKIP) continue; - else if (error == VIEW_CHECK_ERROR) + else if (unlikely(error == VIEW_CHECK_ERROR)) { thd->fatal_error(); goto err2; @@ -2655,8 +2692,9 @@ int multi_update::do_updates() if (has_vers_fields && table->versioned()) table->vers_update_fields(); - if ((local_error=table->file->ha_update_row(table->record[1], - table->record[0])) && + if (unlikely((local_error= + table->file->ha_update_row(table->record[1], + table->record[0]))) && local_error != HA_ERR_RECORD_IS_THE_SAME) { if (!ignore || @@ -2691,8 +2729,8 @@ int multi_update::do_updates() } if (table->triggers && - table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, - TRG_ACTION_AFTER, TRUE)) + unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, TRUE))) goto err2; } @@ -2762,7 +2800,7 @@ bool multi_update::send_eof() error takes into account killed status gained in do_updates() */ int local_error= thd->is_error(); - if (!local_error) + if (likely(!local_error)) local_error = (table_count) ? do_updates() : 0; /* if local_error is not set ON until after do_updates() then @@ -2792,12 +2830,13 @@ bool multi_update::send_eof() thd->transaction.all.m_unsafe_rollback_flags|= (thd->transaction.stmt.m_unsafe_rollback_flags & THD_TRANS::DID_WAIT); - if (local_error == 0 || thd->transaction.stmt.modified_non_trans_table) + if (likely(local_error == 0 || + thd->transaction.stmt.modified_non_trans_table)) { if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) { int errcode= 0; - if (local_error == 0) + if (likely(local_error == 0)) thd->clear_error(); else errcode= query_error_code(thd, killed_status == NOT_KILLED); @@ -2811,23 +2850,25 @@ bool multi_update::send_eof() break; } } - ScopedStatementReplication scoped_stmt_rpl(force_stmt ? thd : NULL); + enum_binlog_format save_binlog_format; + save_binlog_format= thd->get_current_stmt_binlog_format(); + if (force_stmt) + thd->set_current_stmt_binlog_format_stmt(); if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(), thd->query_length(), transactional_tables, FALSE, FALSE, errcode)) - { local_error= 1; // Rollback update - } + thd->set_current_stmt_binlog_format(save_binlog_format); } } - DBUG_ASSERT(trans_safe || !updated || + DBUG_ASSERT(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table); - if (local_error != 0) + if (likely(local_error != 0)) error_handled= TRUE; // to force early leave from ::abort_result_set() - if (local_error > 0) // if the above log write did not fail ... + if (unlikely(local_error > 0)) // if the above log write did not fail ... { /* Safety: If we haven't got an error before (can happen in do_updates) */ my_message(ER_UNKNOWN_ERROR, "An error occurred in multi-table update", diff --git a/sql/sql_view.cc b/sql/sql_view.cc index e910d48c75c..6679334552b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -530,7 +530,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, /* prepare select to resolve all fields */ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; - if (unit->prepare(thd, 0, 0)) + if (unit->prepare(unit->derived, 0, 0)) { /* some errors from prepare are reported to user, if is not then @@ -609,7 +609,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, if (!fld) continue; TABLE_SHARE *s= fld->field->table->s; - const LString_i field_name= fld->field->field_name; + const Lex_ident field_name= fld->field->field_name; if (s->tmp_table || (s->versioned && (field_name.streq(s->vers_start_field()->field_name) || @@ -1333,6 +1333,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, now Lex placed in statement memory */ + table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local; if (!table->view) { @@ -1359,8 +1360,9 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, goto end; lex_start(thd); + lex->stmt_lex= old_lex; view_select= &lex->select_lex; - view_select->select_number= ++thd->stmt_lex->current_select_number; + view_select->select_number= ++thd->lex->stmt_lex->current_select_number; sql_mode_t saved_mode= thd->variables.sql_mode; /* switch off modes which can prevent normal parsing of VIEW @@ -1791,13 +1793,14 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) TABLES we have to simply prohibit dropping of views. */ - if (thd->locked_tables_mode) + if (unlikely(thd->locked_tables_mode)) { my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); DBUG_RETURN(TRUE); } - if (lock_table_names(thd, views, 0, thd->variables.lock_wait_timeout, 0)) + if (unlikely(lock_table_names(thd, views, 0, + thd->variables.lock_wait_timeout, 0))) DBUG_RETURN(TRUE); for (view= views; view; view= view->next_local) @@ -1835,7 +1838,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) } continue; } - if (mysql_file_delete(key_file_frm, path, MYF(MY_WME))) + if (unlikely(mysql_file_delete(key_file_frm, path, MYF(MY_WME)))) error= TRUE; some_views_deleted= TRUE; @@ -1850,12 +1853,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) sp_cache_invalidate(); } - if (wrong_object_name) + if (unlikely(wrong_object_name)) { my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name, "VIEW"); } - if (non_existant_views.length()) + if (unlikely(non_existant_views.length())) { my_error(ER_UNKNOWN_VIEW, MYF(0), non_existant_views.c_ptr_safe()); } @@ -1866,11 +1869,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) /* if something goes wrong, bin-log with possible error code, otherwise bin-log with error code cleared. */ - if (write_bin_log(thd, !something_wrong, thd->query(), thd->query_length())) + if (unlikely(write_bin_log(thd, !something_wrong, thd->query(), + thd->query_length()))) something_wrong= 1; } - if (something_wrong) + if (unlikely(something_wrong)) { DBUG_RETURN(TRUE); } @@ -2038,7 +2042,7 @@ bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view) if ((fld= entry->item->field_for_view_update())) { TABLE_SHARE *s= fld->context->table_list->table->s; - LString_i field_name= fld->field_name; + Lex_ident field_name= fld->field_name; if (s->versioned && (field_name.streq(s->vers_start_field()->field_name) || field_name.streq(s->vers_end_field()->field_name))) diff --git a/sql/sql_window.cc b/sql/sql_window.cc index db34b77ddcb..38fdd8ab80b 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -2799,7 +2799,7 @@ bool compute_window_func(THD *thd, /* Check if we found any error in the window function while adding values through cursors. */ - if (thd->is_error() || thd->is_killed()) + if (unlikely(thd->is_error() || thd->is_killed())) break; @@ -2931,7 +2931,7 @@ bool Window_func_runner::exec(THD *thd, TABLE *tbl, SORT_INFO *filesort_result) bool Window_funcs_sort::exec(JOIN *join) { THD *thd= join->thd; - JOIN_TAB *join_tab= join->join_tab + join->exec_join_tab_cnt(); + JOIN_TAB *join_tab= join->join_tab + join->total_join_tab_cnt(); /* Sort the table based on the most specific sorting criteria of the window functions. */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d69156ced9b..049b2c0cac9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -37,7 +37,7 @@ #include "sql_priv.h" #include "sql_parse.h" /* comp_*_creator */ #include "sql_table.h" /* primary_key_name */ -#include "sql_partition.h" /* mem_alloc_error, partition_info, HASH_PARTITION */ +#include "sql_partition.h" /* partition_info, HASH_PARTITION */ #include "sql_acl.h" /* *_ACL */ #include "sql_class.h" /* Key_part_spec, enum_filetype, Diag_condition_item_name */ #include "slave.h" @@ -67,8 +67,6 @@ #include "lex_token.h" #include "sql_lex.h" #include "sql_sequence.h" -#include "sql_tvc.h" -#include "vers_utils.h" #include "my_base.h" /* this is to get the bison compilation windows warnings out */ @@ -82,7 +80,7 @@ int yylex(void *yylval, void *yythd); #define yyoverflow(A,B,C,D,E,F) \ { \ size_t val= *(F); \ - if (my_yyoverflow((B), (D), &val)) \ + if (unlikely(my_yyoverflow((B), (D), &val))) \ { \ yyerror(thd, (char*) (A)); \ return 2; \ @@ -101,7 +99,7 @@ int yylex(void *yylval, void *yythd); } while (0) #define MYSQL_YYABORT_UNLESS(A) \ - if (!(A)) \ + if (unlikely(!(A))) \ { \ thd->parse_error(); \ MYSQL_YYABORT; \ @@ -342,14 +340,14 @@ bool LEX::set_trigger_new_row(const LEX_CSTRING *name, Item *val) Item_trigger_field::NEW_ROW, name, UPDATE_ACL, FALSE); - if (trg_fld == NULL) + if (unlikely(trg_fld == NULL)) return TRUE; sp_fld= new (thd->mem_root) sp_instr_set_trigger_field(sphead->instructions(), spcont, trg_fld, val, this); - if (sp_fld == NULL) + if (unlikely(sp_fld == NULL)) return TRUE; /* @@ -377,20 +375,25 @@ bool LEX::set_trigger_new_row(const LEX_CSTRING *name, Item *val) @return An Item_splocal object representing the SP variable, or NULL on error. */ Item_splocal* -LEX::create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar, - const char *start_in_q, const char *end_in_q) +LEX::create_item_for_sp_var(const Lex_ident_cli_st *cname, sp_variable *spvar) { const Sp_rcontext_handler *rh; Item_splocal *item; + const char *start_in_q= cname->pos(); + const char *end_in_q= cname->end(); uint pos_in_q, len_in_q; + Lex_ident_sys name(thd, cname); + + if (name.is_null()) + return NULL; // EOM /* If necessary, look for the variable. */ if (spcont && !spvar) - spvar= find_variable(name, &rh); + spvar= find_variable(&name, &rh); if (!spvar) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), name->str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), name.str); return NULL; } @@ -401,7 +404,7 @@ LEX::create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar, len_in_q= (uint)(end_in_q - start_in_q); item= new (thd->mem_root) - Item_splocal(thd, rh, name, spvar->offset, spvar->type_handler(), + Item_splocal(thd, rh, &name, spvar->offset, spvar->type_handler(), pos_in_q, len_in_q); #ifdef DBUG_ASSERT_EXISTS @@ -546,7 +549,8 @@ bool LEX::add_select_to_union_list(bool is_union_distinct, as possible */ if (type == INTERSECT_TYPE && (current_select->linkage != INTERSECT_TYPE && - current_select != current_select->master_unit()->first_select())) + current_select != current_select->master_unit()->first_select()) + && !(thd->variables.sql_mode & MODE_ORACLE)) { /* This and previous SELECTs should go one level down because of @@ -567,11 +571,9 @@ bool LEX::add_select_to_union_list(bool is_union_distinct, return TRUE; mysql_init_select(this); current_select->linkage= type; + current_select->with_all_modifier= !is_union_distinct; if (is_union_distinct) /* UNION DISTINCT - remember position */ - { - current_select->master_unit()->union_distinct= - current_select; - } + current_select->master_unit()->union_distinct= current_select; else DBUG_ASSERT(type == UNION_TYPE); return FALSE; @@ -707,7 +709,7 @@ bool LEX::add_alter_list(const char *name, Virtual_column_info *expr, { MEM_ROOT *mem_root= thd->mem_root; Alter_column *ac= new (mem_root) Alter_column(name, expr, exists); - if (ac == NULL) + if (unlikely(ac == NULL)) return true; alter_info.alter_list.push_back(ac, mem_root); alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; @@ -750,7 +752,7 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) #define bincmp_collation(X,Y) \ do \ { \ - if (Lex->set_bincmp(X,Y)) \ + if (unlikely(Lex->set_bincmp(X,Y))) \ MYSQL_YYABORT; \ } while(0) @@ -758,11 +760,8 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) { Virtual_column_info *v= new (thd->mem_root) Virtual_column_info(); - if (!v) - { - mem_alloc_error(sizeof(Virtual_column_info)); + if (unlikely(!v)) return 0; - } v->expr= expr; v->utf8= 0; /* connection charset */ return v; @@ -778,9 +777,10 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) /* structs */ LEX_CSTRING lex_str; - LEX_SYMBOL symbol; + Lex_ident_cli_st kwd; + Lex_ident_cli_st ident_cli; + Lex_ident_sys_st ident_sys; Lex_string_with_metadata_st lex_string_with_metadata; - Lex_string_with_pos_st lex_string_with_pos; Lex_spblock_st spblock; Lex_spblock_handlers_st spblock_handlers; Lex_length_and_dec_st Lex_length_and_dec; @@ -888,10 +888,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 139 shift/reduce conflicts. + Currently there are 62 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 139 +%expect 62 /* Comments for TOKENS. @@ -911,679 +911,277 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); This makes the code grep-able, and helps maintenance. */ - + + +/* + Reserved keywords and operators +*/ %token ABORT_SYM /* INTERNAL (used in lex) */ %token ACCESSIBLE_SYM -%token ACTION /* SQL-2003-N */ %token ADD /* SQL-2003-R */ -%token ADMIN_SYM /* SQL-2003-N */ -%token ADDDATE_SYM /* MYSQL-FUNC */ -%token AFTER_SYM /* SQL-2003-N */ -%token AGAINST -%token AGGREGATE_SYM -%token ALGORITHM_SYM %token ALL /* SQL-2003-R */ %token ALTER /* SQL-2003-R */ -%token ALWAYS_SYM %token ANALYZE_SYM %token AND_AND_SYM /* OPERATOR */ %token AND_SYM /* SQL-2003-R */ -%token ANY_SYM /* SQL-2003-R */ %token AS /* SQL-2003-R */ %token ASC /* SQL-2003-N */ -%token ASCII_SYM /* MYSQL-FUNC */ %token ASENSITIVE_SYM /* FUTURE-USE */ -%token AT_SYM /* SQL-2003-R */ -%token ATOMIC_SYM /* SQL-2003-R */ -%token AUTHORS_SYM -%token AUTOEXTEND_SIZE_SYM -%token AUTO_INC -%token AUTO_SYM -%token AVG_ROW_LENGTH -%token AVG_SYM /* SQL-2003-N */ -%token BACKUP_SYM %token BEFORE_SYM /* SQL-2003-N */ -%token BEGIN_SYM /* SQL-2003-R */ %token BETWEEN_SYM /* SQL-2003-R */ %token BIGINT /* SQL-2003-R */ %token BINARY /* SQL-2003-R */ -%token BINLOG_SYM %token BIN_NUM %token BIT_AND /* MYSQL-FUNC */ %token BIT_OR /* MYSQL-FUNC */ -%token BIT_SYM /* MYSQL-FUNC */ %token BIT_XOR /* MYSQL-FUNC */ %token BLOB_SYM /* SQL-2003-R */ -%token BLOCK_SYM -%token BODY_SYM /* Oracle-R */ -%token BOOLEAN_SYM /* SQL-2003-R */ -%token BOOL_SYM %token BOTH /* SQL-2003-R */ -%token BTREE_SYM %token BY /* SQL-2003-R */ -%token BYTE_SYM -%token CACHE_SYM %token CALL_SYM /* SQL-2003-R */ %token CASCADE /* SQL-2003-N */ -%token CASCADED /* SQL-2003-R */ %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ -%token CATALOG_NAME_SYM /* SQL-2003-N */ -%token CHAIN_SYM /* SQL-2003-N */ %token CHANGE -%token CHANGED -%token CHARSET %token CHAR_SYM /* SQL-2003-R */ -%token CHECKPOINT_SYM -%token CHECKSUM_SYM %token CHECK_SYM /* SQL-2003-R */ -%token CIPHER_SYM -%token CLASS_ORIGIN_SYM /* SQL-2003-N */ -%token CLIENT_SYM -%token CLOSE_SYM /* SQL-2003-R */ -%token CLOB /* SQL-2003-R */ -%token COALESCE /* SQL-2003-N */ -%token CODE_SYM %token COLLATE_SYM /* SQL-2003-R */ -%token COLLATION_SYM /* SQL-2003-N */ -%token COLUMNS -%token COLUMN_ADD_SYM -%token COLUMN_CHECK_SYM -%token COLUMN_CREATE_SYM -%token COLUMN_DELETE_SYM -%token COLUMN_GET_SYM -%token COLUMN_SYM /* SQL-2003-R */ -%token COLUMN_NAME_SYM /* SQL-2003-N */ -%token COMMENT_SYM -%token COMMITTED_SYM /* SQL-2003-N */ -%token COMMIT_SYM /* SQL-2003-R */ -%token COMPACT_SYM -%token COMPLETION_SYM -%token COMPRESSED_SYM -%token CONCURRENT %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ -%token CONNECTION_SYM -%token CONSISTENT_SYM %token CONSTRAINT /* SQL-2003-R */ -%token CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ -%token CONSTRAINT_NAME_SYM /* SQL-2003-N */ -%token CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ -%token CONTAINS_SYM /* SQL-2003-N */ -%token CONTEXT_SYM %token CONTINUE_SYM /* SQL-2003-R */ -%token CONTRIBUTORS_SYM %token CONVERT_SYM /* SQL-2003-N */ %token COUNT_SYM /* SQL-2003-N */ -%token CPU_SYM %token CREATE /* SQL-2003-R */ %token CROSS /* SQL-2003-R */ -%token CUBE_SYM /* SQL-2003-R */ %token CUME_DIST_SYM %token CURDATE /* MYSQL-FUNC */ -%token CURRENT_SYM /* SQL-2003-R */ %token CURRENT_USER /* SQL-2003-R */ %token CURRENT_ROLE /* SQL-2003-R */ -%token CURRENT_POS_SYM %token CURSOR_SYM /* SQL-2003-R */ -%token CURSOR_NAME_SYM /* SQL-2003-N */ %token CURTIME /* MYSQL-FUNC */ -%token CYCLE_SYM %token DATABASE %token DATABASES -%token DATAFILE_SYM -%token DATA_SYM /* SQL-2003-N */ -%token DATETIME %token DATE_ADD_INTERVAL /* MYSQL-FUNC */ -%token DATE_FORMAT_SYM /* MYSQL-FUNC */ %token DATE_SUB_INTERVAL /* MYSQL-FUNC */ -%token DATE_SYM /* SQL-2003-R */ %token DAY_HOUR_SYM %token DAY_MICROSECOND_SYM %token DAY_MINUTE_SYM %token DAY_SECOND_SYM -%token DAY_SYM /* SQL-2003-R */ -%token DEALLOCATE_SYM /* SQL-2003-R */ %token DECIMAL_NUM %token DECIMAL_SYM /* SQL-2003-R */ %token DECLARE_SYM /* SQL-2003-R */ -%token DECODE_SYM /* Oracle function, non-reserved */ %token DEFAULT /* SQL-2003-R */ -%token DEFINER_SYM -%token DELAYED_SYM -%token DELAY_KEY_WRITE_SYM %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ %token DENSE_RANK_SYM %token DESC /* SQL-2003-N */ %token DESCRIBE /* SQL-2003-R */ -%token DES_KEY_FILE %token DETERMINISTIC_SYM /* SQL-2003-R */ -%token DIAGNOSTICS_SYM /* SQL-2003-N */ -%token DIRECTORY_SYM -%token DISABLE_SYM -%token DISCARD -%token DISK_SYM %token DISTINCT /* SQL-2003-R */ %token DIV_SYM %token DOUBLE_SYM /* SQL-2003-R */ %token DO_DOMAIN_IDS_SYM -%token DO_SYM %token DOT_DOT_SYM %token DROP /* SQL-2003-R */ %token DUAL_SYM -%token DUMPFILE -%token DUPLICATE_SYM -%token DYNAMIC_SYM /* SQL-2003-R */ %token EACH_SYM /* SQL-2003-R */ %token ELSE /* SQL-2003-R */ %token ELSEIF_SYM -%token ELSIF_SYM /* Oracle, reserved in PL/SQL*/ -%token ENABLE_SYM %token ENCLOSED -%token END /* SQL-2003-R */ -%token ENDS_SYM %token END_OF_INPUT /* INTERNAL */ -%token ENGINES_SYM -%token ENGINE_SYM -%token ENUM %token EQUAL_SYM /* OPERATOR */ -%token ERROR_SYM -%token ERRORS %token ESCAPED -%token ESCAPE_SYM /* SQL-2003-R */ -%token EVENTS_SYM -%token EVENT_SYM -%token EVERY_SYM /* SQL-2003-N */ -%token EXCHANGE_SYM -%token EXAMINED_SYM %token EXCEPT_SYM /* SQL-2003-R */ -%token EXCLUDE_SYM /* SQL-2011-N */ -%token EXECUTE_SYM /* SQL-2003-R */ -%token EXCEPTION_SYM /* SQL-2003-N, Oracle-PLSQL-R */ %token EXISTS /* SQL-2003-R */ -%token EXIT_SYM -%token EXPANSION_SYM -%token EXPORT_SYM -%token EXTENDED_SYM -%token EXTENT_SIZE_SYM %token EXTRACT_SYM /* SQL-2003-N */ %token FALSE_SYM /* SQL-2003-R */ -%token FAST_SYM -%token FAULTS_SYM %token FETCH_SYM /* SQL-2003-R */ -%token FILE_SYM %token FIRST_VALUE_SYM /* SQL-2011 */ -%token FIRST_SYM /* SQL-2003-N */ -%token FIXED_SYM %token FLOAT_NUM %token FLOAT_SYM /* SQL-2003-R */ -%token FLUSH_SYM -%token FOLLOWS_SYM /* MYSQL trigger*/ -%token FOLLOWING_SYM /* SQL-2011-N */ -%token FORCE_SYM %token FOREIGN /* SQL-2003-R */ %token FOR_SYM /* SQL-2003-R */ %token FOR_SYSTEM_TIME_SYM /* INTERNAL */ -%token FORMAT_SYM -%token FOUND_SYM /* SQL-2003-R */ %token FROM -%token FULL /* SQL-2003-R */ %token FULLTEXT_SYM -%token FUNCTION_SYM /* SQL-2003-R */ %token GE -%token GENERAL -%token GENERATED_SYM -%token GEOMETRYCOLLECTION -%token GEOMETRY_SYM -%token GET_FORMAT /* MYSQL-FUNC */ -%token GET_SYM /* SQL-2003-R */ -%token GLOBAL_SYM /* SQL-2003-R */ -%token GOTO_SYM /* Oracle, reserved in PL/SQL*/ %token GRANT /* SQL-2003-R */ -%token GRANTS %token GROUP_SYM /* SQL-2003-R */ %token GROUP_CONCAT_SYM %token LAG_SYM /* SQL-2011 */ %token LEAD_SYM /* SQL-2011 */ -%token HANDLER_SYM -%token HARD_SYM -%token HASH_SYM %token HAVING /* SQL-2003-R */ -%token HELP_SYM %token HEX_NUM %token HEX_STRING -%token HIGH_PRIORITY -%token HISTORY_SYM /* MYSQL */ -%token HOST_SYM -%token HOSTS_SYM %token HOUR_MICROSECOND_SYM %token HOUR_MINUTE_SYM %token HOUR_SECOND_SYM -%token HOUR_SYM /* SQL-2003-R */ -%token ID_SYM /* MYSQL */ %token IDENT -%token IDENTIFIED_SYM %token IDENT_QUOTED %token IF_SYM %token IGNORE_DOMAIN_IDS_SYM %token IGNORE_SYM -%token IGNORE_SERVER_IDS_SYM -%token IMMEDIATE_SYM /* SQL-2003-R */ -%token IMPORT -%token INCREMENT_SYM -%token INDEXES %token INDEX_SYM %token INFILE -%token INITIAL_SIZE_SYM %token INNER_SYM /* SQL-2003-R */ %token INOUT_SYM /* SQL-2003-R */ %token INSENSITIVE_SYM /* SQL-2003-R */ %token INSERT /* SQL-2003-R */ -%token INSERT_METHOD -%token INSTALL_SYM %token INTERSECT_SYM /* SQL-2003-R */ %token INTERVAL_SYM /* SQL-2003-R */ %token INTO /* SQL-2003-R */ %token INT_SYM /* SQL-2003-R */ -%token INVOKER_SYM %token IN_SYM /* SQL-2003-R */ -%token IO_SYM -%token IPC_SYM %token IS /* SQL-2003-R */ -%token ISOLATION /* SQL-2003-R */ -%token ISOPEN_SYM /* Oracle-N */ -%token ISSUER_SYM %token ITERATE_SYM -%token INVISIBLE_SYM %token JOIN_SYM /* SQL-2003-R */ -%token JSON_SYM %token KEYS -%token KEY_BLOCK_SIZE %token KEY_SYM /* SQL-2003-N */ %token KILL_SYM -%token LANGUAGE_SYM /* SQL-2003-R */ -%token LAST_SYM /* SQL-2003-N */ -%token LAST_VALUE -%token LASTVAL_SYM /* PostgreSQL sequence function */ %token LE /* OPERATOR */ %token LEADING /* SQL-2003-R */ -%token LEAVES %token LEAVE_SYM %token LEFT /* SQL-2003-R */ -%token LESS_SYM -%token LEVEL_SYM %token LEX_HOSTNAME %token LIKE /* SQL-2003-R */ %token LIMIT %token LINEAR_SYM %token LINES -%token LINESTRING -%token LIST_SYM %token LOAD -%token LOCAL_SYM /* SQL-2003-R */ %token LOCATOR_SYM /* SQL-2003-N */ -%token LOCKS_SYM %token LOCK_SYM -%token LOGFILE_SYM -%token LOGS_SYM %token LONGBLOB %token LONGTEXT %token LONG_NUM %token LONG_SYM %token LOOP_SYM %token LOW_PRIORITY -%token MASTER_CONNECT_RETRY_SYM -%token MASTER_DELAY_SYM -%token MASTER_GTID_POS_SYM -%token MASTER_HOST_SYM -%token MASTER_LOG_FILE_SYM -%token MASTER_LOG_POS_SYM -%token MASTER_PASSWORD_SYM -%token MASTER_PORT_SYM -%token MASTER_SERVER_ID_SYM -%token MASTER_SSL_CAPATH_SYM -%token MASTER_SSL_CA_SYM -%token MASTER_SSL_CERT_SYM -%token MASTER_SSL_CIPHER_SYM -%token MASTER_SSL_CRL_SYM -%token MASTER_SSL_CRLPATH_SYM -%token MASTER_SSL_KEY_SYM -%token MASTER_SSL_SYM %token MASTER_SSL_VERIFY_SERVER_CERT_SYM -%token MASTER_SYM -%token MASTER_USER_SYM -%token MASTER_USE_GTID_SYM -%token MASTER_HEARTBEAT_PERIOD_SYM %token MATCH /* SQL-2003-R */ -%token MAX_CONNECTIONS_PER_HOUR -%token MAX_QUERIES_PER_HOUR -%token MAX_ROWS -%token MAX_SIZE_SYM %token MAX_SYM /* SQL-2003-N */ -%token MAX_UPDATES_PER_HOUR -%token MAX_STATEMENT_TIME_SYM -%token MAX_USER_CONNECTIONS_SYM %token MAXVALUE_SYM /* SQL-2003-N */ %token MEDIAN_SYM %token MEDIUMBLOB %token MEDIUMINT %token MEDIUMTEXT -%token MEDIUM_SYM -%token MEMORY_SYM -%token MERGE_SYM /* SQL-2003-R */ -%token MESSAGE_TEXT_SYM /* SQL-2003-N */ -%token MICROSECOND_SYM /* MYSQL-FUNC */ -%token MIGRATE_SYM %token MINUTE_MICROSECOND_SYM %token MINUTE_SECOND_SYM -%token MINUTE_SYM /* SQL-2003-R */ -%token MINVALUE_SYM -%token MIN_ROWS %token MIN_SYM /* SQL-2003-N */ -%token MODE_SYM %token MODIFIES_SYM /* SQL-2003-R */ -%token MODIFY_SYM %token MOD_SYM /* SQL-2003-N */ -%token MONTH_SYM /* SQL-2003-R */ -%token MULTILINESTRING -%token MULTIPOINT -%token MULTIPOLYGON -%token MUTEX_SYM -%token MYSQL_SYM -%token MYSQL_ERRNO_SYM -%token NAMES_SYM /* SQL-2003-N */ -%token NAME_SYM /* SQL-2003-N */ -%token NATIONAL_SYM /* SQL-2003-R */ +%token MYSQL_CONCAT_SYM /* OPERATOR */ %token NATURAL /* SQL-2003-R */ %token NCHAR_STRING -%token NCHAR_SYM /* SQL-2003-R */ %token NE /* OPERATOR */ %token NEG -%token NEW_SYM /* SQL-2003-R */ -%token NEXT_SYM /* SQL-2003-N */ -%token NEXTVAL_SYM /* PostgreSQL sequence function */ -%token NOCACHE_SYM -%token NOCYCLE_SYM -%token NODEGROUP_SYM -%token NONE_SYM /* SQL-2003-R */ %token NOT2_SYM %token NOT_SYM /* SQL-2003-R */ -%token NOTFOUND_SYM /* Oracle-R */ %token NOW_SYM -%token NO_SYM /* SQL-2003-R */ -%token NOMAXVALUE_SYM -%token NOMINVALUE_SYM -%token NO_WAIT_SYM -%token NOWAIT_SYM %token NO_WRITE_TO_BINLOG %token NTILE_SYM %token NULL_SYM /* SQL-2003-R */ %token NUM -%token NUMBER_SYM /* SQL-2003-N */ %token NUMERIC_SYM /* SQL-2003-R */ %token NTH_VALUE_SYM /* SQL-2011 */ -%token NVARCHAR_SYM -%token OF_SYM /* SQL-1992-R, Oracle-R */ -%token OFFSET_SYM -%token OLD_PASSWORD_SYM %token ON /* SQL-2003-R */ -%token ONE_SYM -%token ONLY_SYM /* SQL-2003-R */ -%token ONLINE_SYM -%token OPEN_SYM /* SQL-2003-R */ %token OPTIMIZE -%token OPTIONS_SYM -%token OPTION /* SQL-2003-N */ %token OPTIONALLY +%token ORACLE_CONCAT_SYM /* INTERNAL */ %token OR2_SYM %token ORDER_SYM /* SQL-2003-R */ -%token OR_OR_SYM /* OPERATOR */ %token OR_SYM /* SQL-2003-R */ -%token OTHERS_SYM /* SQL-2011-N */ %token OUTER %token OUTFILE %token OUT_SYM /* SQL-2003-R */ %token OVER_SYM -%token OWNER_SYM -%token PACKAGE_SYM /* Oracle-R */ -%token PACK_KEYS_SYM -%token PAGE_SYM %token PAGE_CHECKSUM_SYM %token PARAM_MARKER -%token PARSER_SYM %token PARSE_VCOL_EXPR_SYM -%token PARTIAL /* SQL-2003-N */ %token PARTITION_SYM /* SQL-2003-R */ -%token PARTITIONS_SYM -%token PARTITIONING_SYM -%token PASSWORD_SYM %token PERCENT_RANK_SYM %token PERCENTILE_CONT_SYM %token PERCENTILE_DISC_SYM -%token PERIOD_SYM /* SQL-2011-R */ -%token PERSISTENT_SYM -%token PHASE_SYM -%token PLUGINS_SYM -%token PLUGIN_SYM -%token POINT_SYM -%token POLYGON -%token PORT_SYM %token POSITION_SYM /* SQL-2003-N */ -%token PRECEDES_SYM /* MYSQL */ -%token PRECEDING_SYM /* SQL-2011-N */ %token PRECISION /* SQL-2003-R */ -%token PREPARE_SYM /* SQL-2003-R */ -%token PRESERVE_SYM -%token PREV_SYM -%token PREVIOUS_SYM %token PRIMARY_SYM /* SQL-2003-R */ -%token PRIVILEGES /* SQL-2003-N */ %token PROCEDURE_SYM /* SQL-2003-R */ -%token PROCESS -%token PROCESSLIST_SYM -%token PROFILE_SYM -%token PROFILES_SYM -%token PROXY_SYM %token PURGE -%token QUARTER_SYM -%token QUERY_SYM -%token QUICK -%token RAISE_SYM /* Oracle-PLSQL-R */ %token RANGE_SYM /* SQL-2003-R */ %token RANK_SYM -%token RAW /* Oracle */ %token READS_SYM /* SQL-2003-R */ -%token READ_ONLY_SYM %token READ_SYM /* SQL-2003-N */ %token READ_WRITE_SYM %token REAL /* SQL-2003-R */ -%token REBUILD_SYM -%token RECOVER_SYM %token RECURSIVE_SYM -%token REDOFILE_SYM -%token REDO_BUFFER_SIZE_SYM -%token REDUNDANT_SYM +%token REF_SYSTEM_ID_SYM %token REFERENCES /* SQL-2003-R */ %token REGEXP -%token RELAY -%token RELAYLOG_SYM -%token RELAY_LOG_FILE_SYM -%token RELAY_LOG_POS_SYM -%token RELAY_THREAD %token RELEASE_SYM /* SQL-2003-R */ -%token RELOAD -%token REMOVE_SYM %token RENAME -%token REORGANIZE_SYM -%token REPAIR -%token REPEATABLE_SYM /* SQL-2003-N */ %token REPEAT_SYM /* MYSQL-FUNC */ %token REPLACE /* MYSQL-FUNC */ -%token REPLICATION %token REQUIRE_SYM -%token RESET_SYM -%token RESTART_SYM %token RESIGNAL_SYM /* SQL-2003-R */ -%token RESOURCES -%token RESTORE_SYM %token RESTRICT -%token RESUME_SYM -%token RETURNED_SQLSTATE_SYM /* SQL-2003-N */ %token RETURNING_SYM -%token RETURNS_SYM /* SQL-2003-R */ %token RETURN_SYM /* SQL-2003-R */ -%token REUSE_SYM /* Oracle-R */ -%token REVERSE_SYM %token REVOKE /* SQL-2003-R */ %token RIGHT /* SQL-2003-R */ -%token ROLE_SYM -%token ROLLBACK_SYM /* SQL-2003-R */ -%token ROLLUP_SYM /* SQL-2003-R */ -%token ROUTINE_SYM /* SQL-2003-N */ -%token ROWCOUNT_SYM /* Oracle-N */ -%token ROW_SYM /* SQL-2003-R */ %token ROWS_SYM /* SQL-2003-R */ -%token ROWTYPE_SYM /* Oracle-PLSQL-R */ -%token ROW_COUNT_SYM /* SQL-2003-N */ -%token ROW_FORMAT_SYM %token ROW_NUMBER_SYM -%token RTREE_SYM -%token SAVEPOINT_SYM /* SQL-2003-R */ -%token SCHEDULE_SYM -%token SCHEMA_NAME_SYM /* SQL-2003-N */ %token SECOND_MICROSECOND_SYM -%token SECOND_SYM /* SQL-2003-R */ -%token SECURITY_SYM /* SQL-2003-N */ %token SELECT_SYM /* SQL-2003-R */ %token SENSITIVE_SYM /* FUTURE-USE */ %token SEPARATOR_SYM -%token SEQUENCE_SYM -%token SERIALIZABLE_SYM /* SQL-2003-N */ -%token SERIAL_SYM -%token SESSION_SYM /* SQL-2003-N */ -%token SERVER_SYM %token SERVER_OPTIONS %token SET /* SQL-2003-R */ -%token SETVAL_SYM /* PostgreSQL sequence function */ %token SET_VAR -%token SHARE_SYM %token SHIFT_LEFT /* OPERATOR */ %token SHIFT_RIGHT /* OPERATOR */ %token SHOW -%token SHUTDOWN %token SIGNAL_SYM /* SQL-2003-R */ -%token SIGNED_SYM -%token SIMPLE_SYM /* SQL-2003-N */ -%token SLAVE -%token SLAVES -%token SLAVE_POS_SYM -%token SLOW %token SMALLINT /* SQL-2003-R */ -%token SNAPSHOT_SYM -%token SOCKET_SYM -%token SOFT_SYM -%token SONAME_SYM -%token SOUNDS_SYM -%token SOURCE_SYM %token SPATIAL_SYM %token SPECIFIC_SYM /* SQL-2003-R */ %token SQLEXCEPTION_SYM /* SQL-2003-R */ %token SQLSTATE_SYM /* SQL-2003-R */ %token SQLWARNING_SYM /* SQL-2003-R */ %token SQL_BIG_RESULT -%token SQL_BUFFER_RESULT -%token SQL_CACHE_SYM -%token SQL_CALC_FOUND_ROWS -%token SQL_NO_CACHE_SYM %token SQL_SMALL_RESULT %token SQL_SYM /* SQL-2003-R */ -%token SQL_THREAD -%token REF_SYSTEM_ID_SYM %token SSL_SYM %token STARTING -%token STARTS_SYM -%token START_SYM /* SQL-2003-R */ -%token STATEMENT_SYM %token STATS_AUTO_RECALC_SYM %token STATS_PERSISTENT_SYM %token STATS_SAMPLE_PAGES_SYM -%token STATUS_SYM %token STDDEV_SAMP_SYM /* SQL-2003-N */ %token STD_SYM -%token STOP_SYM -%token STORAGE_SYM -%token STORED_SYM %token STRAIGHT_JOIN -%token STRING_SYM -%token SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ -%token SUBDATE_SYM -%token SUBJECT_SYM -%token SUBPARTITIONS_SYM -%token SUBPARTITION_SYM %token SUBSTRING /* SQL-2003-N */ %token SUM_SYM /* SQL-2003-N */ -%token SUPER_SYM -%token SUSPEND_SYM -%token SWAPS_SYM -%token SWITCHES_SYM %token SYSDATE -%token SYSTEM /* SQL-2011-R */ -%token SYSTEM_TIME_SYM /* SQL-2011-R */ -%token TABLES -%token TABLESPACE %token TABLE_REF_PRIORITY %token TABLE_SYM /* SQL-2003-R */ -%token TABLE_CHECKSUM_SYM -%token TABLE_NAME_SYM /* SQL-2003-N */ -%token TEMPORARY /* SQL-2003-N */ -%token TEMPTABLE_SYM %token TERMINATED %token TEXT_STRING -%token TEXT_SYM -%token THAN_SYM %token THEN_SYM /* SQL-2003-R */ -%token TIES_SYM /* SQL-2011-N */ -%token TIMESTAMP /* SQL-2003-R */ -%token TIMESTAMP_ADD -%token TIMESTAMP_DIFF -%token TIME_SYM /* SQL-2003-R */ %token TINYBLOB %token TINYINT %token TINYTEXT %token TO_SYM /* SQL-2003-R */ %token TRAILING /* SQL-2003-R */ -%token TRANSACTION_SYM -%token TRANSACTIONAL_SYM -%token TRIGGERS_SYM %token TRIGGER_SYM /* SQL-2003-R */ %token TRIM /* SQL-2003-N */ -%token TRIM_ORACLE %token TRUE_SYM /* SQL-2003-R */ -%token TRUNCATE_SYM -%token TYPES_SYM -%token TYPE_SYM /* SQL-2003-N */ -%token UDF_RETURNS_SYM %token ULONGLONG_NUM -%token UNBOUNDED_SYM /* SQL-2011-N */ -%token UNCOMMITTED_SYM /* SQL-2003-N */ -%token UNDEFINED_SYM %token UNDERSCORE_CHARSET -%token UNDOFILE_SYM -%token UNDO_BUFFER_SIZE_SYM %token UNDO_SYM /* FUTURE-USE */ -%token UNICODE_SYM -%token UNINSTALL_SYM %token UNION_SYM /* SQL-2003-R */ %token UNIQUE_SYM -%token UNKNOWN_SYM /* SQL-2003-R */ %token UNLOCK_SYM %token UNSIGNED -%token UNTIL_SYM %token UPDATE_SYM /* SQL-2003-R */ -%token UPGRADE_SYM %token USAGE /* SQL-2003-N */ -%token USER_SYM /* SQL-2003-R */ -%token USE_FRM %token USE_SYM %token USING /* SQL-2003-R */ %token UTC_DATE_SYM @@ -1592,80 +1190,595 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token VALUES /* SQL-2003-R */ %token VALUES_IN_SYM %token VALUES_LESS_SYM -%token VALUE_SYM /* SQL-2003-R */ %token VARBINARY %token VARCHAR /* SQL-2003-R */ -%token VARCHAR2 /* Oracle */ -%token VARIABLES %token VARIANCE_SYM %token VARYING /* SQL-2003-R */ %token VAR_SAMP_SYM -%token VERSIONING_SYM /* SQL-2011-R */ -%token VIA_SYM -%token VIEW_SYM /* SQL-2003-N */ -%token VIRTUAL_SYM -%token WAIT_SYM -%token WARNINGS -%token WEEK_SYM -%token WEIGHT_STRING_SYM %token WHEN_SYM /* SQL-2003-R */ %token WHERE /* SQL-2003-R */ -%token WINDOW_SYM %token WHILE_SYM %token WITH /* SQL-2003-R */ -%token WITHIN -%token WITHOUT /* SQL-2003-R */ %token WITH_CUBE_SYM /* INTERNAL */ %token WITH_ROLLUP_SYM /* INTERNAL */ %token WITH_SYSTEM_SYM /* INTERNAL */ -%token WORK_SYM /* SQL-2003-N */ -%token WRAPPER_SYM -%token WRITE_SYM /* SQL-2003-N */ -%token X509_SYM -%token XA_SYM -%token XML_SYM %token XOR %token YEAR_MONTH_SYM -%token YEAR_SYM /* SQL-2003-R */ %token ZEROFILL -%token IMPOSSIBLE_ACTION /* To avoid warning for yyerrlab1 */ +%token IMPOSSIBLE_ACTION /* To avoid warning for yyerrlab1 */ + + +/* + Keywords that have different reserved status in std/oracle modes. +*/ +%token <kwd> BODY_SYM /* Oracle-R */ +%token <kwd> COMMENT_SYM +%token <kwd> ELSIF_SYM /* Oracle, reserved in PL/SQL*/ +%token <kwd> GOTO_SYM /* Oracle, reserved in PL/SQL*/ +%token <kwd> OTHERS_SYM /* SQL-2011-N */ +%token <kwd> PACKAGE_SYM /* Oracle-R */ +%token <kwd> RAISE_SYM /* Oracle-PLSQL-R */ +%token <kwd> ROWTYPE_SYM /* Oracle-PLSQL-R */ + +/* + Non-reserved keywords +*/ + +%token <kwd> ACTION /* SQL-2003-N */ +%token <kwd> ADMIN_SYM /* SQL-2003-N */ +%token <kwd> ADDDATE_SYM /* MYSQL-FUNC */ +%token <kwd> AFTER_SYM /* SQL-2003-N */ +%token <kwd> AGAINST +%token <kwd> AGGREGATE_SYM +%token <kwd> ALGORITHM_SYM +%token <kwd> ALWAYS_SYM +%token <kwd> ANY_SYM /* SQL-2003-R */ +%token <kwd> ASCII_SYM /* MYSQL-FUNC */ +%token <kwd> AT_SYM /* SQL-2003-R */ +%token <kwd> ATOMIC_SYM /* SQL-2003-R */ +%token <kwd> AUTHORS_SYM +%token <kwd> AUTOEXTEND_SIZE_SYM +%token <kwd> AUTO_INC +%token <kwd> AUTO_SYM +%token <kwd> AVG_ROW_LENGTH +%token <kwd> AVG_SYM /* SQL-2003-N */ +%token <kwd> BACKUP_SYM +%token <kwd> BEGIN_SYM /* SQL-2003-R, PLSQL-R */ +%token <kwd> BINLOG_SYM +%token <kwd> BIT_SYM /* MYSQL-FUNC */ +%token <kwd> BLOCK_SYM +%token <kwd> BOOL_SYM +%token <kwd> BOOLEAN_SYM /* SQL-2003-R, PLSQL-R */ +%token <kwd> BTREE_SYM +%token <kwd> BYTE_SYM +%token <kwd> CACHE_SYM +%token <kwd> CASCADED /* SQL-2003-R */ +%token <kwd> CATALOG_NAME_SYM /* SQL-2003-N */ +%token <kwd> CHAIN_SYM /* SQL-2003-N */ +%token <kwd> CHANGED +%token <kwd> CHARSET +%token <kwd> CHECKPOINT_SYM +%token <kwd> CHECKSUM_SYM +%token <kwd> CIPHER_SYM +%token <kwd> CLASS_ORIGIN_SYM /* SQL-2003-N */ +%token <kwd> CLIENT_SYM +%token <kwd> CLOB /* SQL-2003-R */ +%token <kwd> CLOSE_SYM /* SQL-2003-R */ +%token <kwd> COALESCE /* SQL-2003-N */ +%token <kwd> CODE_SYM +%token <kwd> COLLATION_SYM /* SQL-2003-N */ +%token <kwd> COLUMNS +%token <kwd> COLUMN_ADD_SYM +%token <kwd> COLUMN_CHECK_SYM +%token <kwd> COLUMN_CREATE_SYM +%token <kwd> COLUMN_DELETE_SYM +%token <kwd> COLUMN_GET_SYM +%token <kwd> COLUMN_SYM /* SQL-2003-R */ +%token <kwd> COLUMN_NAME_SYM /* SQL-2003-N */ +%token <kwd> COMMITTED_SYM /* SQL-2003-N */ +%token <kwd> COMMIT_SYM /* SQL-2003-R */ +%token <kwd> COMPACT_SYM +%token <kwd> COMPLETION_SYM +%token <kwd> COMPRESSED_SYM +%token <kwd> CONCURRENT +%token <kwd> CONNECTION_SYM +%token <kwd> CONSISTENT_SYM +%token <kwd> CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ +%token <kwd> CONSTRAINT_NAME_SYM /* SQL-2003-N */ +%token <kwd> CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ +%token <kwd> CONTAINS_SYM /* SQL-2003-N */ +%token <kwd> CONTEXT_SYM +%token <kwd> CONTRIBUTORS_SYM +%token <kwd> CPU_SYM +%token <kwd> CUBE_SYM /* SQL-2003-R */ +%token <kwd> CURRENT_SYM /* SQL-2003-R */ +%token <kwd> CURRENT_POS_SYM +%token <kwd> CURSOR_NAME_SYM /* SQL-2003-N */ +%token <kwd> CYCLE_SYM +%token <kwd> DATAFILE_SYM +%token <kwd> DATA_SYM /* SQL-2003-N */ +%token <kwd> DATETIME +%token <kwd> DATE_FORMAT_SYM /* MYSQL-FUNC */ +%token <kwd> DATE_SYM /* SQL-2003-R, Oracle-R, PLSQL-R */ +%token <kwd> DAY_SYM /* SQL-2003-R */ +%token <kwd> DEALLOCATE_SYM /* SQL-2003-R */ +%token <kwd> DECODE_SYM /* Oracle function, non-reserved */ +%token <kwd> DEFINER_SYM +%token <kwd> DELAYED_SYM +%token <kwd> DELAY_KEY_WRITE_SYM +%token <kwd> DES_KEY_FILE +%token <kwd> DIAGNOSTICS_SYM /* SQL-2003-N */ +%token <kwd> DIRECTORY_SYM +%token <kwd> DISABLE_SYM +%token <kwd> DISCARD +%token <kwd> DISK_SYM +%token <kwd> DO_SYM +%token <kwd> DUMPFILE +%token <kwd> DUPLICATE_SYM +%token <kwd> DYNAMIC_SYM /* SQL-2003-R */ +%token <kwd> ENABLE_SYM +%token <kwd> END /* SQL-2003-R, PLSQL-R */ +%token <kwd> ENDS_SYM +%token <kwd> ENGINES_SYM +%token <kwd> ENGINE_SYM +%token <kwd> ENUM +%token <kwd> ERROR_SYM +%token <kwd> ERRORS +%token <kwd> ESCAPE_SYM /* SQL-2003-R */ +%token <kwd> EVENTS_SYM +%token <kwd> EVENT_SYM +%token <kwd> EVERY_SYM /* SQL-2003-N */ +%token <kwd> EXCHANGE_SYM +%token <kwd> EXAMINED_SYM +%token <kwd> EXCLUDE_SYM /* SQL-2011-N */ +%token <kwd> EXECUTE_SYM /* SQL-2003-R */ +%token <kwd> EXCEPTION_SYM /* SQL-2003-N, Oracle-PLSQL-R */ +%token <kwd> EXIT_SYM +%token <kwd> EXPANSION_SYM +%token <kwd> EXPORT_SYM +%token <kwd> EXTENDED_SYM +%token <kwd> EXTENT_SIZE_SYM +%token <kwd> FAST_SYM +%token <kwd> FAULTS_SYM +%token <kwd> FILE_SYM +%token <kwd> FIRST_SYM /* SQL-2003-N */ +%token <kwd> FIXED_SYM +%token <kwd> FLUSH_SYM +%token <kwd> FOLLOWS_SYM /* MYSQL trigger*/ +%token <kwd> FOLLOWING_SYM /* SQL-2011-N */ +%token <kwd> FORCE_SYM +%token <kwd> FORMAT_SYM +%token <kwd> FOUND_SYM /* SQL-2003-R */ +%token <kwd> FULL /* SQL-2003-R */ +%token <kwd> FUNCTION_SYM /* SQL-2003-R */ +%token <kwd> GENERAL +%token <kwd> GENERATED_SYM +%token <kwd> GEOMETRYCOLLECTION +%token <kwd> GEOMETRY_SYM +%token <kwd> GET_FORMAT /* MYSQL-FUNC */ +%token <kwd> GET_SYM /* SQL-2003-R */ +%token <kwd> GLOBAL_SYM /* SQL-2003-R */ +%token <kwd> GRANTS +%token <kwd> HANDLER_SYM +%token <kwd> HARD_SYM +%token <kwd> HASH_SYM +%token <kwd> HELP_SYM +%token <kwd> HIGH_PRIORITY +%token <kwd> HISTORY_SYM /* MYSQL */ +%token <kwd> HOST_SYM +%token <kwd> HOSTS_SYM +%token <kwd> HOUR_SYM /* SQL-2003-R */ +%token <kwd> ID_SYM /* MYSQL */ +%token <kwd> IDENTIFIED_SYM +%token <kwd> IGNORE_SERVER_IDS_SYM +%token <kwd> IMMEDIATE_SYM /* SQL-2003-R */ +%token <kwd> IMPORT +%token <kwd> INCREMENT_SYM +%token <kwd> INDEXES +%token <kwd> INITIAL_SIZE_SYM +%token <kwd> INSERT_METHOD +%token <kwd> INSTALL_SYM +%token <kwd> INVOKER_SYM +%token <kwd> IO_SYM +%token <kwd> IPC_SYM +%token <kwd> ISOLATION /* SQL-2003-R */ +%token <kwd> ISOPEN_SYM /* Oracle-N */ +%token <kwd> ISSUER_SYM +%token <kwd> INVISIBLE_SYM +%token <kwd> JSON_SYM +%token <kwd> KEY_BLOCK_SIZE +%token <kwd> LANGUAGE_SYM /* SQL-2003-R */ +%token <kwd> LAST_SYM /* SQL-2003-N */ +%token <kwd> LAST_VALUE +%token <kwd> LASTVAL_SYM /* PostgreSQL sequence function */ +%token <kwd> LEAVES +%token <kwd> LESS_SYM +%token <kwd> LEVEL_SYM +%token <kwd> LINESTRING +%token <kwd> LIST_SYM +%token <kwd> LOCAL_SYM /* SQL-2003-R */ +%token <kwd> LOCKS_SYM +%token <kwd> LOGFILE_SYM +%token <kwd> LOGS_SYM +%token <kwd> MASTER_CONNECT_RETRY_SYM +%token <kwd> MASTER_DELAY_SYM +%token <kwd> MASTER_GTID_POS_SYM +%token <kwd> MASTER_HOST_SYM +%token <kwd> MASTER_LOG_FILE_SYM +%token <kwd> MASTER_LOG_POS_SYM +%token <kwd> MASTER_PASSWORD_SYM +%token <kwd> MASTER_PORT_SYM +%token <kwd> MASTER_SERVER_ID_SYM +%token <kwd> MASTER_SSL_CAPATH_SYM +%token <kwd> MASTER_SSL_CA_SYM +%token <kwd> MASTER_SSL_CERT_SYM +%token <kwd> MASTER_SSL_CIPHER_SYM +%token <kwd> MASTER_SSL_CRL_SYM +%token <kwd> MASTER_SSL_CRLPATH_SYM +%token <kwd> MASTER_SSL_KEY_SYM +%token <kwd> MASTER_SSL_SYM +%token <kwd> MASTER_SYM +%token <kwd> MASTER_USER_SYM +%token <kwd> MASTER_USE_GTID_SYM +%token <kwd> MASTER_HEARTBEAT_PERIOD_SYM +%token <kwd> MAX_CONNECTIONS_PER_HOUR +%token <kwd> MAX_QUERIES_PER_HOUR +%token <kwd> MAX_ROWS +%token <kwd> MAX_SIZE_SYM +%token <kwd> MAX_UPDATES_PER_HOUR +%token <kwd> MAX_STATEMENT_TIME_SYM +%token <kwd> MAX_USER_CONNECTIONS_SYM +%token <kwd> MEDIUM_SYM +%token <kwd> MEMORY_SYM +%token <kwd> MERGE_SYM /* SQL-2003-R */ +%token <kwd> MESSAGE_TEXT_SYM /* SQL-2003-N */ +%token <kwd> MICROSECOND_SYM /* MYSQL-FUNC */ +%token <kwd> MIGRATE_SYM +%token <kwd> MINUTE_SYM /* SQL-2003-R */ +%token <kwd> MINVALUE_SYM +%token <kwd> MIN_ROWS +%token <kwd> MODE_SYM +%token <kwd> MODIFY_SYM +%token <kwd> MONTH_SYM /* SQL-2003-R */ +%token <kwd> MULTILINESTRING +%token <kwd> MULTIPOINT +%token <kwd> MULTIPOLYGON +%token <kwd> MUTEX_SYM +%token <kwd> MYSQL_SYM +%token <kwd> MYSQL_ERRNO_SYM +%token <kwd> NAMES_SYM /* SQL-2003-N */ +%token <kwd> NAME_SYM /* SQL-2003-N */ +%token <kwd> NATIONAL_SYM /* SQL-2003-R */ +%token <kwd> NCHAR_SYM /* SQL-2003-R */ +%token <kwd> NEW_SYM /* SQL-2003-R */ +%token <kwd> NEXT_SYM /* SQL-2003-N */ +%token <kwd> NEXTVAL_SYM /* PostgreSQL sequence function */ +%token <kwd> NOCACHE_SYM +%token <kwd> NOCYCLE_SYM +%token <kwd> NODEGROUP_SYM +%token <kwd> NONE_SYM /* SQL-2003-R */ +%token <kwd> NOTFOUND_SYM /* Oracle-R */ +%token <kwd> NO_SYM /* SQL-2003-R */ +%token <kwd> NOMAXVALUE_SYM +%token <kwd> NOMINVALUE_SYM +%token <kwd> NO_WAIT_SYM +%token <kwd> NOWAIT_SYM +%token <kwd> NUMBER_SYM /* SQL-2003-N, Oracle-R, PLSQL-R */ +%token <kwd> NVARCHAR_SYM +%token <kwd> OF_SYM /* SQL-1992-R, Oracle-R */ +%token <kwd> OFFSET_SYM +%token <kwd> OLD_PASSWORD_SYM +%token <kwd> ONE_SYM +%token <kwd> ONLY_SYM /* SQL-2003-R */ +%token <kwd> ONLINE_SYM +%token <kwd> OPEN_SYM /* SQL-2003-R */ +%token <kwd> OPTIONS_SYM +%token <kwd> OPTION /* SQL-2003-N */ +%token <kwd> OWNER_SYM +%token <kwd> PACK_KEYS_SYM +%token <kwd> PAGE_SYM +%token <kwd> PARSER_SYM +%token <kwd> PARTIAL /* SQL-2003-N */ +%token <kwd> PARTITIONS_SYM +%token <kwd> PARTITIONING_SYM +%token <kwd> PASSWORD_SYM +%token <kwd> PERIOD_SYM /* SQL-2011-R */ +%token <kwd> PERSISTENT_SYM +%token <kwd> PHASE_SYM +%token <kwd> PLUGINS_SYM +%token <kwd> PLUGIN_SYM +%token <kwd> POINT_SYM +%token <kwd> POLYGON +%token <kwd> PORT_SYM +%token <kwd> PRECEDES_SYM /* MYSQL */ +%token <kwd> PRECEDING_SYM /* SQL-2011-N */ +%token <kwd> PREPARE_SYM /* SQL-2003-R */ +%token <kwd> PRESERVE_SYM +%token <kwd> PREV_SYM +%token <kwd> PREVIOUS_SYM +%token <kwd> PRIVILEGES /* SQL-2003-N */ +%token <kwd> PROCESS +%token <kwd> PROCESSLIST_SYM +%token <kwd> PROFILE_SYM +%token <kwd> PROFILES_SYM +%token <kwd> PROXY_SYM +%token <kwd> QUARTER_SYM +%token <kwd> QUERY_SYM +%token <kwd> QUICK +%token <kwd> RAW /* Oracle-R */ +%token <kwd> READ_ONLY_SYM +%token <kwd> REBUILD_SYM +%token <kwd> RECOVER_SYM +%token <kwd> REDOFILE_SYM +%token <kwd> REDO_BUFFER_SIZE_SYM +%token <kwd> REDUNDANT_SYM +%token <kwd> RELAY +%token <kwd> RELAYLOG_SYM +%token <kwd> RELAY_LOG_FILE_SYM +%token <kwd> RELAY_LOG_POS_SYM +%token <kwd> RELAY_THREAD +%token <kwd> RELOAD +%token <kwd> REMOVE_SYM +%token <kwd> REORGANIZE_SYM +%token <kwd> REPAIR +%token <kwd> REPEATABLE_SYM /* SQL-2003-N */ +%token <kwd> REPLICATION +%token <kwd> RESET_SYM +%token <kwd> RESTART_SYM +%token <kwd> RESOURCES +%token <kwd> RESTORE_SYM +%token <kwd> RESUME_SYM +%token <kwd> RETURNED_SQLSTATE_SYM /* SQL-2003-N */ +%token <kwd> RETURNS_SYM /* SQL-2003-R */ +%token <kwd> REUSE_SYM /* Oracle-R */ +%token <kwd> REVERSE_SYM +%token <kwd> ROLE_SYM +%token <kwd> ROLLBACK_SYM /* SQL-2003-R */ +%token <kwd> ROLLUP_SYM /* SQL-2003-R */ +%token <kwd> ROUTINE_SYM /* SQL-2003-N */ +%token <kwd> ROWCOUNT_SYM /* Oracle-N */ +%token <kwd> ROW_SYM /* SQL-2003-R */ +%token <kwd> ROW_COUNT_SYM /* SQL-2003-N */ +%token <kwd> ROW_FORMAT_SYM +%token <kwd> RTREE_SYM +%token <kwd> SAVEPOINT_SYM /* SQL-2003-R */ +%token <kwd> SCHEDULE_SYM +%token <kwd> SCHEMA_NAME_SYM /* SQL-2003-N */ +%token <kwd> SECOND_SYM /* SQL-2003-R */ +%token <kwd> SECURITY_SYM /* SQL-2003-N */ +%token <kwd> SEQUENCE_SYM +%token <kwd> SERIALIZABLE_SYM /* SQL-2003-N */ +%token <kwd> SERIAL_SYM +%token <kwd> SESSION_SYM /* SQL-2003-N */ +%token <kwd> SERVER_SYM +%token <kwd> SETVAL_SYM /* PostgreSQL sequence function */ +%token <kwd> SHARE_SYM +%token <kwd> SHUTDOWN +%token <kwd> SIGNED_SYM +%token <kwd> SIMPLE_SYM /* SQL-2003-N */ +%token <kwd> SLAVE +%token <kwd> SLAVES +%token <kwd> SLAVE_POS_SYM +%token <kwd> SLOW +%token <kwd> SNAPSHOT_SYM +%token <kwd> SOCKET_SYM +%token <kwd> SOFT_SYM +%token <kwd> SONAME_SYM +%token <kwd> SOUNDS_SYM +%token <kwd> SOURCE_SYM +%token <kwd> SQL_BUFFER_RESULT +%token <kwd> SQL_CACHE_SYM +%token <kwd> SQL_CALC_FOUND_ROWS +%token <kwd> SQL_NO_CACHE_SYM +%token <kwd> SQL_THREAD +%token <kwd> STARTS_SYM +%token <kwd> START_SYM /* SQL-2003-R */ +%token <kwd> STATEMENT_SYM +%token <kwd> STATUS_SYM +%token <kwd> STOP_SYM +%token <kwd> STORAGE_SYM +%token <kwd> STORED_SYM +%token <kwd> STRING_SYM +%token <kwd> SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ +%token <kwd> SUBDATE_SYM +%token <kwd> SUBJECT_SYM +%token <kwd> SUBPARTITIONS_SYM +%token <kwd> SUBPARTITION_SYM +%token <kwd> SUPER_SYM +%token <kwd> SUSPEND_SYM +%token <kwd> SWAPS_SYM +%token <kwd> SWITCHES_SYM +%token <kwd> SYSTEM /* SQL-2011-R */ +%token <kwd> SYSTEM_TIME_SYM /* SQL-2011-R */ +%token <kwd> TABLES +%token <kwd> TABLESPACE +%token <kwd> TABLE_CHECKSUM_SYM +%token <kwd> TABLE_NAME_SYM /* SQL-2003-N */ +%token <kwd> TEMPORARY /* SQL-2003-N */ +%token <kwd> TEMPTABLE_SYM +%token <kwd> TEXT_SYM +%token <kwd> THAN_SYM +%token <kwd> TIES_SYM /* SQL-2011-N */ +%token <kwd> TIMESTAMP /* SQL-2003-R */ +%token <kwd> TIMESTAMP_ADD +%token <kwd> TIMESTAMP_DIFF +%token <kwd> TIME_SYM /* SQL-2003-R, Oracle-R */ +%token <kwd> TRANSACTION_SYM +%token <kwd> TRANSACTIONAL_SYM +%token <kwd> TRIGGERS_SYM +%token <kwd> TRIM_ORACLE +%token <kwd> TRUNCATE_SYM +%token <kwd> TYPES_SYM +%token <kwd> TYPE_SYM /* SQL-2003-N */ +%token <kwd> UDF_RETURNS_SYM +%token <kwd> UNBOUNDED_SYM /* SQL-2011-N */ +%token <kwd> UNCOMMITTED_SYM /* SQL-2003-N */ +%token <kwd> UNDEFINED_SYM +%token <kwd> UNDOFILE_SYM +%token <kwd> UNDO_BUFFER_SIZE_SYM +%token <kwd> UNICODE_SYM +%token <kwd> UNINSTALL_SYM +%token <kwd> UNKNOWN_SYM /* SQL-2003-R */ +%token <kwd> UNTIL_SYM +%token <kwd> UPGRADE_SYM +%token <kwd> USER_SYM /* SQL-2003-R */ +%token <kwd> USE_FRM +%token <kwd> VALUE_SYM /* SQL-2003-R */ +%token <kwd> VARCHAR2 /* Oracle-R, PLSQL-R */ +%token <kwd> VARIABLES +%token <kwd> VERSIONING_SYM /* SQL-2011-R */ +%token <kwd> VIA_SYM +%token <kwd> VIEW_SYM /* SQL-2003-N */ +%token <kwd> VIRTUAL_SYM +%token <kwd> WAIT_SYM +%token <kwd> WARNINGS +%token <kwd> WEEK_SYM +%token <kwd> WEIGHT_STRING_SYM +%token <kwd> WINDOW_SYM /* SQL-2003-R */ +%token <kwd> WITHIN +%token <kwd> WITHOUT /* SQL-2003-R */ +%token <kwd> WORK_SYM /* SQL-2003-N */ +%token <kwd> WRAPPER_SYM +%token <kwd> WRITE_SYM /* SQL-2003-N */ +%token <kwd> X509_SYM +%token <kwd> XA_SYM +%token <kwd> XML_SYM +%token <kwd> YEAR_SYM /* SQL-2003-R */ + %left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT /* A dummy token to force the priority of table_ref production in a join. */ %left TABLE_REF_PRIORITY %left SET_VAR -%left OR_OR_SYM OR_SYM OR2_SYM +%left OR_SYM OR2_SYM %left XOR %left AND_SYM AND_AND_SYM + +%left PREC_BELOW_NOT +%left NOT_SYM + %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE %left '=' EQUAL_SYM GE '>' LE '<' NE IS LIKE REGEXP IN_SYM %left '|' %left '&' %left SHIFT_LEFT SHIFT_RIGHT -%left '-' '+' +%left '-' '+' ORACLE_CONCAT_SYM %left '*' '/' '%' DIV_SYM MOD_SYM %left '^' -%left NEG '~' -%right NOT_SYM NOT2_SYM -%right BINARY COLLATE_SYM -%left INTERVAL_SYM +%left MYSQL_CONCAT_SYM +%left NEG '~' NOT2_SYM BINARY +%left COLLATE_SYM + +/* + Tokens that can change their meaning from identifier to something else + in certain context. + + - TRANSACTION: identifier, history unit: + SELECT transaction FROM t1; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION @var; + + - TIMESTAMP: identifier, literal, history unit: + SELECT timestamp FROM t1; + SELECT TIMESTAMP '2001-01-01 10:20:30'; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TIMESTAMP CONCAT(@date,' ',@time); + + - PERIOD: identifier, period for sytem time: + SELECT period FROM t1; + ALTER TABLE DROP PERIOD FOR SYSTEM TIME; + + - SYSTEM: identifier, system versioning: + SELECT system FROM t1; + ALTER TABLE DROP SYSTEM VERSIONIONG; + + Note, we need here only tokens that cause shirt/reduce conflicts + with keyword identifiers. For example: + opt_clause1: %empty | KEYWORD ... ; + clause2: opt_clause1 ident; + KEYWORD can appear both in opt_clause1 and in "ident" through the "keyword" + rule. So the parser reports a conflict on how to interpret KEYWORD: + - as a start of non-empty branch in opt_clause1, or + - as an identifier which follows the empty branch in opt_clause1. + + Example#1: + alter_list_item: + DROP opt_column opt_if_exists_table_element field_ident + | DROP SYSTEM VERSIONING_SYM + SYSTEM can be a keyword in field_ident, or can be a start of + SYSTEM VERSIONING. + + Example#2: + system_time_expr: AS OF_SYM history_point + history_point: opt_history_unit bit_expr + opt_history_unit: | TRANSACTION_SYM + TRANSACTION can be a non-empty history unit, or can be an identifier + in bit_expr. + + In the grammar below we use %prec to explicitely tell Bison to go + through the empty branch in the optional rule only when the lookahead + token does not belong to a small set of selected tokens. + + Tokens NEXT_SYM and PREVIOUS_SYM also change their meaning from + identifiers to sequence operations when followed by VALUE_SYM: + SELECT NEXT VALUE FOR s1, PREVIOUS VALUE FOR s1; + but we don't need to list them here as they do not seem to cause + conflicts (according to bison -v), as both meanings + (as identifier, and as a sequence operation) are parts of the same target + column_default_non_parenthesized_expr, and there are no any optional + clauses between the start of column_default_non_parenthesized_expr + and until NEXT_SYM / PREVIOUS_SYM. +*/ +%left PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE +%left TRANSACTION_SYM TIMESTAMP PERIOD_SYM SYSTEM + + +/* + Tokens that can appear in a token contraction on the second place + and change the meaning of the previous token. + + - TEXT_STRING: changes the meaning of TIMESTAMP/TIME/DATE + from identifier to literal: + SELECT timestamp FROM t1; + SELECT TIMESTAMP'2001-01-01 00:00:00' FROM t1; + + - Parenthesis: changes the meaning of TIMESTAMP/TIME/DATE + from identifiers to CAST-alike functions: + SELECT timestamp FROM t1; + SELECT timestamp(1) FROM t1; + + - VALUE: changes NEXT and PREVIOUS from identifier to sequence operation: + SELECT next, previous FROM t1; + SELECT NEXT VALUE FOR s1, PREVIOUS VALUE FOR s1; + + - VERSIONING: changes SYSTEM from identifier to SYSTEM VERSIONING + SELECT system FROM t1; + ALTER TABLE t1 ADD SYSTEM VERSIONING; +*/ +%left PREC_BELOW_CONTRACTION_TOKEN2 +%left TEXT_STRING '(' VALUE_SYM VERSIONING_SYM %type <lex_str> - IDENT IDENT_QUOTED DECIMAL_NUM FLOAT_NUM NUM LONG_NUM + DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM HEX_STRING LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident_or_text - IDENT_sys TEXT_STRING_sys TEXT_STRING_literal - opt_component key_cache_name - sp_opt_label BIN_NUM TEXT_STRING_filesystem ident_or_empty - opt_constraint constraint opt_ident ident_table_alias - sp_decl_ident + TEXT_STRING_sys TEXT_STRING_literal + key_cache_name + sp_opt_label BIN_NUM TEXT_STRING_filesystem + opt_constraint constraint opt_ident sp_block_label opt_place opt_db %type <lex_str> - label_ident sp_label +%type <ident_sys> + IDENT_sys + ident + label_ident + sp_decl_ident + ident_or_empty + ident_table_alias + ident_sysvar_name + %type <lex_string_with_metadata> TEXT_STRING NCHAR_STRING @@ -1673,8 +1786,25 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <lex_str_ptr> opt_table_alias -%type <lex_string_with_pos> - ident ident_with_tok_start +%type <ident_cli> + IDENT + IDENT_QUOTED + IDENT_cli + ident_cli + +%type <kwd> + keyword_data_type + keyword_ident + keyword_label + keyword_sp_block_section + keyword_sp_decl + keyword_sp_head + keyword_sp_var_and_label + keyword_sp_var_not_label + keyword_sysvar_name + keyword_sysvar_type + keyword_table_alias + keyword_verb_clause %type <table> table_ident table_ident_nodb references xid @@ -1725,7 +1855,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); opt_default_time_precision case_stmt_body opt_bin_mod opt_for_system_time_clause opt_if_exists_table_element opt_if_not_exists_table_element - opt_recursive opt_format_xid + opt_recursive opt_format_xid %type <object_ddl_options> create_or_replace @@ -1769,6 +1899,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); variable variable_aux bool_pri predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr + primary_expr string_factor_expr mysql_concatenation_expr + select_sublist_qualified_asterisk expr_or_default set_expr_or_default geometry_function signed_literal expr_or_literal opt_escape @@ -1856,10 +1988,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <Lex_length_and_dec> precision opt_precision float_options -%type <symbol> keyword keyword_sp keyword_alias - keyword_sp_data_type - keyword_sp_not_data_type - %type <lex_user> user grant_user grant_role user_or_role current_role admin_option_for_role user_maybe_role @@ -1961,9 +2089,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); vcol_opt_attribute_list vcol_attribute opt_serial_attribute opt_serial_attribute_list serial_attribute explainable_command - opt_lock_wait_timeout + opt_lock_wait_timeout opt_delete_gtid_domain - asrow_attribute + asrow_attribute END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -1984,7 +2112,6 @@ END_OF_INPUT %type <num> sp_decl_idents sp_decl_idents_init_vars %type <num> sp_handler_type sp_hcond_list -%type <num> start_or_end %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value %type <spblock> sp_decls sp_decl sp_decl_body sp_decl_variable_list %type <spname> sp_name @@ -2015,6 +2142,7 @@ END_OF_INPUT %type <spvar_definition> row_field_name row_field_definition %type <spvar_definition_list> row_field_definition_list row_type_body + %type <NONE> opt_window_clause window_def_list window_def window_spec %type <lex_str_ptr> window_name %type <NONE> opt_window_ref opt_window_frame_clause @@ -2025,9 +2153,9 @@ END_OF_INPUT %type <NONE> '-' '+' '*' '/' '%' '(' ')' - ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM + ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM BETWEEN_SYM CASE_SYM THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM - ROLE_SYM + MYSQL_CONCAT_SYM ORACLE_CONCAT_SYM %type <with_clause> opt_with_clause with_clause @@ -2065,8 +2193,8 @@ rule: <-- starts at col 1 query: END_OF_INPUT { - if (!thd->bootstrap && - (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) + if (likely(!thd->bootstrap) && + unlikely(!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) my_yyabort_error((ER_EMPTY_QUERY, MYF(0))); thd->lex->sql_command= SQLCOM_EMPTY_QUERY; @@ -2193,7 +2321,7 @@ prepare: PREPARE_SYM ident FROM prepare_src { LEX *lex= thd->lex; - if (lex->table_or_sp_used()) + if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "PREPARE..FROM")); lex->sql_command= SQLCOM_PREPARE; @@ -2221,7 +2349,7 @@ execute: {} | EXECUTE_SYM IMMEDIATE_SYM prepare_src { - if (Lex->table_or_sp_used()) + if (unlikely(Lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "EXECUTE IMMEDIATE")); Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE; @@ -2235,7 +2363,7 @@ execute_using: | USING { Lex->expr_allows_subselect= false; } execute_var_list { - if (Lex->table_or_sp_used()) + if (unlikely(Lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "EXECUTE..USING")); Lex->expr_allows_subselect= true; @@ -2250,7 +2378,8 @@ execute_var_list: execute_var_ident: expr_or_default { - if (Lex->prepared_stmt_params.push_back($1, thd->mem_root)) + if (unlikely(Lex->prepared_stmt_params.push_back($1, + thd->mem_root))) MYSQL_YYABORT; } ; @@ -2260,7 +2389,7 @@ execute_var_ident: help: HELP_SYM { - if (Lex->sphead) + if (unlikely(Lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HELP")); } ident_or_text @@ -2360,20 +2489,21 @@ master_def: | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal { Lex->mi.heartbeat_period= (float) $3->val_real(); - if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD || - Lex->mi.heartbeat_period < 0.0) + if (unlikely(Lex->mi.heartbeat_period > + SLAVE_MAX_HEARTBEAT_PERIOD) || + unlikely(Lex->mi.heartbeat_period < 0.0)) my_yyabort_error((ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), SLAVE_MAX_HEARTBEAT_PERIOD)); - if (Lex->mi.heartbeat_period > slave_net_timeout) + if (unlikely(Lex->mi.heartbeat_period > slave_net_timeout)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); } - if (Lex->mi.heartbeat_period < 0.001) + if (unlikely(Lex->mi.heartbeat_period < 0.001)) { - if (Lex->mi.heartbeat_period != 0.0) + if (unlikely(Lex->mi.heartbeat_period != 0.0)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN, @@ -2471,19 +2601,19 @@ master_file_def: } | MASTER_USE_GTID_SYM '=' CURRENT_POS_SYM { - if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) + if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_CURRENT_POS; } | MASTER_USE_GTID_SYM '=' SLAVE_POS_SYM { - if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) + if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_SLAVE_POS; } | MASTER_USE_GTID_SYM '=' NO_SYM { - if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) + if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_NO; } @@ -2503,7 +2633,7 @@ connection_name: { Lex->mi.connection_name= $1; #ifdef HAVE_REPLICATION - if (check_master_connection_name(&$1)) + if (unlikely(check_master_connection_name(&$1))) my_yyabort_error((ER_WRONG_ARGUMENTS, MYF(0), "MASTER_CONNECTION_NAME")); #endif } @@ -2516,11 +2646,13 @@ create: { LEX *lex= thd->lex; lex->create_info.init(); - if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4)) + if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, + $1 | $4))) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, + MDL_EXCLUSIVE))) MYSQL_YYABORT; lex->alter_info.reset(); /* @@ -2552,12 +2684,14 @@ create: { LEX *lex= thd->lex; lex->create_info.init(); - if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4)) + if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, + $1 | $4))) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, + MDL_EXCLUSIVE))) MYSQL_YYABORT; /* @@ -2569,15 +2703,15 @@ create: lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; lex->name= null_clex_str; lex->create_last_non_select_table= lex->last_table(); - if (!(lex->create_info.seq_create_info= new (thd->mem_root) - sequence_definition())) + if (unlikely(!(lex->create_info.seq_create_info= + new (thd->mem_root) sequence_definition()))) MYSQL_YYABORT; } opt_sequence opt_create_table_options { LEX *lex= thd->lex; - if (lex->create_info.seq_create_info->check_and_adjust(1)) + if (unlikely(lex->create_info.seq_create_info->check_and_adjust(1))) { my_error(ER_SEQUENCE_INVALID_DATA, MYF(0), lex->select_lex.table_list.first->db.str, @@ -2586,7 +2720,8 @@ create: } /* No fields specified, generate them */ - if (prepare_sequence_fields(thd, &lex->alter_info.create_list)) + if (unlikely(prepare_sequence_fields(thd, + &lex->alter_info.create_list))) MYSQL_YYABORT; /* CREATE SEQUENCE always creates a sequence */ @@ -2594,8 +2729,9 @@ create: Lex->create_info.sequence= 1; lex->current_select= &lex->select_lex; - if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && - !lex->create_info.db_type) + if (unlikely((lex->create_info.used_fields & + HA_CREATE_USED_ENGINE) && + !lex->create_info.db_type)) { lex->create_info.use_default_db_type(thd); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -2610,9 +2746,9 @@ create: opt_key_algorithm_clause ON table_ident { - if (Lex->add_create_index_prepare($8)) + if (unlikely(Lex->add_create_index_prepare($8))) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, $6, $1 | $4)) + if (unlikely(Lex->add_create_index($2, &$5, $6, $1 | $4))) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout normal_key_options @@ -2620,9 +2756,10 @@ create: | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident ON table_ident { - if (Lex->add_create_index_prepare($7)) + if (unlikely(Lex->add_create_index_prepare($7))) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (unlikely(Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, + $1 | $4))) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout fulltext_key_options @@ -2630,9 +2767,10 @@ create: | create_or_replace spatial INDEX_SYM opt_if_not_exists ident ON table_ident { - if (Lex->add_create_index_prepare($7)) + if (unlikely(Lex->add_create_index_prepare($7))) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (unlikely(Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, + $1 | $4))) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout spatial_key_options @@ -2645,15 +2783,17 @@ create: opt_create_database_options { LEX *lex=Lex; - if (lex->set_command_with_check(SQLCOM_CREATE_DB, 0, $1 | $3)) + if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_DB, 0, + $1 | $3))) MYSQL_YYABORT; lex->name= $4; } | create_or_replace definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident { - if (Lex->add_create_view(thd, $1 | $5, - DTYPE_ALGORITHM_UNDEFINED, $3, $6)) + if (unlikely(Lex->add_create_view(thd, $1 | $5, + DTYPE_ALGORITHM_UNDEFINED, $3, + $6))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -2661,7 +2801,7 @@ create: | create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident { - if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7)) + if (unlikely(Lex->add_create_view(thd, $1 | $6, $2, $4, $7))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -2703,13 +2843,15 @@ create: | create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list opt_require_clause opt_resource_options { - if (Lex->set_command_with_check(SQLCOM_CREATE_USER, $1 | $3)) + if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER, + $1 | $3))) MYSQL_YYABORT; } | create_or_replace ROLE_SYM opt_if_not_exists clear_privileges role_list opt_with_admin { - if (Lex->set_command_with_check(SQLCOM_CREATE_ROLE, $1 | $3)) + if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_ROLE, + $1 | $3))) MYSQL_YYABORT; } | CREATE LOGFILE_SYM GROUP_SYM logfile_group_info @@ -2728,7 +2870,7 @@ create: sf_tail_not_aggregate: sf_tail { - if (Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR) + if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)) { my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0))); } @@ -2738,7 +2880,7 @@ sf_tail_not_aggregate: sf_tail_aggregate: sf_tail { - if (!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)) + if (unlikely(!(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR))) { my_yyabort_error((ER_INVALID_AGGREGATE_FUNCTION, MYF(0))); } @@ -2773,105 +2915,105 @@ sequence_def: } | NO_SYM MINVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; } | NOMINVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; } | MAXVALUE_SYM opt_equal longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_max_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_max_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE")); Lex->create_info.seq_create_info->max_value= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; } | NO_SYM MAXVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; } | NOMAXVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; } | START_SYM opt_with longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_start) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_start)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "START")); Lex->create_info.seq_create_info->start= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_start; } | INCREMENT_SYM opt_by longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_increment) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_increment)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "INCREMENT")); Lex->create_info.seq_create_info->increment= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment; } | CACHE_SYM opt_equal longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cache) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cache)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE")); Lex->create_info.seq_create_info->cache= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache; } | NOCACHE_SYM { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cache) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cache)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE")); Lex->create_info.seq_create_info->cache= 0; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache; } | CYCLE_SYM { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cycle) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cycle)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE")); Lex->create_info.seq_create_info->cycle= 1; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle; } | NOCYCLE_SYM { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cycle) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cycle)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE")); Lex->create_info.seq_create_info->cycle= 0; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle; } | RESTART_SYM { - if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE) + if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE)) { thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); YYABORT; } - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_restart) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_restart)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart; } | RESTART_SYM opt_with longlong_num { - if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE) + if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE)) { thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); YYABORT; } - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_restart) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_restart)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART")); Lex->create_info.seq_create_info->restart= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value; @@ -2881,7 +3023,7 @@ sequence_def: server_def: SERVER_SYM opt_if_not_exists ident_or_text { - if (Lex->add_create_options_with_check($2)) + if (unlikely(Lex->add_create_options_with_check($2))) MYSQL_YYABORT; Lex->server_options.reset($3); } @@ -2940,9 +3082,10 @@ event_tail: LEX *lex=Lex; lex->stmt_definition_begin= $1; - if (lex->add_create_options_with_check($2)) + if (unlikely(lex->add_create_options_with_check($2))) MYSQL_YYABORT; - if (!(lex->event_parse_data= Event_parse_data::new_instance(thd))) + if (unlikely(!(lex->event_parse_data= + Event_parse_data::new_instance(thd)))) MYSQL_YYABORT; lex->event_parse_data->identifier= $3; lex->event_parse_data->on_completion= @@ -3005,7 +3148,7 @@ ev_starts: /* empty */ { Item *item= new (thd->mem_root) Item_func_now_local(thd, 0); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; Lex->event_parse_data->item_starts= item; } @@ -3069,11 +3212,12 @@ ev_sql_stmt: (the nested ALTER EVENT can have anything but DO clause) - CREATE PROCEDURE ... BEGIN DROP EVENT ... END| */ - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_EVENT_RECURSION_FORBIDDEN, MYF(0))); - if (!lex->make_sp_head(thd, lex->event_parse_data->identifier, - &sp_handler_procedure)) + if (unlikely(!lex->make_sp_head(thd, + lex->event_parse_data->identifier, + &sp_handler_procedure))) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_ptr()); @@ -3108,12 +3252,12 @@ clear_privileges: sp_name: ident '.' ident { - if (!($$= Lex->make_sp_name(thd, &$1, &$3))) + if (unlikely(!($$= Lex->make_sp_name(thd, &$1, &$3)))) MYSQL_YYABORT; } | ident { - if (!($$= Lex->make_sp_name(thd, &$1))) + if (unlikely(!($$= Lex->make_sp_name(thd, &$1)))) MYSQL_YYABORT; } ; @@ -3166,7 +3310,7 @@ sp_suid: call: CALL_SYM sp_name { - if (Lex->call_statement_start(thd, $2)) + if (unlikely(Lex->call_statement_start(thd, $2))) MYSQL_YYABORT; } opt_sp_cparam_list {} @@ -3208,7 +3352,7 @@ sp_fdparams: sp_param_name: ident { - if (!($$= Lex->sp_param_init(&$1))) + if (unlikely(!($$= Lex->sp_param_init(&$1)))) MYSQL_YYABORT; } ; @@ -3216,32 +3360,35 @@ sp_param_name: sp_param_name_and_type: sp_param_name type_with_opt_collate { - if (Lex->sp_param_fill_definition($$= $1)) + if (unlikely(Lex->sp_param_fill_definition($$= $1))) MYSQL_YYABORT; } | sp_param_name TYPE_SYM OF_SYM ident '.' ident { - if (Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $4, $6)) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, + $$= $1, $4, + $6))) MYSQL_YYABORT; } | sp_param_name TYPE_SYM OF_SYM ident '.' ident '.' ident { - if (Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $4, $6, $8)) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, + $4, $6, $8))) MYSQL_YYABORT; } | sp_param_name ROW_SYM TYPE_SYM OF_SYM ident { - if (Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5)) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5))) MYSQL_YYABORT; } | sp_param_name ROW_SYM TYPE_SYM OF_SYM ident '.' ident { - if (Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5, $7)) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5, $7))) MYSQL_YYABORT; } | sp_param_name ROW_SYM row_type_body { - if (Lex->sphead->spvar_fill_row(thd, $$= $1, $3)) + if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3))) MYSQL_YYABORT; } ; @@ -3313,7 +3460,7 @@ sp_decls: because letting the grammar rules reflect it caused tricky shift/reduce conflicts with the wrong result. (And we get better error handling this way.) */ - if (Lex->sp_declarations_join(&$$, $1, $2)) + if (unlikely(Lex->sp_declarations_join(&$$, $1, $2))) MYSQL_YYABORT; } ; @@ -3326,18 +3473,20 @@ sp_decl: optionally_qualified_column_ident: sp_decl_ident { - if (!($$= new (thd->mem_root) Qualified_column_ident(&$1))) + if (unlikely(!($$= new (thd->mem_root) + Qualified_column_ident(&$1)))) MYSQL_YYABORT; } | sp_decl_ident '.' ident { - if (!($$= new (thd->mem_root) Qualified_column_ident(&$1, &$3))) + if (unlikely(!($$= new (thd->mem_root) + Qualified_column_ident(&$1, &$3)))) MYSQL_YYABORT; } | sp_decl_ident '.' ident '.' ident { - if (!($$= new (thd->mem_root) Qualified_column_ident(thd, - &$1, &$3, &$5))) + if (unlikely(!($$= new (thd->mem_root) + Qualified_column_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } ; @@ -3345,10 +3494,10 @@ optionally_qualified_column_ident: row_field_name: ident { - if (check_string_char_length(&$1, 0, NAME_CHAR_LEN, - system_charset_info, 1)) + if (unlikely(check_string_char_length(&$1, 0, NAME_CHAR_LEN, + system_charset_info, 1))) my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str)); - if (!($$= new (thd->mem_root) Spvar_definition())) + if (unlikely(!($$= new (thd->mem_root) Spvar_definition()))) MYSQL_YYABORT; Lex->init_last_field($$, &$1, thd->variables.collation_database); } @@ -3361,17 +3510,18 @@ row_field_definition: row_field_definition_list: row_field_definition { - if (!($$= new (thd->mem_root) Row_definition_list())) + if (unlikely(!($$= new (thd->mem_root) Row_definition_list())) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); } | row_field_definition_list ',' row_field_definition { uint unused; - if ($1->find_row_field_by_name(&$3->field_name, &unused)) + if (unlikely($1->find_row_field_by_name(&$3->field_name, &unused))) my_yyabort_error((ER_DUP_FIELDNAME, MYF(0), $3->field_name.str)); $$= $1; - $$->push_back($3, thd->mem_root); + if (unlikely($$->push_back($3, thd->mem_root))) + MYSQL_YYABORT; } ; @@ -3391,8 +3541,9 @@ sp_decl_variable_list: type_with_opt_collate sp_opt_default { - if (Lex->sp_variable_declarations_finalize(thd, $1, - &Lex->last_field[0], $3)) + if (unlikely(Lex->sp_variable_declarations_finalize(thd, $1, + &Lex->last_field[0], + $3))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3400,7 +3551,7 @@ sp_decl_variable_list: TYPE_SYM OF_SYM optionally_qualified_column_ident sp_opt_default { - if (Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $4, $5)) + if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $4, $5))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3408,7 +3559,7 @@ sp_decl_variable_list: ROW_SYM TYPE_SYM OF_SYM optionally_qualified_column_ident sp_opt_default { - if (Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $5, $6)) + if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $5, $6))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3416,7 +3567,7 @@ sp_decl_variable_list: ROW_SYM row_type_body sp_opt_default { - if (Lex->sp_variable_declarations_row_finalize(thd, $1, $3, $4)) + if (unlikely(Lex->sp_variable_declarations_row_finalize(thd, $1, $3, $4))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3426,19 +3577,19 @@ sp_decl_body: sp_decl_variable_list | sp_decl_ident CONDITION_SYM FOR_SYM sp_cond { - if (Lex->spcont->declare_condition(thd, &$1, $4)) + if (unlikely(Lex->spcont->declare_condition(thd, &$1, $4))) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } | sp_handler_type HANDLER_SYM FOR_SYM { - if (Lex->sp_handler_declaration_init(thd, $1)) + if (unlikely(Lex->sp_handler_declaration_init(thd, $1))) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt { - if (Lex->sp_handler_declaration_finalize(thd, $1)) + if (unlikely(Lex->sp_handler_declaration_finalize(thd, $1))) MYSQL_YYABORT; $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= 1; @@ -3451,9 +3602,9 @@ sp_decl_body: FOR_SYM sp_cursor_stmt { sp_pcontext *param_ctx= Lex->spcont; - if (Lex->sp_block_finalize(thd)) + if (unlikely(Lex->sp_block_finalize(thd))) MYSQL_YYABORT; - if (Lex->sp_declare_cursor(thd, &$1, $6, param_ctx, true)) + if (unlikely(Lex->sp_declare_cursor(thd, &$1, $6, param_ctx, true))) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; @@ -3469,7 +3620,8 @@ opt_parenthesized_cursor_formal_parameters: sp_cursor_stmt_lex: { DBUG_ASSERT(thd->lex->sphead); - if (!($$= new (thd->mem_root) sp_lex_cursor(thd, thd->lex))) + if (unlikely(!($$= new (thd->mem_root) + sp_lex_cursor(thd, thd->lex)))) MYSQL_YYABORT; } ; @@ -3483,8 +3635,8 @@ sp_cursor_stmt: select { DBUG_ASSERT(Lex == $1); - if ($1->stmt_finalize(thd) || - $1->sphead->restore_lex(thd)) + if (unlikely($1->stmt_finalize(thd)) || + unlikely($1->sphead->restore_lex(thd))) MYSQL_YYABORT; $$= $1; } @@ -3510,7 +3662,7 @@ sp_hcond_element: sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont->parent_context(); - if (ctx->check_duplicate_handler($1)) + if (unlikely(ctx->check_duplicate_handler($1))) my_yyabort_error((ER_SP_DUP_HANDLER, MYF(0))); sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); @@ -3521,10 +3673,10 @@ sp_hcond_element: sp_cond: ulong_num { /* mysql errno */ - if ($1 == 0) + if (unlikely($1 == 0)) my_yyabort_error((ER_WRONG_VALUE, MYF(0), "CONDITION", "0")); $$= new (thd->mem_root) sp_condition_value($1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | sqlstate @@ -3541,10 +3693,11 @@ sqlstate: allowed to SIGNAL, or declare a handler for the completion condition. */ - if (!is_sqlstate_valid(&$3) || is_sqlstate_completion($3.str)) + if (unlikely(!is_sqlstate_valid(&$3) || + is_sqlstate_completion($3.str))) my_yyabort_error((ER_SP_BAD_SQLSTATE, MYF(0), $3.str)); $$= new (thd->mem_root) sp_condition_value($3.str); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3562,25 +3715,25 @@ sp_hcond: | ident /* CONDITION name */ { $$= Lex->spcont->find_condition(&$1, false); - if ($$ == NULL) + if (unlikely($$ == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); } | SQLWARNING_SYM /* SQLSTATEs 01??? */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::WARNING); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | not FOUND_SYM /* SQLSTATEs 02??? */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::NOT_FOUND); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SQLEXCEPTION_SYM /* All other SQLSTATEs */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::EXCEPTION); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3588,7 +3741,7 @@ sp_hcond: signal_stmt: SIGNAL_SYM signal_value opt_set_signal_information { - if (Lex->add_signal_statement(thd, $2)) + if (unlikely(Lex->add_signal_statement(thd, $2))) MYSQL_YYABORT; } ; @@ -3600,12 +3753,12 @@ signal_value: sp_condition_value *cond; /* SIGNAL foo cannot be used outside of stored programs */ - if (lex->spcont == NULL) + if (unlikely(lex->spcont == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); cond= lex->spcont->find_condition(&$1, false); - if (cond == NULL) + if (unlikely(cond == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); - if (cond->type != sp_condition_value::SQLSTATE) + if (unlikely(cond->type != sp_condition_value::SQLSTATE)) my_yyabort_error((ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0))); $$= cond; } @@ -3643,7 +3796,7 @@ signal_information_item_list: Set_signal_information *info; info= &thd->m_parser_state->m_yacc.m_set_signal_info; int index= (int) $3; - if (info->m_item[index] != NULL) + if (unlikely(info->m_item[index] != NULL)) my_yyabort_error((ER_DUP_SIGNAL_SET, MYF(0), Diag_condition_item_names[index].str)); info->m_item[index]= $5; @@ -3661,7 +3814,7 @@ signal_allowed_expr: if ($1->type() == Item::FUNC_ITEM) { Item_func *item= (Item_func*) $1; - if (item->functype() == Item_func::SUSERVAR_FUNC) + if (unlikely(item->functype() == Item_func::SUSERVAR_FUNC)) { /* Don't allow the following syntax: @@ -3709,7 +3862,7 @@ signal_condition_information_item_name: resignal_stmt: RESIGNAL_SYM opt_signal_value opt_set_signal_information { - if (Lex->add_resignal_statement(thd, $2)) + if (unlikely(Lex->add_resignal_statement(thd, $2))) MYSQL_YYABORT; } ; @@ -3724,7 +3877,7 @@ get_diagnostics: Lex->sql_command= SQLCOM_GET_DIAGNOSTICS; Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_get_diagnostics(info); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -3740,13 +3893,13 @@ diagnostics_information: statement_information { $$= new (thd->mem_root) Statement_information($1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CONDITION_SYM condition_number condition_information { $$= new (thd->mem_root) Condition_information($2, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3755,12 +3908,13 @@ statement_information: statement_information_item { $$= new (thd->mem_root) List<Statement_information_item>; - if ($$ == NULL || $$->push_back($1, thd->mem_root)) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; } | statement_information ',' statement_information_item { - if ($1->push_back($3, thd->mem_root)) + if (unlikely($1->push_back($3, thd->mem_root))) MYSQL_YYABORT; $$= $1; } @@ -3770,24 +3924,20 @@ statement_information_item: simple_target_specification '=' statement_information_item_name { $$= new (thd->mem_root) Statement_information_item($3, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } simple_target_specification: - ident + ident_cli { - Lex_input_stream *lip= &thd->m_parser_state->m_lip; - $$= thd->lex->create_item_for_sp_var(&$1, NULL, - lip->get_tok_start(), - lip->get_ptr()); - if ($$ == NULL) + if (unlikely(!($$= thd->lex->create_item_for_sp_var(&$1, NULL)))) MYSQL_YYABORT; } | '@' ident_or_text { $$= new (thd->mem_root) Item_func_get_user_var(thd, &$2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3812,12 +3962,13 @@ condition_information: condition_information_item { $$= new (thd->mem_root) List<Condition_information_item>; - if ($$ == NULL || $$->push_back($1, thd->mem_root)) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; } | condition_information ',' condition_information_item { - if ($1->push_back($3, thd->mem_root)) + if (unlikely($1->push_back($3, thd->mem_root))) MYSQL_YYABORT; $$= $1; } @@ -3827,7 +3978,7 @@ condition_information_item: simple_target_specification '=' condition_information_item_name { $$= new (thd->mem_root) Condition_information_item($3, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } @@ -3861,7 +4012,12 @@ condition_information_item_name: ; sp_decl_ident: - ident { $$= $1; } + IDENT_sys + | keyword_sp_decl + { + if (unlikely($$.copy_ident_cli(thd, &$1))) + MYSQL_YYABORT; + } ; sp_decl_idents: @@ -3872,7 +4028,7 @@ sp_decl_idents: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_variable(&$1, TRUE)) + if (unlikely(spc->find_variable(&$1, TRUE))) my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $1.str)); spc->add_variable(thd, &$1); $$= 1; @@ -3884,7 +4040,7 @@ sp_decl_idents: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_variable(&$3, TRUE)) + if (unlikely(spc->find_variable(&$3, TRUE))) my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $3.str)); spc->add_variable(thd, &$3); $$= $1 + 1; @@ -3933,7 +4089,7 @@ sp_proc_stmt_compound_ok: sp_proc_stmt_if: IF_SYM { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sphead->new_cont_backpatch(NULL); } @@ -3957,7 +4113,7 @@ sp_proc_stmt_statement: sp->m_flags|= sp_get_flags_for_command(lex); /* "USE db" doesn't work in a procedure */ - if (lex->sql_command == SQLCOM_CHANGE_DB) + if (unlikely(lex->sql_command == SQLCOM_CHANGE_DB)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "USE")); /* Don't add an instruction for SET statements, since all @@ -3970,7 +4126,7 @@ sp_proc_stmt_statement: { sp_instr_stmt *i=new (thd->mem_root) sp_instr_stmt(sp->instructions(), lex->spcont, lex); - if (i == NULL) + if (unlikely(i == NULL)) MYSQL_YYABORT; /* @@ -3982,13 +4138,13 @@ sp_proc_stmt_statement: i->m_query.length= lip->get_ptr() - sp->m_tmp_query; else i->m_query.length= lip->get_tok_start() - sp->m_tmp_query;; - if (!(i->m_query.str= strmake_root(thd->mem_root, - sp->m_tmp_query, - i->m_query.length)) || - sp->add_instr(i)) + if (unlikely(!(i->m_query.str= strmake_root(thd->mem_root, + sp->m_tmp_query, + i->m_query.length))) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } - if (sp->restore_lex(thd)) + if (unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -4000,9 +4156,9 @@ sp_proc_stmt_return: { LEX *lex= Lex; sp_head *sp= lex->sphead; - if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, - $3, lex) || - sp->restore_lex(thd)) + if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, + $3, lex)) || + unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -4010,7 +4166,7 @@ sp_proc_stmt_return: sp_proc_stmt_leave: LEAVE_SYM label_ident { - if (Lex->sp_leave_statement(thd, &$2)) + if (unlikely(Lex->sp_leave_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -4018,7 +4174,7 @@ sp_proc_stmt_leave: sp_proc_stmt_iterate: ITERATE_SYM label_ident { - if (Lex->sp_iterate_statement(thd, &$2)) + if (unlikely(Lex->sp_iterate_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -4026,7 +4182,8 @@ sp_proc_stmt_iterate: assignment_source_lex: { DBUG_ASSERT(Lex->sphead); - if (!($$= new (thd->mem_root) sp_assignment_lex(thd, thd->lex))) + if (unlikely(!($$= new (thd->mem_root) + sp_assignment_lex(thd, thd->lex)))) MYSQL_YYABORT; } ; @@ -4044,7 +4201,7 @@ assignment_source_expr: $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, thd->free_list); thd->free_list= NULL; - if ($$->sphead->restore_lex(thd)) + if (unlikely($$->sphead->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -4060,7 +4217,7 @@ for_loop_bound_expr: $$= $1; $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, NULL); - if ($$->sphead->restore_lex(thd)) + if (unlikely($$->sphead->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -4068,7 +4225,7 @@ for_loop_bound_expr: cursor_actual_parameters: assignment_source_expr { - if (!($$= new (thd->mem_root) List<sp_assignment_lex>)) + if (unlikely(!($$= new (thd->mem_root) List<sp_assignment_lex>))) MYSQL_YYABORT; $$->push_back($1, thd->mem_root); } @@ -4087,7 +4244,7 @@ opt_parenthesized_cursor_actual_parameters: sp_proc_stmt_open: OPEN_SYM ident opt_parenthesized_cursor_actual_parameters { - if (Lex->sp_open_cursor(thd, &$2, $3)) + if (unlikely(Lex->sp_open_cursor(thd, &$2, $3))) MYSQL_YYABORT; } ; @@ -4095,17 +4252,17 @@ sp_proc_stmt_open: sp_proc_stmt_fetch_head: FETCH_SYM ident INTO { - if (Lex->sp_add_cfetch(thd, &$2)) + if (unlikely(Lex->sp_add_cfetch(thd, &$2))) MYSQL_YYABORT; } | FETCH_SYM FROM ident INTO { - if (Lex->sp_add_cfetch(thd, &$3)) + if (unlikely(Lex->sp_add_cfetch(thd, &$3))) MYSQL_YYABORT; } | FETCH_SYM NEXT_SYM FROM ident INTO { - if (Lex->sp_add_cfetch(thd, &$4)) + if (unlikely(Lex->sp_add_cfetch(thd, &$4))) MYSQL_YYABORT; } ; @@ -4120,8 +4277,8 @@ sp_proc_stmt_fetch: sp_instr_agg_cfetch *i= new (thd->mem_root) sp_instr_agg_cfetch(sp->instructions(), lex->spcont); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } ; @@ -4134,12 +4291,12 @@ sp_proc_stmt_close: uint offset; sp_instr_cclose *i; - if (! lex->spcont->find_cursor(&$2, &offset, false)) + if (unlikely(!lex->spcont->find_cursor(&$2, &offset, false))) my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $2.str)); i= new (thd->mem_root) sp_instr_cclose(sp->instructions(), lex->spcont, offset); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } ; @@ -4152,7 +4309,7 @@ sp_fetch_list: sp_pcontext *spc= lex->spcont; sp_variable *spv; - if (!spc || !(spv = spc->find_variable(&$1, false))) + if (unlikely(!spc || !(spv = spc->find_variable(&$1, false)))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str)); /* An SP local variable */ @@ -4166,7 +4323,7 @@ sp_fetch_list: sp_pcontext *spc= lex->spcont; sp_variable *spv; - if (!spc || !(spv = spc->find_variable(&$3, false))) + if (unlikely(!spc || !(spv = spc->find_variable(&$3, false)))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $3.str)); /* An SP local variable */ @@ -4185,12 +4342,12 @@ sp_if: uint ip= sp->instructions(); sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(ip, ctx, $2, lex); - if (i == NULL || - sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)) || - sp->add_cont_backpatch(i) || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0))) || + unlikely(sp->add_cont_backpatch(i)) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; - if (sp->restore_lex(thd)) + if (unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } sp_proc_stmts1 @@ -4199,8 +4356,8 @@ sp_if: sp_pcontext *ctx= Lex->spcont; uint ip= sp->instructions(); sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, ctx); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; sp->backpatch(ctx->pop_label()); sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)); @@ -4222,7 +4379,7 @@ sp_elseifs: case_stmt_specification: CASE_SYM { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; /** @@ -4293,10 +4450,9 @@ case_stmt_body: { Lex->sphead->reset_lex(thd); /* For expr $2 */ } expr { - if (Lex->case_stmt_action_expr($2)) + if (unlikely(Lex->case_stmt_action_expr($2))) MYSQL_YYABORT; - - if (Lex->sphead->restore_lex(thd)) + if (unlikely(Lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } simple_when_clause_list @@ -4325,16 +4481,16 @@ simple_when_clause: /* Simple case: <caseval> = <whenval> */ LEX *lex= Lex; - if (lex->case_stmt_action_when($3, true)) + if (unlikely(lex->case_stmt_action_when($3, true))) MYSQL_YYABORT; /* For expr $3 */ - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } THEN_SYM sp_proc_stmts1 { - if (Lex->case_stmt_action_then()) + if (unlikely(Lex->case_stmt_action_then())) MYSQL_YYABORT; } ; @@ -4347,16 +4503,16 @@ searched_when_clause: expr { LEX *lex= Lex; - if (lex->case_stmt_action_when($3, false)) + if (unlikely(lex->case_stmt_action_when($3, false))) MYSQL_YYABORT; /* For expr $3 */ - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } THEN_SYM sp_proc_stmts1 { - if (Lex->case_stmt_action_then()) + if (unlikely(Lex->case_stmt_action_then())) MYSQL_YYABORT; } ; @@ -4369,8 +4525,8 @@ else_clause_opt: uint ip= sp->instructions(); sp_instr_error *i= new (thd->mem_root) sp_instr_error(ip, lex->spcont, ER_SP_CASE_NOT_FOUND); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } | ELSE sp_proc_stmts1 @@ -4388,7 +4544,7 @@ sp_opt_label: sp_block_label: sp_label { - if (Lex->spcont->block_label_declare(&$1)) + if (unlikely(Lex->spcont->block_label_declare(&$1))) MYSQL_YYABORT; $$= $1; } @@ -4405,7 +4561,7 @@ sp_labeled_block: END sp_opt_label { - if (Lex->sp_block_finalize(thd, $4, &$7)) + if (unlikely(Lex->sp_block_finalize(thd, $4, &$7))) MYSQL_YYABORT; } ; @@ -4419,7 +4575,7 @@ sp_unlabeled_block: sp_proc_stmts END { - if (Lex->sp_block_finalize(thd, $3)) + if (unlikely(Lex->sp_block_finalize(thd, $3))) MYSQL_YYABORT; } ; @@ -4427,7 +4583,7 @@ sp_unlabeled_block: sp_unlabeled_block_not_atomic: BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sp_block_init(thd); } @@ -4435,7 +4591,7 @@ sp_unlabeled_block_not_atomic: sp_proc_stmts END { - if (Lex->sp_block_finalize(thd, $5)) + if (unlikely(Lex->sp_block_finalize(thd, $5))) MYSQL_YYABORT; } ; @@ -4449,7 +4605,7 @@ opt_sp_for_loop_direction: sp_for_loop_index_and_bounds: ident sp_for_loop_bounds { - if (Lex->sp_for_loop_declarations(thd, &$$, &$1, $2)) + if (unlikely(Lex->sp_for_loop_declarations(thd, &$$, &$1, $2))) MYSQL_YYABORT; } ; @@ -4472,7 +4628,8 @@ sp_for_loop_bounds: } | IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')' { - if (Lex->sp_for_loop_implicit_cursor_statement(thd, &$$, $4)) + if (unlikely(Lex->sp_for_loop_implicit_cursor_statement(thd, &$$, + $4))) MYSQL_YYABORT; } ; @@ -4485,8 +4642,8 @@ loop_body: sp_label *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, lex->spcont, lab->ip); - if (i == NULL || - lex->sphead->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(lex->sphead->add_instr(i))) MYSQL_YYABORT; } ; @@ -4495,14 +4652,14 @@ while_body: expr DO_SYM { LEX *lex= Lex; - if (lex->sp_while_loop_expression(thd, $1)) + if (unlikely(lex->sp_while_loop_expression(thd, $1))) MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } sp_proc_stmts1 END WHILE_SYM { - if (Lex->sp_while_loop_finalize(thd)) + if (unlikely(Lex->sp_while_loop_finalize(thd))) MYSQL_YYABORT; } ; @@ -4517,10 +4674,10 @@ repeat_body: sp_label *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(ip, lex->spcont, $4, lab->ip, lex); - if (i == NULL || - lex->sphead->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(lex->sphead->add_instr(i))) MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; /* We can shortcut the cont_backpatch here */ i->m_cont_dest= ip+1; @@ -4530,7 +4687,7 @@ repeat_body: pop_sp_loop_label: sp_opt_label { - if (Lex->sp_pop_loop_label(thd, &$1)) + if (unlikely(Lex->sp_pop_loop_label(thd, &$1))) MYSQL_YYABORT; } ; @@ -4538,14 +4695,14 @@ pop_sp_loop_label: sp_labeled_control: sp_label LOOP_SYM { - if (Lex->sp_push_loop_label(thd, &$1)) + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; } loop_body pop_sp_loop_label { } | sp_label WHILE_SYM { - if (Lex->sp_push_loop_label(thd, &$1)) + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); } @@ -4558,28 +4715,28 @@ sp_labeled_control: } sp_for_loop_index_and_bounds { - if (Lex->sp_push_loop_label(thd, &$1)) // The inner WHILE block + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) // The inner WHILE block MYSQL_YYABORT; - if (Lex->sp_for_loop_condition_test(thd, $4)) + if (unlikely(Lex->sp_for_loop_condition_test(thd, $4))) MYSQL_YYABORT; } DO_SYM sp_proc_stmts1 END FOR_SYM { - if (Lex->sp_for_loop_finalize(thd, $4)) + if (unlikely(Lex->sp_for_loop_finalize(thd, $4))) MYSQL_YYABORT; } pop_sp_loop_label // The inner WHILE block { Lex_spblock tmp; tmp.curs= MY_TEST($4.m_implicit_cursor); - if (Lex->sp_block_finalize(thd, tmp)) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END MYSQL_YYABORT; } | sp_label REPEAT_SYM { - if (Lex->sp_push_loop_label(thd, &$1)) + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; } repeat_body pop_sp_loop_label @@ -4589,7 +4746,7 @@ sp_labeled_control: sp_unlabeled_control: LOOP_SYM { - if (Lex->sp_push_loop_empty_label(thd)) + if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; } loop_body @@ -4598,7 +4755,7 @@ sp_unlabeled_control: } | WHILE_SYM { - if (Lex->sp_push_loop_empty_label(thd)) + if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); } @@ -4609,15 +4766,15 @@ sp_unlabeled_control: | FOR_SYM { // See "The FOR LOOP statement" comments in sql_lex.cc - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block } sp_for_loop_index_and_bounds { - if (Lex->sp_push_loop_empty_label(thd)) // The inner WHILE block + if (unlikely(Lex->sp_push_loop_empty_label(thd))) // The inner WHILE block MYSQL_YYABORT; - if (Lex->sp_for_loop_condition_test(thd, $3)) + if (unlikely(Lex->sp_for_loop_condition_test(thd, $3))) MYSQL_YYABORT; } DO_SYM @@ -4626,15 +4783,15 @@ sp_unlabeled_control: { Lex_spblock tmp; tmp.curs= MY_TEST($3.m_implicit_cursor); - if (Lex->sp_for_loop_finalize(thd, $3)) + if (unlikely(Lex->sp_for_loop_finalize(thd, $3))) MYSQL_YYABORT; Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block - if (Lex->sp_block_finalize(thd, tmp)) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END MYSQL_YYABORT; } | REPEAT_SYM { - if (Lex->sp_push_loop_empty_label(thd)) + if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; } repeat_body @@ -4853,7 +5010,7 @@ tablespace_name: LEX *lex= Lex; lex->alter_tablespace_info= (new (thd->mem_root) st_alter_tablespace()); - if (lex->alter_tablespace_info == NULL) + if (unlikely(lex->alter_tablespace_info == NULL)) MYSQL_YYABORT; lex->alter_tablespace_info->tablespace_name= $1.str; lex->sql_command= SQLCOM_ALTER_TABLESPACE; @@ -4866,7 +5023,7 @@ logfile_group_name: LEX *lex= Lex; lex->alter_tablespace_info= (new (thd->mem_root) st_alter_tablespace()); - if (lex->alter_tablespace_info == NULL) + if (unlikely(lex->alter_tablespace_info == NULL)) MYSQL_YYABORT; lex->alter_tablespace_info->logfile_group_name= $1.str; lex->sql_command= SQLCOM_ALTER_TABLESPACE; @@ -4943,7 +5100,7 @@ opt_ts_nodegroup: NODEGROUP_SYM opt_equal real_ulong_num { LEX *lex= Lex; - if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP) + if (unlikely(lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP")); lex->alter_tablespace_info->nodegroup_id= $3; } @@ -4953,7 +5110,7 @@ opt_ts_comment: COMMENT_SYM opt_equal TEXT_STRING_sys { LEX *lex= Lex; - if (lex->alter_tablespace_info->ts_comment != NULL) + if (unlikely(lex->alter_tablespace_info->ts_comment != NULL)) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT")); lex->alter_tablespace_info->ts_comment= $3.str; } @@ -4963,7 +5120,7 @@ opt_ts_engine: opt_storage ENGINE_SYM opt_equal storage_engines { LEX *lex= Lex; - if (lex->alter_tablespace_info->storage_engine != NULL) + if (unlikely(lex->alter_tablespace_info->storage_engine != NULL)) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE, MYF(0), "STORAGE ENGINE")); lex->alter_tablespace_info->storage_engine= $4; @@ -4984,7 +5141,7 @@ ts_wait: | NO_WAIT_SYM { LEX *lex= Lex; - if (!(lex->alter_tablespace_info->wait_until_completed)) + if (unlikely(!(lex->alter_tablespace_info->wait_until_completed))) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT")); lex->alter_tablespace_info->wait_until_completed= FALSE; } @@ -4994,34 +5151,8 @@ size_number: real_ulonglong_num { $$= $1;} | IDENT_sys { - ulonglong number; - uint text_shift_number= 0; - longlong prefix_number; - const char *start_ptr= $1.str; - size_t str_len= $1.length; - const char *end_ptr= start_ptr + str_len; - int error; - prefix_number= my_strtoll10(start_ptr, (char**) &end_ptr, &error); - if ((start_ptr + str_len - 1) == end_ptr) - { - switch (end_ptr[0]) - { - case 'g': - case 'G': text_shift_number+=30; break; - case 'm': - case 'M': text_shift_number+=20; break; - case 'k': - case 'K': text_shift_number+=10; break; - default: - my_yyabort_error((ER_WRONG_SIZE_NUMBER, MYF(0))); - } - if (prefix_number >> 31) - my_yyabort_error((ER_SIZE_OVERFLOW_ERROR, MYF(0))); - number= prefix_number << text_shift_number; - } - else - my_yyabort_error((ER_WRONG_SIZE_NUMBER, MYF(0))); - $$= number; + if ($1.to_size_number(&$$)) + MYSQL_YYABORT; } ; @@ -5050,7 +5181,7 @@ create_body: Lex->create_info.add(DDL_options_st::OPT_LIKE); TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd, $1, NULL, 0, TL_READ, MDL_SHARED_READ); - if (! src_table) + if (unlikely(! src_table)) MYSQL_YYABORT; /* CREATE TABLE ... LIKE is not allowed for views. */ src_table->required_type= TABLE_TYPE_NORMAL; @@ -5134,11 +5265,8 @@ partitioning: { LEX *lex= Lex; lex->part_info= new (thd->mem_root) partition_info(); - if (!lex->part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!lex->part_info)) MYSQL_YYABORT; - } if (lex->sql_command == SQLCOM_ALTER_TABLE) { lex->alter_info.partition_flags|= ALTER_PARTITION_INFO; @@ -5152,7 +5280,7 @@ have_partitioning: { #ifdef WITH_PARTITION_STORAGE_ENGINE LEX_CSTRING partition_name={STRING_WITH_LEN("partition")}; - if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN)) + if (unlikely(!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))) my_yyabort_error((ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-partition")); #else @@ -5165,7 +5293,7 @@ have_partitioning: partition_entry: PARTITION_SYM { - if (!Lex->part_info) + if (unlikely(!Lex->part_info)) { thd->parse_error(ER_PARTITION_ENTRY_ERROR); MYSQL_YYABORT; @@ -5212,7 +5340,10 @@ part_type_def: | LIST_SYM part_column_list { Lex->part_info->part_type= LIST_PARTITION; } | SYSTEM_TIME_SYM - { if (Lex->part_info->vers_init_info(thd)) MYSQL_YYABORT; } + { + if (unlikely(Lex->part_info->vers_init_info(thd))) + MYSQL_YYABORT; + } opt_versioning_rotation ; @@ -5256,12 +5387,10 @@ part_field_item: { partition_info *part_info= Lex->part_info; part_info->num_columns++; - if (part_info->part_field_list.push_back($1.str, thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(part_info->part_field_list.push_back($1.str, + thd->mem_root))) MYSQL_YYABORT; - } - if (part_info->num_columns > MAX_REF_PARTS) + if (unlikely(part_info->num_columns > MAX_REF_PARTS)) my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), "list of partition fields")); } @@ -5281,8 +5410,8 @@ part_func: '(' remember_name part_func_expr remember_end ')' { partition_info *part_info= Lex->part_info; - if (part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE)) - { MYSQL_YYABORT; } + if (unlikely(part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE))) + MYSQL_YYABORT; part_info->num_columns= 1; part_info->column_list= FALSE; } @@ -5291,8 +5420,8 @@ part_func: sub_part_func: '(' remember_name part_func_expr remember_end ')' { - if (Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE)) - { MYSQL_YYABORT; } + if (unlikely(Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE))) + MYSQL_YYABORT; } ; @@ -5303,7 +5432,7 @@ opt_num_parts: { uint num_parts= $2; partition_info *part_info= Lex->part_info; - if (num_parts == 0) + if (unlikely(num_parts == 0)) my_yyabort_error((ER_NO_PARTS_ERROR, MYF(0), "partitions")); part_info->num_parts= num_parts; @@ -5335,12 +5464,11 @@ sub_part_field_item: ident { partition_info *part_info= Lex->part_info; - if (part_info->subpart_field_list.push_back($1.str, thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(part_info->subpart_field_list.push_back($1.str, + thd->mem_root))) MYSQL_YYABORT; - } - if (part_info->subpart_field_list.elements > MAX_REF_PARTS) + + if (unlikely(part_info->subpart_field_list.elements > MAX_REF_PARTS)) my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), "list of subpartition fields")); } @@ -5349,7 +5477,7 @@ sub_part_field_item: part_func_expr: bit_expr { - if (!Lex->safe_to_cache_query) + if (unlikely(!Lex->safe_to_cache_query)) { thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); MYSQL_YYABORT; @@ -5364,7 +5492,7 @@ opt_num_subparts: { uint num_parts= $2; LEX *lex= Lex; - if (num_parts == 0) + if (unlikely(num_parts == 0)) my_yyabort_error((ER_NO_PARTS_ERROR, MYF(0), "subpartitions")); lex->part_info->num_subparts= num_parts; lex->part_info->use_default_num_subpartitions= FALSE; @@ -5375,10 +5503,10 @@ part_defs: /* empty */ { partition_info *part_info= Lex->part_info; - if (part_info->part_type == RANGE_PARTITION) + if (unlikely(part_info->part_type == RANGE_PARTITION)) my_yyabort_error((ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "RANGE")); - if (part_info->part_type == LIST_PARTITION) + if (unlikely(part_info->part_type == LIST_PARTITION)) my_yyabort_error((ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "LIST")); } @@ -5388,8 +5516,8 @@ part_defs: uint count_curr_parts= part_info->partitions.elements; if (part_info->num_parts != 0) { - if (part_info->num_parts != - count_curr_parts) + if (unlikely(part_info->num_parts != + count_curr_parts)) { thd->parse_error(ER_PARTITION_WRONG_NO_PART_ERROR); MYSQL_YYABORT; @@ -5414,12 +5542,10 @@ part_definition: partition_info *part_info= Lex->part_info; partition_element *p_elem= new (thd->mem_root) partition_element(); - if (!p_elem || - part_info->partitions.push_back(p_elem, thd->mem_root)) - { - mem_alloc_error(sizeof(partition_element)); + if (unlikely(!p_elem) || + unlikely(part_info->partitions.push_back(p_elem, thd->mem_root))) MYSQL_YYABORT; - } + p_elem->part_state= PART_NORMAL; p_elem->id= part_info->partitions.elements - 1; part_info->curr_part_elem= p_elem; @@ -5439,7 +5565,7 @@ part_name: { partition_info *part_info= Lex->part_info; partition_element *p_elem= part_info->curr_part_elem; - if (check_ident_length(&$1)) + if (unlikely(check_ident_length(&$1))) MYSQL_YYABORT; p_elem->partition_name= $1.str; } @@ -5452,9 +5578,9 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->error_if_requires_values()) - MYSQL_YYABORT; - if (part_info->part_type == VERSIONING_PARTITION) + if (unlikely(part_info->error_if_requires_values())) + MYSQL_YYABORT; + if (unlikely(part_info->part_type == VERSIONING_PARTITION)) my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0), lex->create_last_non_select_table-> table_name.str)); @@ -5468,7 +5594,7 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type != RANGE_PARTITION) + if (unlikely(part_info->part_type != RANGE_PARTITION)) my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN")); } @@ -5482,7 +5608,7 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type != LIST_PARTITION) + if (unlikely(part_info->part_type != LIST_PARTITION)) my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "LIST", "IN")); } @@ -5492,60 +5618,13 @@ opt_part_values: part_values_in {} | CURRENT_SYM { - LEX *lex= Lex; - partition_info *part_info= lex->part_info; - partition_element *elem= part_info->curr_part_elem; - if (! lex->is_partition_management()) - { - if (part_info->part_type != VERSIONING_PARTITION) - my_yyabort_error((ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME")); - } - else - { - DBUG_ASSERT(Lex->create_last_non_select_table); - DBUG_ASSERT(Lex->create_last_non_select_table->table_name.str); - // FIXME: other ALTER commands? - my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0), - Lex->create_last_non_select_table-> - table_name.str)); - } - elem->type(partition_element::CURRENT); - DBUG_ASSERT(part_info->vers_info); - part_info->vers_info->now_part= elem; - if (part_info->init_column_part(thd)) - { + if (Lex->part_values_current(thd)) MYSQL_YYABORT; - } } | HISTORY_SYM { - LEX *lex= Lex; - partition_info *part_info= lex->part_info; - partition_element *elem= part_info->curr_part_elem; - if (! lex->is_partition_management()) - { - if (part_info->part_type != VERSIONING_PARTITION) - my_yyabort_error((ER_PARTITION_WRONG_TYPE, MYF(0), "SYSTEM_TIME")); - } - else - { - part_info->vers_init_info(thd); - elem->id= UINT_MAX32; - } - DBUG_ASSERT(part_info->vers_info); - if (part_info->vers_info->now_part) - { - DBUG_ASSERT(Lex->create_last_non_select_table); - DBUG_ASSERT(Lex->create_last_non_select_table->table_name.str); - my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0), - Lex->create_last_non_select_table-> - table_name.str)); - } - elem->type(partition_element::HISTORY); - if (part_info->init_column_part(thd)) - { + if (Lex->part_values_history(thd)) MYSQL_YYABORT; - } } | DEFAULT { @@ -5553,20 +5632,16 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type != LIST_PARTITION) + if (unlikely(part_info->part_type != LIST_PARTITION)) my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "LIST", "DEFAULT")); } else part_info->part_type= LIST_PARTITION; - if (part_info->init_column_part(thd)) - { + if (unlikely(part_info->init_column_part(thd))) MYSQL_YYABORT; - } - if (part_info->add_max_value(thd)) - { + if (unlikely(part_info->add_max_value(thd))) MYSQL_YYABORT; - } } ; @@ -5575,8 +5650,8 @@ part_func_max: { partition_info *part_info= Lex->part_info; - if (part_info->num_columns && - part_info->num_columns != 1U) + if (unlikely(part_info->num_columns && + part_info->num_columns != 1U)) { part_info->print_debug("Kilroy II", NULL); thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); @@ -5584,14 +5659,10 @@ part_func_max: } else part_info->num_columns= 1U; - if (part_info->init_column_part(thd)) - { + if (unlikely(part_info->init_column_part(thd))) MYSQL_YYABORT; - } - if (part_info->add_max_value(thd)) - { + if (unlikely(part_info->add_max_value(thd))) MYSQL_YYABORT; - } } | part_value_item {} ; @@ -5605,9 +5676,9 @@ part_values_in: if (part_info->num_columns != 1U) { - if (!lex->is_partition_management() || - part_info->num_columns == 0 || - part_info->num_columns > MAX_REF_PARTS) + if (unlikely(!lex->is_partition_management() || + part_info->num_columns == 0 || + part_info->num_columns > MAX_REF_PARTS)) { part_info->print_debug("Kilroy III", NULL); thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); @@ -5620,16 +5691,14 @@ part_values_in: we ADD or REORGANIZE partitions. Also can only happen for LIST partitions. */ - if (part_info->reorganize_into_single_field_col_val(thd)) - { + if (unlikely(part_info->reorganize_into_single_field_col_val(thd))) MYSQL_YYABORT; - } } } | '(' part_value_list ')' { partition_info *part_info= Lex->part_info; - if (part_info->num_columns < 2U) + if (unlikely(part_info->num_columns < 2U)) { thd->parse_error(ER_ROW_SINGLE_PARTITION_FIELD_ERROR); MYSQL_YYABORT; @@ -5648,12 +5717,10 @@ part_value_item: partition_info *part_info= Lex->part_info; part_info->print_debug("( part_value_item", NULL); /* Initialisation code needed for each list of value expressions */ - if (!(part_info->part_type == LIST_PARTITION && - part_info->num_columns == 1U) && - part_info->init_column_part(thd)) - { + if (unlikely(!(part_info->part_type == LIST_PARTITION && + part_info->num_columns == 1U) && + part_info->init_column_part(thd))) MYSQL_YYABORT; - } } part_value_item_list {} ')' @@ -5662,7 +5729,7 @@ part_value_item: part_info->print_debug(") part_value_item", NULL); if (part_info->num_columns == 0) part_info->num_columns= part_info->curr_list_object; - if (part_info->num_columns != part_info->curr_list_object) + if (unlikely(part_info->num_columns != part_info->curr_list_object)) { /* All value items lists must be of equal length, in some cases @@ -5688,15 +5755,13 @@ part_value_expr_item: MAXVALUE_SYM { partition_info *part_info= Lex->part_info; - if (part_info->part_type == LIST_PARTITION) + if (unlikely(part_info->part_type == LIST_PARTITION)) { thd->parse_error(ER_MAXVALUE_IN_VALUES_IN); MYSQL_YYABORT; } - if (part_info->add_max_value(thd)) - { + if (unlikely(part_info->add_max_value(thd))) MYSQL_YYABORT; - } } | bit_expr { @@ -5704,15 +5769,13 @@ part_value_expr_item: partition_info *part_info= lex->part_info; Item *part_expr= $1; - if (!lex->safe_to_cache_query) + if (unlikely(!lex->safe_to_cache_query)) { thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); MYSQL_YYABORT; } - if (part_info->add_column_list_value(thd, part_expr)) - { + if (unlikely(part_info->add_column_list_value(thd, part_expr))) MYSQL_YYABORT; - } } ; @@ -5721,8 +5784,8 @@ opt_sub_partition: /* empty */ { partition_info *part_info= Lex->part_info; - if (part_info->num_subparts != 0 && - !part_info->use_default_subpartitions) + if (unlikely(part_info->num_subparts != 0 && + !part_info->use_default_subpartitions)) { /* We come here when we have defined subpartitions on the first @@ -5737,8 +5800,8 @@ opt_sub_partition: partition_info *part_info= Lex->part_info; if (part_info->num_subparts != 0) { - if (part_info->num_subparts != - part_info->count_curr_subparts) + if (unlikely(part_info->num_subparts != + part_info->count_curr_subparts)) { thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; @@ -5746,7 +5809,7 @@ opt_sub_partition: } else if (part_info->count_curr_subparts > 0) { - if (part_info->partitions.elements > 1) + if (unlikely(part_info->partitions.elements > 1)) { thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; @@ -5769,8 +5832,8 @@ sub_part_definition: partition_element *curr_part= part_info->current_partition; partition_element *sub_p_elem= new (thd->mem_root) partition_element(curr_part); - if (part_info->use_default_subpartitions && - part_info->partitions.elements >= 2) + if (unlikely(part_info->use_default_subpartitions && + part_info->partitions.elements >= 2)) { /* create table t1 (a int) @@ -5786,12 +5849,10 @@ sub_part_definition: thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; } - if (!sub_p_elem || - curr_part->subpartitions.push_back(sub_p_elem, thd->mem_root)) - { - mem_alloc_error(sizeof(partition_element)); + if (unlikely(!sub_p_elem) || + unlikely(curr_part->subpartitions.push_back(sub_p_elem, thd->mem_root))) MYSQL_YYABORT; - } + sub_p_elem->id= curr_part->subpartitions.elements - 1; part_info->curr_part_elem= sub_p_elem; part_info->use_default_subpartitions= FALSE; @@ -5804,7 +5865,7 @@ sub_part_definition: sub_name: ident_or_text { - if (check_ident_length(&$1)) + if (unlikely(check_ident_length(&$1))) MYSQL_YYABORT; Lex->part_info->curr_part_elem->partition_name= $1.str; } @@ -5854,7 +5915,7 @@ opt_versioning_rotation: | INTERVAL_SYM expr interval opt_versioning_interval_start { partition_info *part_info= Lex->part_info; - if (part_info->vers_set_interval($2, $3, $4)) + if (unlikely(part_info->vers_set_interval($2, $3, $4))) { my_error(ER_PART_WRONG_VALUE, MYF(0), Lex->create_last_non_select_table->table_name.str, @@ -5865,7 +5926,7 @@ opt_versioning_rotation: | LIMIT ulonglong_num { partition_info *part_info= Lex->part_info; - if (part_info->vers_set_limit($2)) + if (unlikely(part_info->vers_set_limit($2))) { my_error(ER_PART_WRONG_VALUE, MYF(0), Lex->create_last_non_select_table->table_name.str, @@ -5875,22 +5936,21 @@ opt_versioning_rotation: } ; - ; opt_versioning_interval_start: /* empty */ { - $$= thd->systime(); + $$= thd->query_start(); } - | remember_tok_start STARTS_SYM ulong_num + | STARTS_SYM ulong_num { /* only allowed from mysql_unpack_partition() */ - if (!Lex->part_info->table) + if (unlikely(!Lex->part_info->table)) { - thd->parse_error(ER_SYNTAX_ERROR, $1); + thd->parse_error(ER_SYNTAX_ERROR, $1.pos()); MYSQL_YYABORT; } - $$= (ulong)$3; + $$= (ulong)$2; } ; @@ -6125,7 +6185,7 @@ create_table_option: larger values. 65535 pages, 16kb each means to sample 1GB, which is impractical. If at some point this needs to be extended, then we can store the higher bits from stats_sample_pages in .frm too. */ - if ($3 == 0 || $3 > 0xffff) + if (unlikely($3 == 0 || $3 > 0xffff)) { thd->parse_error(); MYSQL_YYABORT; @@ -6230,31 +6290,33 @@ create_table_option: } | IDENT_sys equal TEXT_STRING_sys { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, true, &Lex->create_info.option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, true, + &Lex->create_info.option_list, + &Lex->option_list_last); } | IDENT_sys equal ident { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, false, &Lex->create_info.option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, false, + &Lex->create_info.option_list, + &Lex->option_list_last); } | IDENT_sys equal real_ulonglong_num { - new (thd->mem_root) - engine_option_value($1, $3, &Lex->create_info.option_list, - &Lex->option_list_last, thd->mem_root); + (void) new (thd->mem_root) + engine_option_value($1, $3, &Lex->create_info.option_list, + &Lex->option_list_last, thd->mem_root); } | IDENT_sys equal DEFAULT { - new (thd->mem_root) - engine_option_value($1, &Lex->create_info.option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, &Lex->create_info.option_list, + &Lex->option_list_last); } | SEQUENCE_SYM opt_equal choice { @@ -6272,7 +6334,7 @@ opt_versioning_option: versioning_option: WITH_SYSTEM_SYM VERSIONING_SYM { - if (Lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) + if (unlikely(Lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) { if (DBUG_EVALUATE_IF("sysvers_force", 0, 1)) { @@ -6291,7 +6353,7 @@ versioning_option: default_charset: opt_default charset opt_equal charset_name_or_default { - if (Lex->create_info.add_table_option_default_charset($4)) + if (unlikely(Lex->create_info.add_table_option_default_charset($4))) MYSQL_YYABORT; } ; @@ -6300,13 +6362,11 @@ default_collation: opt_default COLLATE_SYM opt_equal collation_name_or_default { HA_CREATE_INFO *cinfo= &Lex->create_info; - if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && - cinfo->default_table_charset && $4 && - !($4= merge_charset_and_collation(cinfo->default_table_charset, - $4))) - { + if (unlikely((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !($4= merge_charset_and_collation(cinfo->default_table_charset, + $4)))) MYSQL_YYABORT; - } Lex->create_info.default_table_charset= $4; Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; @@ -6319,7 +6379,7 @@ storage_engines: plugin_ref plugin= ha_resolve_by_name(thd, &$1, thd->lex->create_info.tmp_table()); - if (plugin) + if (likely(plugin)) $$= plugin_hton(plugin); else { @@ -6338,7 +6398,7 @@ known_storage_engines: ident_or_text { plugin_ref plugin; - if ((plugin= ha_resolve_by_name(thd, &$1, false))) + if (likely((plugin= ha_resolve_by_name(thd, &$1, false)))) $$= plugin_hton(plugin); else my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str)); @@ -6399,28 +6459,28 @@ key_def: key_or_index opt_if_not_exists opt_ident opt_USING_key_algorithm { Lex->option_list= NULL; - if (Lex->add_key(Key::MULTIPLE, &$3, $4, $2)) + if (unlikely(Lex->add_key(Key::MULTIPLE, &$3, $4, $2))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | key_or_index opt_if_not_exists ident TYPE_SYM btree_or_rtree { Lex->option_list= NULL; - if (Lex->add_key(Key::MULTIPLE, &$3, $5, $2)) + if (unlikely(Lex->add_key(Key::MULTIPLE, &$3, $5, $2))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | fulltext opt_key_or_index opt_if_not_exists opt_ident { Lex->option_list= NULL; - if (Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)) + if (unlikely(Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3))) MYSQL_YYABORT; } '(' key_list ')' fulltext_key_options { } | spatial opt_key_or_index opt_if_not_exists opt_ident { Lex->option_list= NULL; - if (Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)) + if (unlikely(Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3))) MYSQL_YYABORT; } '(' key_list ')' spatial_key_options { } @@ -6429,7 +6489,7 @@ key_def: opt_USING_key_algorithm { Lex->option_list= NULL; - if (Lex->add_key($2, $4.str ? &$4 : &$1, $5, $3)) + if (unlikely(Lex->add_key($2, $4.str ? &$4 : &$1, $5, $3))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } @@ -6437,16 +6497,17 @@ key_def: TYPE_SYM btree_or_rtree { Lex->option_list= NULL; - if (Lex->add_key($2, $4.str ? &$4 : &$1, $6, $3)) + if (unlikely(Lex->add_key($2, $4.str ? &$4 : &$1, $6, $3))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | opt_constraint FOREIGN KEY_SYM opt_if_not_exists opt_ident { - if (Lex->check_add_key($4) || - !(Lex->last_key= (new (thd->mem_root) - Key(Key::MULTIPLE, $1.str ? &$1 : &$5, - HA_KEY_ALG_UNDEF, true, $4)))) + if (unlikely(Lex->check_add_key($4)) || + unlikely(!(Lex->last_key= (new (thd->mem_root) + Key(Key::MULTIPLE, + $1.str ? &$1 : &$5, + HA_KEY_ALG_UNDEF, true, $4))))) MYSQL_YYABORT; Lex->option_list= NULL; } @@ -6463,7 +6524,7 @@ key_def: lex->fk_update_opt, lex->fk_match_option, $4)); - if (key == NULL) + if (unlikely(key == NULL)) MYSQL_YYABORT; /* handle_if_exists_options() expectes the two keys in this order: @@ -6502,12 +6563,9 @@ opt_check_constraint: check_constraint: CHECK_SYM '(' expr ')' { - Virtual_column_info *v= - add_virtual_expression(thd, $3); - if (!v) - { + Virtual_column_info *v= add_virtual_expression(thd, $3); + if (unlikely(!v)) MYSQL_YYABORT; - } $$= v; } ; @@ -6527,11 +6585,11 @@ field_spec: LEX *lex=Lex; Create_field *f= new (thd->mem_root) Create_field(); - if (check_string_char_length(&$1, 0, NAME_CHAR_LEN, - system_charset_info, 1)) + if (unlikely(check_string_char_length(&$1, 0, NAME_CHAR_LEN, + system_charset_info, 1))) my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str)); - if (!f) + if (unlikely(!f)) MYSQL_YYABORT; lex->init_last_field(f, &$1, NULL); @@ -6544,7 +6602,7 @@ field_spec: $$->check_constraint= $4; - if ($$->check(thd)) + if (unlikely($$->check(thd))) MYSQL_YYABORT; lex->alter_info.create_list.push_back($$, thd->mem_root); @@ -6597,46 +6655,16 @@ field_def: Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps } vcol_opt_specifier vcol_opt_attribute - | opt_generated_always AS ROW_SYM start_or_end opt_asrow_attribute + | opt_generated_always AS ROW_SYM START_SYM opt_asrow_attribute { - LEX *lex= Lex; - Vers_parse_info &info= lex->vers_get_info(); - const LEX_CSTRING &field_name= lex->last_field->field_name; - - LString_i *p; - switch ($4) - { - case 1: - p= &info.as_row.start; - if (*p) - { - my_yyabort_error((ER_VERS_DUPLICATE_ROW_START_END, MYF(0), - "START", field_name.str)); - } - lex->last_field->flags|= VERS_SYS_START_FLAG | NOT_NULL_FLAG; - break; - case 0: - p= &info.as_row.end; - if (*p) - { - my_yyabort_error((ER_VERS_DUPLICATE_ROW_START_END, MYF(0), - "END", field_name.str)); - } - lex->last_field->flags|= VERS_SYS_END_FLAG | NOT_NULL_FLAG; - break; - default: - /* Not Reachable */ + if (Lex->last_field_generated_always_as_row_start()) + MYSQL_YYABORT; + } + | opt_generated_always AS ROW_SYM END opt_asrow_attribute + { + if (Lex->last_field_generated_always_as_row_end()) MYSQL_YYABORT; - break; - } - DBUG_ASSERT(p); - *p= field_name; } - ; - -start_or_end: - START_SYM { $$ = 1; } - | END { $$ = 0; } ; opt_generated_always: @@ -6689,7 +6717,7 @@ vcol_attribute: | COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; } | INVISIBLE_SYM { - Lex->last_field->invisible= INVISIBLE_USER; + Lex->last_field->invisible= INVISIBLE_USER; } ; @@ -6706,7 +6734,7 @@ parse_vcol_expr: expr { Virtual_column_info *v= add_virtual_expression(thd, $3); - if (!v) + if (unlikely(!v)) MYSQL_YYABORT; Lex->last_field->vcol_info= v; } @@ -6716,7 +6744,7 @@ parenthesized_expr: subselect { $$= new (thd->mem_root) Item_singlerow_subselect(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | expr @@ -6724,7 +6752,7 @@ parenthesized_expr: { $3->push_front($1, thd->mem_root); $$= new (thd->mem_root) Item_row(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -6734,10 +6762,8 @@ virtual_column_func: { Virtual_column_info *v= add_virtual_expression(thd, $2); - if (!v) - { + if (unlikely(!v)) MYSQL_YYABORT; - } $$= v; } ; @@ -6748,7 +6774,7 @@ column_default_expr: virtual_column_func | expr_or_literal { - if (!($$= add_virtual_expression(thd, $1))) + if (unlikely(!($$= add_virtual_expression(thd, $1)))) MYSQL_YYABORT; } ; @@ -6771,7 +6797,7 @@ field_type_numeric: { int err; ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err); - if (err || tmp_length > PRECISION_FOR_DOUBLE) + if (unlikely(err || tmp_length > PRECISION_FOR_DOUBLE)) my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0), Lex->last_field->field_name.str)); if (tmp_length > PRECISION_FOR_FLOAT) @@ -7069,7 +7095,7 @@ attribute: | ON UPDATE_SYM NOW_SYM opt_default_time_precision { Item *item= new (thd->mem_root) Item_func_now_local(thd, $4); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; Lex->last_field->on_update= item; } @@ -7082,14 +7108,14 @@ attribute: } | COLLATE_SYM collation_name { - if (Lex->charset && !my_charset_same(Lex->charset,$2)) + if (unlikely(Lex->charset && !my_charset_same(Lex->charset,$2))) my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0), $2->name,Lex->charset->csname)); Lex->last_field->charset= $2; } | COMPRESSED_SYM opt_compression_method { - if (Lex->last_field->set_compressed($2)) + if (unlikely(Lex->last_field->set_compressed($2))) MYSQL_YYABORT; } | serial_attribute @@ -7118,30 +7144,33 @@ serial_attribute: asrow_attribute | IDENT_sys equal TEXT_STRING_sys { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, true, &Lex->last_field->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, true, + &Lex->last_field->option_list, + &Lex->option_list_last); } | IDENT_sys equal ident { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, false, &Lex->last_field->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, false, + &Lex->last_field->option_list, + &Lex->option_list_last); } | IDENT_sys equal real_ulonglong_num { - new (thd->mem_root) - engine_option_value($1, $3, &Lex->last_field->option_list, - &Lex->option_list_last, thd->mem_root); + (void) new (thd->mem_root) + engine_option_value($1, $3, &Lex->last_field->option_list, + &Lex->option_list_last, thd->mem_root); } | IDENT_sys equal DEFAULT { - new (thd->mem_root) - engine_option_value($1, &Lex->last_field->option_list, &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, &Lex->last_field->option_list, + &Lex->option_list_last); } | with_or_without_system VERSIONING_SYM { @@ -7173,7 +7202,7 @@ type_with_opt_collate: if ($2) { - if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))) + if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))) MYSQL_YYABORT; } Lex->last_field->set_attributes($1, Lex->charset); @@ -7188,7 +7217,7 @@ charset: charset_name: ident_or_text { - if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) + if (unlikely(!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str)); } | BINARY { $$= &my_charset_bin; } @@ -7207,8 +7236,9 @@ opt_load_data_charset: old_or_new_charset_name: ident_or_text { - if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && - !($$=get_old_charset_by_name($1.str))) + if (unlikely(!($$=get_charset_by_csname($1.str, + MY_CS_PRIMARY,MYF(0))) && + !($$=get_old_charset_by_name($1.str)))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str)); } | BINARY { $$= &my_charset_bin; } @@ -7222,7 +7252,7 @@ old_or_new_charset_name_or_default: collation_name: ident_or_text { - if (!($$= mysqld_collation_get_by_name($1.str))) + if (unlikely(!($$= mysqld_collation_get_by_name($1.str)))) MYSQL_YYABORT; } ; @@ -7247,7 +7277,7 @@ charset_or_alias: | ASCII_SYM { $$= &my_charset_latin1; } | UNICODE_SYM { - if (!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0)))) + if (unlikely(!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0))))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2")); } ; @@ -7268,7 +7298,7 @@ opt_bin_mod: ws_nweights: '(' real_ulong_num { - if ($2 == 0) + if (unlikely($2 == 0)) { thd->parse_error(); MYSQL_YYABORT; @@ -7359,14 +7389,14 @@ ref_list: ref_list ',' ident { Key_part_spec *key= new (thd->mem_root) Key_part_spec(&$3, 0); - if (key == NULL) + if (unlikely(key == NULL)) MYSQL_YYABORT; Lex->ref_list.push_back(key, thd->mem_root); } | ident { Key_part_spec *key= new (thd->mem_root) Key_part_spec(&$1, 0); - if (key == NULL) + if (unlikely(key == NULL)) MYSQL_YYABORT; LEX *lex= Lex; lex->ref_list.empty(); @@ -7527,30 +7557,31 @@ all_key_opt: { Lex->last_key->key_create_info.comment= $2; } | IDENT_sys equal TEXT_STRING_sys { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, true, &Lex->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, true, &Lex->option_list, + &Lex->option_list_last); } | IDENT_sys equal ident { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, false, &Lex->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, false, &Lex->option_list, + &Lex->option_list_last); } | IDENT_sys equal real_ulonglong_num { - new (thd->mem_root) - engine_option_value($1, $3, &Lex->option_list, - &Lex->option_list_last, thd->mem_root); + (void) new (thd->mem_root) + engine_option_value($1, $3, &Lex->option_list, + &Lex->option_list_last, thd->mem_root); } | IDENT_sys equal DEFAULT { - new (thd->mem_root) - engine_option_value($1, &Lex->option_list, &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, &Lex->option_list, + &Lex->option_list_last); } ; @@ -7567,7 +7598,7 @@ fulltext_key_opt: all_key_opt | WITH PARSER_SYM IDENT_sys { - if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN)) + if (likely(plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))) Lex->last_key->key_create_info.parser_name= $3; else my_yyabort_error((ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str)); @@ -7595,16 +7626,16 @@ key_part: ident { $$= new (thd->mem_root) Key_part_spec(&$1, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ident '(' NUM ')' { int key_part_len= atoi($3.str); - if (!key_part_len) + if (unlikely(!key_part_len)) my_yyabort_error((ER_KEY_PART_0, MYF(0), $1.str)); $$= new (thd->mem_root) Key_part_spec(&$1, (uint) key_part_len); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -7614,11 +7645,6 @@ opt_ident: | field_ident { $$= $1; } ; -opt_component: - /* empty */ { $$= null_clex_str; } - | '.' ident { $$= $2; } - ; - string_list: text_string { Lex->last_field->interval_list.push_back($1, thd->mem_root); } @@ -7646,21 +7672,21 @@ alter: } alter_options TABLE_SYM table_ident opt_lock_wait_timeout { - if (!Lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_UPGRADABLE)) + if (unlikely(!Lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_UPGRADABLE))) MYSQL_YYABORT; Lex->select_lex.db= (Lex->select_lex.table_list.first)->db; Lex->create_last_non_select_table= Lex->last_table(); } alter_commands { - if (!Lex->m_sql_cmd) + if (likely(!Lex->m_sql_cmd)) { /* Create a generic ALTER TABLE statment. */ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table(); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } } @@ -7674,13 +7700,14 @@ alter: LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; lex->name= $3; - if (lex->name.str == NULL && lex->copy_db_to(&lex->name)) + if (lex->name.str == NULL && + unlikely(lex->copy_db_to(&lex->name))) MYSQL_YYABORT; } | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "DATABASE")); lex->sql_command= SQLCOM_ALTER_DB_UPGRADE; lex->name= $3; @@ -7689,7 +7716,7 @@ alter: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE")); lex->sp_chistics.init(); } @@ -7704,7 +7731,7 @@ alter: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); lex->sp_chistics.init(); } @@ -7717,7 +7744,7 @@ alter: } | ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident { - if (Lex->add_alter_view(thd, $2, $4, $6)) + if (unlikely(Lex->add_alter_view(thd, $2, $4, $6))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -7729,7 +7756,7 @@ alter: with the ALTER EVENT below. */ { - if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5)) + if (unlikely(Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -7744,7 +7771,7 @@ alter: Event_parse_data. */ - if (!(Lex->event_parse_data= Event_parse_data::new_instance(thd))) + if (unlikely(!(Lex->event_parse_data= Event_parse_data::new_instance(thd)))) MYSQL_YYABORT; Lex->event_parse_data->identifier= $5; @@ -7757,7 +7784,7 @@ alter: opt_ev_comment opt_ev_sql_stmt { - if (!($7 || $8 || $9 || $10 || $11)) + if (unlikely(!($7 || $8 || $9 || $10 || $11))) { thd->parse_error(); MYSQL_YYABORT; @@ -7815,18 +7842,19 @@ alter: table_ident { LEX *lex= Lex; - if (!(lex->create_info.seq_create_info= new (thd->mem_root) - sequence_definition()) || - !lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_SEQUENCE, - TL_WRITE, MDL_EXCLUSIVE)) + if (unlikely(!(lex->create_info.seq_create_info= + new (thd->mem_root) sequence_definition())) || + unlikely(!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_SEQUENCE, + TL_WRITE, + MDL_EXCLUSIVE))) MYSQL_YYABORT; } sequence_defs { /* Create a generic ALTER SEQUENCE statment. */ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -7857,8 +7885,8 @@ opt_ev_sql_stmt: ; ident_or_empty: - /* empty */ { $$= null_clex_str; } - | ident { $$= $1; } + /* empty */ { $$= Lex_ident_sys(); } + | ident ; alter_commands: @@ -7868,7 +7896,7 @@ alter_commands: Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_discard_import_tablespace( Sql_cmd_discard_import_tablespace::DISCARD_TABLESPACE); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | IMPORT TABLESPACE @@ -7876,7 +7904,7 @@ alter_commands: Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_discard_import_tablespace( Sql_cmd_discard_import_tablespace::IMPORT_TABLESPACE); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | alter_list @@ -7915,7 +7943,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_optimize_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_no_write_to_binlog @@ -7928,7 +7956,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_analyze_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list @@ -7938,7 +7966,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_check_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_mi_check_type @@ -7951,7 +7979,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_repair_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_mi_repair_type @@ -7969,7 +7997,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_truncate_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | reorg_partition_rule @@ -7979,21 +8007,19 @@ alter_commands: LEX *lex= thd->lex; lex->select_lex.db= $6->db; if (lex->select_lex.db.str == NULL && - lex->copy_db_to(&lex->select_lex.db)) - { + unlikely(lex->copy_db_to(&lex->select_lex.db))) MYSQL_YYABORT; - } lex->name= $6->table; lex->alter_info.partition_flags|= ALTER_PARTITION_EXCHANGE; - if (!lex->select_lex.add_table_to_list(thd, $6, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $6, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE))) MYSQL_YYABORT; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_exchange_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8019,11 +8045,9 @@ add_partition_rule: { LEX *lex= Lex; lex->part_info= new (thd->mem_root) partition_info(); - if (!lex->part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!lex->part_info)) MYSQL_YYABORT; - } + lex->alter_info.partition_flags|= ALTER_PARTITION_ADD; DBUG_ASSERT(!Lex->create_info.if_not_exists()); lex->create_info.set($3); @@ -8051,11 +8075,9 @@ reorg_partition_rule: { LEX *lex= Lex; lex->part_info= new (thd->mem_root) partition_info(); - if (!lex->part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!lex->part_info)) MYSQL_YYABORT; - } + lex->no_write_to_binlog= $3; } reorg_parts_rule @@ -8085,12 +8107,9 @@ alt_part_name_list: alt_part_name_item: ident { - if (Lex->alter_info.partition_names.push_back($1.str, - thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(Lex->alter_info.partition_names.push_back($1.str, + thd->mem_root))) MYSQL_YYABORT; - } } ; @@ -8161,7 +8180,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::COLUMN, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_PARSER_DROP_COLUMN; @@ -8172,7 +8191,7 @@ alter_list_item: Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::CHECK_CONSTRAINT, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_CHECK_CONSTRAINT; @@ -8182,7 +8201,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::FOREIGN_KEY, $5.str, $4)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_FOREIGN_KEY; @@ -8193,7 +8212,7 @@ alter_list_item: Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::KEY, primary_key_name, FALSE)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_INDEX; @@ -8203,7 +8222,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::KEY, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_INDEX; @@ -8222,12 +8241,13 @@ alter_list_item: } | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr { - if (Lex->add_alter_list($4.str, $7, $3)) + if (unlikely(Lex->add_alter_list($4.str, $7, $3))) MYSQL_YYABORT; } | ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT { - if (Lex->add_alter_list($4.str, (Virtual_column_info*) 0, $3)) + if (unlikely(Lex->add_alter_list($4.str, (Virtual_column_info*) 0, + $3))) MYSQL_YYABORT; } | RENAME opt_to table_ident @@ -8235,12 +8255,11 @@ alter_list_item: LEX *lex=Lex; lex->select_lex.db= $3->db; if (lex->select_lex.db.str == NULL && - lex->copy_db_to(&lex->select_lex.db)) - { + unlikely(lex->copy_db_to(&lex->select_lex.db))) MYSQL_YYABORT; - } - if (check_table_name($3->table.str,$3->table.length, FALSE) || - ($3->db.str && check_db_name((LEX_STRING*) &$3->db))) + if (unlikely(check_table_name($3->table.str,$3->table.length, + FALSE)) || + ($3->db.str && unlikely(check_db_name((LEX_STRING*) &$3->db)))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3->table.str)); lex->name= $3->table; lex->alter_info.flags|= ALTER_RENAME; @@ -8252,10 +8271,10 @@ alter_list_item: $4= thd->variables.collation_database; } $5= $5 ? $5 : $4; - if (!my_charset_same($4,$5)) + if (unlikely(!my_charset_same($4,$5))) my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0), $5->name, $4->csname)); - if (Lex->create_info.add_alter_list_item_convert_to_charset($5)) + if (unlikely(Lex->create_info.add_alter_list_item_convert_to_charset($5))) MYSQL_YYABORT; Lex->alter_info.flags|= ALTER_OPTIONS; } @@ -8310,7 +8329,7 @@ alter_algorithm_option: } | ALGORITHM_SYM opt_equal ident { - if (Lex->alter_info.set_requested_algorithm(&$3)) + if (unlikely(Lex->alter_info.set_requested_algorithm(&$3))) my_yyabort_error((ER_UNKNOWN_ALTER_ALGORITHM, MYF(0), $3.str)); } ; @@ -8323,13 +8342,13 @@ alter_lock_option: } | LOCK_SYM opt_equal ident { - if (Lex->alter_info.set_requested_lock(&$3)) + if (unlikely(Lex->alter_info.set_requested_lock(&$3))) my_yyabort_error((ER_UNKNOWN_ALTER_LOCK, MYF(0), $3.str)); } ; opt_column: - /* empty */ {} + /* empty */ {} %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE | COLUMN_SYM {} ; @@ -8429,8 +8448,8 @@ start: LEX *lex= Lex; lex->sql_command= SQLCOM_BEGIN; /* READ ONLY and READ WRITE are mutually exclusive. */ - if (($3 & MYSQL_START_TRANS_OPT_READ_WRITE) && - ($3 & MYSQL_START_TRANS_OPT_READ_ONLY)) + if (unlikely(($3 & MYSQL_START_TRANS_OPT_READ_WRITE) && + ($3 & MYSQL_START_TRANS_OPT_READ_ONLY))) { thd->parse_error(); MYSQL_YYABORT; @@ -8498,10 +8517,10 @@ slave_until: | UNTIL_SYM slave_until_opts { LEX *lex=Lex; - if (((lex->mi.log_file_name || lex->mi.pos) && - (lex->mi.relay_log_name || lex->mi.relay_log_pos)) || - !((lex->mi.log_file_name && lex->mi.pos) || - (lex->mi.relay_log_name && lex->mi.relay_log_pos))) + if (unlikely(((lex->mi.log_file_name || lex->mi.pos) && + (lex->mi.relay_log_name || lex->mi.relay_log_pos)) || + !((lex->mi.log_file_name && lex->mi.pos) || + (lex->mi.relay_log_name && lex->mi.relay_log_pos)))) my_yyabort_error((ER_BAD_SLAVE_UNTIL_COND, MYF(0))); } | UNTIL_SYM MASTER_GTID_POS_SYM '=' TEXT_STRING_sys @@ -8556,7 +8575,7 @@ repair: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8598,7 +8617,7 @@ analyze: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8633,7 +8652,7 @@ persistent_column_stat_spec: { LEX* lex= thd->lex; lex->column_list= new (thd->mem_root) List<LEX_STRING>; - if (lex->column_list == NULL) + if (unlikely(lex->column_list == NULL)) MYSQL_YYABORT; } table_column_list @@ -8646,7 +8665,7 @@ persistent_index_stat_spec: { LEX* lex= thd->lex; lex->index_list= new (thd->mem_root) List<LEX_STRING>; - if (lex->index_list == NULL) + if (unlikely(lex->index_list == NULL)) MYSQL_YYABORT; } table_index_list @@ -8720,11 +8739,11 @@ check: CHECK_SYM check_view_or_table { LEX* lex= thd->lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "CHECK")); DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8769,7 +8788,7 @@ optimize: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8796,14 +8815,14 @@ rename: rename_list: user TO_SYM user { - if (Lex->users_list.push_back($1, thd->mem_root) || - Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root) || + Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } | rename_list ',' user TO_SYM user { - if (Lex->users_list.push_back($3, thd->mem_root) || - Lex->users_list.push_back($5, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root) || + Lex->users_list.push_back($5, thd->mem_root))) MYSQL_YYABORT; } ; @@ -8818,10 +8837,12 @@ table_to_table: { LEX *lex=Lex; SELECT_LEX *sl= lex->current_select; - if (!sl->add_table_to_list(thd, $1,NULL,TL_OPTION_UPDATING, - TL_IGNORE, MDL_EXCLUSIVE) || - !sl->add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING, - TL_IGNORE, MDL_EXCLUSIVE)) + if (unlikely(!sl->add_table_to_list(thd, $1,NULL, + TL_OPTION_UPDATING, + TL_IGNORE, MDL_EXCLUSIVE)) || + unlikely(!sl->add_table_to_list(thd, $4, NULL, + TL_OPTION_UPDATING, + TL_IGNORE, MDL_EXCLUSIVE))) MYSQL_YYABORT; } ; @@ -8852,9 +8873,10 @@ keycache_list: assign_to_keycache: table_ident cache_keys_spec { - if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8862,9 +8884,10 @@ assign_to_keycache: assign_to_keycache_parts: table_ident adm_partition cache_keys_spec { - if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8898,9 +8921,10 @@ preload_list: preload_keys: table_ident cache_keys_spec opt_ignore_leaves { - if (!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8908,9 +8932,10 @@ preload_keys: preload_keys_parts: table_ident adm_partition cache_keys_spec opt_ignore_leaves { - if (!Select->add_table_to_list(thd, $1, NULL, $4, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, $4, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -9200,13 +9225,14 @@ select_options: /* empty*/ | select_option_list { - if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL) + if (unlikely((Select->options & SELECT_DISTINCT) && + (Select->options & SELECT_ALL))) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT")); } ; opt_history_unit: - /* empty*/ + /* empty*/ %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE { $$= VERS_UNDEFINED; } @@ -9221,9 +9247,13 @@ opt_history_unit: ; history_point: - temporal_literal + TIMESTAMP TEXT_STRING { - $$= Vers_history_point(VERS_TIMESTAMP, $1); + Item *item; + if (!(item= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, + MYSQL_TYPE_DATETIME, true))) + MYSQL_YYABORT; + $$= Vers_history_point(VERS_TIMESTAMP, item); } | function_call_keyword_timestamp { @@ -9278,11 +9308,11 @@ select_option: Allow this flag only on the first top-level SELECT statement, if SQL_CACHE wasn't specified, and only once per query. */ - if (Lex->current_select != &Lex->select_lex) + if (unlikely(Lex->current_select != &Lex->select_lex)) my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE")); Lex->safe_to_cache_query=0; @@ -9295,11 +9325,11 @@ select_option: Allow this flag only on the first top-level SELECT statement, if SQL_NO_CACHE wasn't specified, and only once per query. */ - if (Lex->current_select != &Lex->select_lex) + if (unlikely(Lex->current_select != &Lex->select_lex)) my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE")); Lex->safe_to_cache_query=1; @@ -9335,30 +9365,30 @@ select_item_list: Item *item= new (thd->mem_root) Item_field(thd, &thd->lex->current_select->context, NULL, NULL, &star_clex_str); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; - if (add_item_to_list(thd, item)) + if (unlikely(add_item_to_list(thd, item))) MYSQL_YYABORT; (thd->lex->current_select->with_wild)++; } ; select_item: - remember_name table_wild remember_end + remember_name select_sublist_qualified_asterisk remember_end { - if (add_item_to_list(thd, $2)) + if (unlikely(add_item_to_list(thd, $2))) MYSQL_YYABORT; } | remember_name expr remember_end select_alias { DBUG_ASSERT($1 < $3); - if (add_item_to_list(thd, $2)) + if (unlikely(add_item_to_list(thd, $2))) MYSQL_YYABORT; if ($4.str) { - if (Lex->sql_command == SQLCOM_CREATE_VIEW && - check_column_name($4.str)) + if (unlikely(Lex->sql_command == SQLCOM_CREATE_VIEW && + check_column_name($4.str))) my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), $4.str)); $2->is_autogenerated_name= FALSE; $2->set_name(thd, $4.str, $4.length, system_charset_info); @@ -9462,7 +9492,7 @@ expr: { /* X OR Y */ $$= new (thd->mem_root) Item_cond_or(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } } @@ -9470,7 +9500,7 @@ expr: { /* XOR is a proprietary extension */ $$= new (thd->mem_root) Item_func_xor(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | expr and expr %prec AND_SYM @@ -9512,84 +9542,84 @@ expr: { /* X AND Y */ $$= new (thd->mem_root) Item_cond_and(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } } | NOT_SYM expr %prec NOT_SYM { $$= negate_expression(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_istrue(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnottrue(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isfalse(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotfalse(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bool_pri + | bool_pri %prec PREC_BELOW_NOT ; bool_pri: bool_pri IS NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM { $$= new (thd->mem_root) Item_func_equal(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | predicate @@ -9599,22 +9629,22 @@ predicate: bit_expr IN_SYM '(' subselect ')' { $$= new (thd->mem_root) Item_in_subselect(thd, $1, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' subselect ')' { Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $5); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= negate_expression(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr IN_SYM '(' expr ')' { $$= handle_sql2003_note184_exception(thd, $1, true, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr IN_SYM '(' expr ',' expr_list ')' @@ -9622,13 +9652,13 @@ predicate: $6->push_front($4, thd->mem_root); $6->push_front($1, thd->mem_root); $$= new (thd->mem_root) Item_func_in(thd, *$6); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' expr ')' { $$= handle_sql2003_note184_exception(thd, $1, false, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' expr ',' expr_list ')' @@ -9636,21 +9666,21 @@ predicate: $7->push_front($5, thd->mem_root); $7->push_front($1, thd->mem_root); Item_func_in *item= new (thd->mem_root) Item_func_in(thd, *$7); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= item->neg_transformer(thd); } | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate { $$= new (thd->mem_root) Item_func_between(thd, $1, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate { Item_func_between *item; item= new (thd->mem_root) Item_func_between(thd, $1, $4, $6); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= item->neg_transformer(thd); } @@ -9658,131 +9688,157 @@ predicate: { Item *item1= new (thd->mem_root) Item_func_soundex(thd, $1); Item *item4= new (thd->mem_root) Item_func_soundex(thd, $4); - if ((item1 == NULL) || (item4 == NULL)) + if (unlikely(item1 == NULL) || unlikely(item4 == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_eq(thd, item1, item4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bit_expr LIKE simple_expr opt_escape + | bit_expr LIKE mysql_concatenation_expr opt_escape { $$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4, Lex->escape_used); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bit_expr not LIKE simple_expr opt_escape + | bit_expr not LIKE mysql_concatenation_expr opt_escape { Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5, Lex->escape_used); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= item->neg_transformer(thd); } | bit_expr REGEXP bit_expr { $$= new (thd->mem_root) Item_func_regex(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not REGEXP bit_expr { Item *item= new (thd->mem_root) Item_func_regex(thd, $1, $4); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= negate_expression(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bit_expr + | bit_expr %prec PREC_BELOW_NOT ; bit_expr: bit_expr '|' bit_expr %prec '|' { $$= new (thd->mem_root) Item_func_bit_or(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '&' bit_expr %prec '&' { $$= new (thd->mem_root) Item_func_bit_and(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT { $$= new (thd->mem_root) Item_func_shift_left(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT { $$= new (thd->mem_root) Item_func_shift_right(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | bit_expr ORACLE_CONCAT_SYM bit_expr + { + $$= new (thd->mem_root) Item_func_concat_operator_oracle(thd, + $1, $3); + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '+' bit_expr %prec '+' { $$= new (thd->mem_root) Item_func_plus(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '-' bit_expr %prec '-' { $$= new (thd->mem_root) Item_func_minus(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '+' INTERVAL_SYM expr interval %prec '+' { $$= new (thd->mem_root) Item_date_add_interval(thd, $1, $4, $5, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '-' INTERVAL_SYM expr interval %prec '-' { $$= new (thd->mem_root) Item_date_add_interval(thd, $1, $4, $5, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | INTERVAL_SYM expr interval '+' expr + /* we cannot put interval before - */ + { + $$= new (thd->mem_root) Item_date_add_interval(thd, $5, $2, $3, 0); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | '+' INTERVAL_SYM expr interval '+' expr %prec NEG + { + $$= new (thd->mem_root) Item_date_add_interval(thd, $6, $3, $4, 0); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | '-' INTERVAL_SYM expr interval '+' expr %prec NEG + { + $$= new (thd->mem_root) Item_date_add_interval(thd, $6, $3, $4, 1); + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '*' bit_expr %prec '*' { $$= new (thd->mem_root) Item_func_mul(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '/' bit_expr %prec '/' { $$= new (thd->mem_root) Item_func_div(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '%' bit_expr %prec '%' { $$= new (thd->mem_root) Item_func_mod(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr DIV_SYM bit_expr %prec DIV_SYM { $$= new (thd->mem_root) Item_func_int_div(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr MOD_SYM bit_expr %prec MOD_SYM { $$= new (thd->mem_root) Item_func_mod(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '^' bit_expr { $$= new (thd->mem_root) Item_func_bit_xor(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | simple_expr + | mysql_concatenation_expr %prec '^' ; or: @@ -9869,7 +9925,7 @@ dyncall_create_element: LEX *lex= Lex; $$= (DYNCALL_CREATE_DEF *) alloc_root(thd->mem_root, sizeof(DYNCALL_CREATE_DEF)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->key= $1; $$->value= $3; @@ -9889,7 +9945,7 @@ dyncall_create_list: dyncall_create_element { $$= new (thd->mem_root) List<DYNCALL_CREATE_DEF>; - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->push_back($1, thd->mem_root); } @@ -9955,18 +10011,18 @@ column_default_non_parenthesized_expr: { $5->push_front($3, thd->mem_root); $$= new (thd->mem_root) Item_row(thd, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | EXISTS '(' subselect ')' { $$= new (thd->mem_root) Item_exists_subselect(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | '{' ident expr '}' { - if (!($$= $3->make_odbc_literal(thd, &$2))) + if (unlikely(!($$= $3->make_odbc_literal(thd, &$2)))) MYSQL_YYABORT; } | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' @@ -9974,46 +10030,46 @@ column_default_non_parenthesized_expr: $2->push_front($5, thd->mem_root); Item_func_match *i1= new (thd->mem_root) Item_func_match(thd, *$2, $6); - if (i1 == NULL) + if (unlikely(i1 == NULL)) MYSQL_YYABORT; Select->add_ftfunc_to_list(thd, i1); $$= i1; } | CAST_SYM '(' expr AS cast_type ')' { - if (!($$= $5.create_typecast_item(thd, $3, Lex->charset))) + if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) MYSQL_YYABORT; } | CASE_SYM when_list_opt_else END { - if (!($$= new(thd->mem_root) Item_func_case_searched(thd, *$2))) + if (unlikely(!($$= new(thd->mem_root) Item_func_case_searched(thd, *$2)))) MYSQL_YYABORT; } | CASE_SYM expr when_list_opt_else END { $3->push_front($2, thd->mem_root); - if (!($$= new (thd->mem_root) Item_func_case_simple(thd, *$3))) + if (unlikely(!($$= new (thd->mem_root) Item_func_case_simple(thd, *$3)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr ',' cast_type ')' { - if (!($$= $5.create_typecast_item(thd, $3, Lex->charset))) + if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' { $$= new (thd->mem_root) Item_func_conv_charset(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DEFAULT '(' simple_ident ')' { Item_splocal *il= $3->get_item_splocal(); - if (il) + if (unlikely(il)) my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str)); $$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(), $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->default_used= TRUE; } @@ -10021,64 +10077,66 @@ column_default_non_parenthesized_expr: { $$= new (thd->mem_root) Item_insert_value(thd, Lex->current_context(), $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NEXT_SYM VALUE_SYM FOR_SYM table_ident { - if (!($$= Lex->create_item_func_nextval(thd, $4))) + if (unlikely(!($$= Lex->create_item_func_nextval(thd, $4)))) MYSQL_YYABORT; } | NEXTVAL_SYM '(' table_ident ')' { - if (!($$= Lex->create_item_func_nextval(thd, $3))) + if (unlikely(!($$= Lex->create_item_func_nextval(thd, $3)))) MYSQL_YYABORT; } | PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident { - if (!($$= Lex->create_item_func_lastval(thd, $4))) + if (unlikely(!($$= Lex->create_item_func_lastval(thd, $4)))) MYSQL_YYABORT; } | LASTVAL_SYM '(' table_ident ')' { - if (!($$= Lex->create_item_func_lastval(thd, $3))) + if (unlikely(!($$= Lex->create_item_func_lastval(thd, $3)))) MYSQL_YYABORT; } | SETVAL_SYM '(' table_ident ',' longlong_num ')' { - if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1))) + if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1)))) MYSQL_YYABORT; } | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ')' { - if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7))) + if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7)))) MYSQL_YYABORT; } | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ',' ulonglong_num ')' { - if (!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7))) + if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7)))) MYSQL_YYABORT; } ; -simple_expr: +primary_expr: column_default_non_parenthesized_expr - | simple_expr COLLATE_SYM collation_name %prec NEG - { - if (!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3))) - MYSQL_YYABORT; - } | '(' parenthesized_expr ')' { $$= $2; } - | BINARY simple_expr %prec NEG + ; + +string_factor_expr: + primary_expr + | string_factor_expr COLLATE_SYM collation_name { - Type_cast_attributes at(&my_charset_bin); - if (!($$= type_handler_long_blob.create_typecast_item(thd, $2, at))) + if (unlikely(!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3)))) MYSQL_YYABORT; } - | simple_expr OR_OR_SYM simple_expr + ; + +simple_expr: + string_factor_expr %prec NEG + | BINARY simple_expr { - $$= new (thd->mem_root) Item_func_concat(thd, $1, $3); - if ($$ == NULL) + Type_cast_attributes at(&my_charset_bin); + if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at)))) MYSQL_YYABORT; } | '+' simple_expr %prec NEG @@ -10088,26 +10146,29 @@ simple_expr: | '-' simple_expr %prec NEG { $$= $2->neg(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | '~' simple_expr %prec NEG { $$= new (thd->mem_root) Item_func_bit_neg(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | not2 simple_expr %prec NEG { $$= negate_expression(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM - /* we cannot put interval before - */ + ; + +mysql_concatenation_expr: + simple_expr + | mysql_concatenation_expr MYSQL_CONCAT_SYM simple_expr { - $$= new (thd->mem_root) Item_date_add_interval(thd, $5, $2, $3, 0); - if ($$ == NULL) + $$= new (thd->mem_root) Item_func_concat(thd, $1, $3); + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -10117,13 +10178,13 @@ function_call_keyword_timestamp: { $$= new (thd->mem_root) Item_datetime_typecast(thd, $3, AUTO_SEC_PART_DIGITS); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TIMESTAMP '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_add_time(thd, $3, $5, 1, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -10137,20 +10198,20 @@ function_call_keyword: CHAR_SYM '(' expr_list ')' { $$= new (thd->mem_root) Item_func_char(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CHAR_SYM '(' expr_list USING charset_name ')' { $$= new (thd->mem_root) Item_func_char(thd, *$3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CURRENT_USER optional_braces { $$= new (thd->mem_root) Item_func_current_user(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -10159,7 +10220,7 @@ function_call_keyword: { $$= new (thd->mem_root) Item_func_current_role(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -10167,87 +10228,88 @@ function_call_keyword: | DATE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_date_typecast(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DAY_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_dayofmonth(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | HOUR_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_hour(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | INSERT '(' expr ',' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_insert(thd, $3, $5, $7, $9); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | INTERVAL_SYM '(' expr ',' expr ')' %prec INTERVAL_SYM + | INTERVAL_SYM '(' expr ',' expr ')' { List<Item> *list= new (thd->mem_root) List<Item>; - if (list == NULL) + if (unlikely(list == NULL)) + MYSQL_YYABORT; + if (unlikely(list->push_front($5, thd->mem_root)) || + unlikely(list->push_front($3, thd->mem_root))) MYSQL_YYABORT; - list->push_front($5, thd->mem_root); - list->push_front($3, thd->mem_root); Item_row *item= new (thd->mem_root) Item_row(thd, *list); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_interval(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' %prec INTERVAL_SYM + | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' { $7->push_front($5, thd->mem_root); $7->push_front($3, thd->mem_root); Item_row *item= new (thd->mem_root) Item_row(thd, *$7); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_interval(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LEFT '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_left(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MINUTE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_minute(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MONTH_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_month(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | RIGHT '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_right(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SECOND_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_second(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TIME_SYM '(' expr ')' { $$= new (thd->mem_root) Item_time_typecast(thd, $3, AUTO_SEC_PART_DIGITS); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | function_call_keyword_timestamp @@ -10256,13 +10318,13 @@ function_call_keyword: } | TRIM '(' trim_operands ')' { - if (!($$= $3.make_item_func_trim(thd))) + if (unlikely(!($$= $3.make_item_func_trim(thd)))) MYSQL_YYABORT; } | USER_SYM '(' ')' { $$= new (thd->mem_root) Item_func_user(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query=0; @@ -10270,7 +10332,7 @@ function_call_keyword: | YEAR_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_year(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -10292,117 +10354,115 @@ function_call_nonkeyword: { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $5, INTERVAL_DAY, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CURDATE optional_braces { $$= new (thd->mem_root) Item_func_curdate_local(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | CURTIME opt_time_precision { $$= new (thd->mem_root) Item_func_curtime_local(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')' - %prec INTERVAL_SYM { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')' - %prec INTERVAL_SYM { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATE_FORMAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DECODE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_decode(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | GET_FORMAT '(' date_time_type ',' expr ')' { $$= new (thd->mem_root) Item_func_get_format(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NOW_SYM opt_time_precision { $$= new (thd->mem_root) Item_func_now_local(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | POSITION_SYM '(' bit_expr IN_SYM expr ')' { $$= new (thd->mem_root) Item_func_locate(thd, $5, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUBDATE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $5, INTERVAL_DAY, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUBSTRING '(' expr ',' expr ',' expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5, $7))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7)))) MYSQL_YYABORT; } | SUBSTRING '(' expr ',' expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5)))) MYSQL_YYABORT; } | SUBSTRING '(' expr FROM expr FOR_SYM expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5, $7))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7)))) MYSQL_YYABORT; } | SUBSTRING '(' expr FROM expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5)))) MYSQL_YYABORT; } | SYSDATE opt_time_precision @@ -10419,45 +10479,45 @@ function_call_nonkeyword: $$= new (thd->mem_root) Item_func_sysdate_local(thd, $2); else $$= new (thd->mem_root) Item_func_now_local(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $7, $5, $3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_timestamp_diff(thd, $5, $7, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TRIM_ORACLE '(' trim_operands ')' { - if (!($$= $3.make_item_func_trim_oracle(thd))) + if (unlikely(!($$= $3.make_item_func_trim_oracle(thd)))) MYSQL_YYABORT; } | UTC_DATE_SYM optional_braces { $$= new (thd->mem_root) Item_func_curdate_utc(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | UTC_TIME_SYM opt_time_precision { $$= new (thd->mem_root) Item_func_curtime_utc(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | UTC_TIMESTAMP_SYM opt_time_precision { $$= new (thd->mem_root) Item_func_now_utc(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } @@ -10465,28 +10525,28 @@ function_call_nonkeyword: COLUMN_ADD_SYM '(' expr ',' dyncall_create_list ')' { $$= create_func_dyncol_add(thd, $3, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLUMN_DELETE_SYM '(' expr ',' expr_list ')' { $$= create_func_dyncol_delete(thd, $3, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLUMN_CHECK_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_dyncol_check(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLUMN_CREATE_SYM '(' dyncall_create_list ')' { $$= create_func_dyncol_create(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | @@ -10496,7 +10556,7 @@ function_call_nonkeyword: $$= create_func_dyncol_get(thd, $3, $5, $7.type_handler(), $7.length(), $7.dec(), lex->charset); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -10510,50 +10570,50 @@ function_call_conflict: ASCII_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_ascii(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CHARSET '(' expr ')' { $$= new (thd->mem_root) Item_func_charset(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COALESCE '(' expr_list ')' { $$= new (thd->mem_root) Item_func_coalesce(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLLATION_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_collation(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATABASE '(' ')' { $$= new (thd->mem_root) Item_func_database(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | IF_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_if(thd, $3, $5, $7); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | FORMAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_format(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | FORMAT_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_format(thd, $3, $5, $7); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } /* LAST_VALUE here conflicts with the definition for window functions. @@ -10562,75 +10622,75 @@ function_call_conflict: | LAST_VALUE '(' expr ')' { List<Item> *list= new (thd->mem_root) List<Item>; - if (list == NULL) + if (unlikely(list == NULL)) MYSQL_YYABORT; list->push_back($3, thd->mem_root); $$= new (thd->mem_root) Item_func_last_value(thd, *list); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LAST_VALUE '(' expr_list ',' expr ')' { $3->push_back($5, thd->mem_root); $$= new (thd->mem_root) Item_func_last_value(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MICROSECOND_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_microsecond(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MOD_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_mod(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | OLD_PASSWORD_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_password(thd, $3, Item_func_password::OLD); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | PASSWORD_SYM '(' expr ')' { Item* i1; i1= new (thd->mem_root) Item_func_password(thd, $3); - if (i1 == NULL) + if (unlikely(i1 == NULL)) MYSQL_YYABORT; $$= i1; } | QUARTER_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_quarter(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | REPEAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_repeat(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | REPLACE '(' expr ',' expr ',' expr ')' { - if (!($$= Lex->make_item_func_replace(thd, $3, $5, $7))) + if (unlikely(!($$= Lex->make_item_func_replace(thd, $3, $5, $7)))) MYSQL_YYABORT; } | REVERSE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_reverse(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ROW_COUNT_SYM '(' ')' { $$= new (thd->mem_root) Item_func_row_count(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -10638,25 +10698,25 @@ function_call_conflict: | TRUNCATE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_round(thd, $3, $5, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEEK_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_week(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEEK_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_week(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr opt_ws_levels ')' { $$= new (thd->mem_root) Item_func_weight_string(thd, $3, 0, 0, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr AS CHAR_SYM ws_nweights opt_ws_levels ')' @@ -10664,26 +10724,26 @@ function_call_conflict: $$= new (thd->mem_root) Item_func_weight_string(thd, $3, 0, $6, $7 | MY_STRXFRM_PAD_WITH_SPACE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr AS BINARY ws_nweights ')' { Item *item= new (thd->mem_root) Item_char_typecast(thd, $3, $6, &my_charset_bin); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_weight_string(thd, item, 0, $6, MY_STRXFRM_PAD_WITH_SPACE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr ',' ulong_num ',' ulong_num ',' ulong_num ')' { $$= new (thd->mem_root) Item_func_weight_string(thd, $3, $5, $7, $9); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | geometry_function @@ -10691,7 +10751,7 @@ function_call_conflict: #ifdef HAVE_SPATIAL $$= $1; /* $1 may be NULL, GEOM_NEW not tested for out of memory */ - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; #else my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, @@ -10779,7 +10839,7 @@ function_call_generic: (udf= find_udf($1.str, $1.length)) && udf->type == UDFTYPE_AGGREGATE) { - if (lex->current_select->inc_in_sum_expr()) + if (unlikely(lex->current_select->inc_in_sum_expr())) { thd->parse_error(); MYSQL_YYABORT; @@ -10794,10 +10854,8 @@ function_call_generic: Create_func *builder; Item *item= NULL; - if (check_routine_name(&$1)) - { + if (unlikely(check_routine_name(&$1))) MYSQL_YYABORT; - } /* Implementation note: @@ -10837,45 +10895,13 @@ function_call_generic: } } - if (! ($$= item)) - { + if (unlikely(! ($$= item))) MYSQL_YYABORT; - } } - | ident '.' ident '(' opt_expr_list ')' + | ident_cli '.' ident_cli '(' opt_expr_list ')' { - Create_qfunc *builder; - Item *item= NULL; - - /* - The following in practice calls: - <code>Create_sp_func::create()</code> - and builds a stored function. - - However, it's important to maintain the interface between the - parser and the implementation in item_create.cc clean, - since this will change with WL#2128 (SQL PATH): - - INFORMATION_SCHEMA.version() is the SQL 99 syntax for the native - function version(), - - MySQL.version() is the SQL 2003 syntax for the native function - version() (a vendor can specify any schema). - */ - - if (!$1.str || check_db_name((LEX_STRING*) &$1)) - my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); - if (check_routine_name(&$3)) - { - MYSQL_YYABORT; - } - - builder= find_qualified_function_builder(thd); - DBUG_ASSERT(builder); - item= builder->create_with_db(thd, &$1, &$3, true, $5); - - if (! ($$= item)) - { + if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5)))) MYSQL_YYABORT; - } } ; @@ -10905,7 +10931,7 @@ udf_expr_list: udf_expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->push_back($1, thd->mem_root); } @@ -10947,46 +10973,46 @@ sum_expr: AVG_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_avg(thd, $3, FALSE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | AVG_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_avg(thd, $4, TRUE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIT_AND '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_and(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIT_OR '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_or(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIT_XOR '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_xor(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COUNT_SYM '(' opt_all '*' ')' { Item *item= new (thd->mem_root) Item_int(thd, (int32) 0L, 1); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_count(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COUNT_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_count(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COUNT_SYM '(' DISTINCT @@ -10996,13 +11022,13 @@ sum_expr: ')' { $$= new (thd->mem_root) Item_sum_count(thd, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MIN_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_min(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } /* @@ -11013,55 +11039,55 @@ sum_expr: | MIN_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_min(thd, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MAX_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_max(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MAX_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_max(thd, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | STD_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_std(thd, $3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | VARIANCE_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_variance(thd, $3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | STDDEV_SAMP_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_std(thd, $3, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | VAR_SAMP_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_variance(thd, $3, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUM_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_sum(thd, $3, FALSE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUM_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_sum(thd, $4, TRUE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | GROUP_CONCAT_SYM '(' opt_distinct @@ -11078,7 +11104,7 @@ sum_expr: sel->gorder_list, $7, $8, sel->select_limit, sel->offset_limit); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; sel->select_limit= NULL; sel->offset_limit= NULL; @@ -11092,25 +11118,25 @@ window_func_expr: window_func OVER_SYM window_name { $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; - if (Select->add_window_func((Item_window_func *) $$)) + if (unlikely(Select->add_window_func((Item_window_func *) $$))) MYSQL_YYABORT; } | window_func OVER_SYM window_spec { LEX *lex= Lex; - if (Select->add_window_spec(thd, lex->win_ref, - Select->group_list, - Select->order_list, - lex->win_frame)) + if (unlikely(Select->add_window_spec(thd, lex->win_ref, + Select->group_list, + Select->order_list, + lex->win_frame))) MYSQL_YYABORT; $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, thd->lex->win_spec); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; - if (Select->add_window_func((Item_window_func *) $$)) + if (unlikely(Select->add_window_func((Item_window_func *) $$))) MYSQL_YYABORT; } ; @@ -11128,63 +11154,63 @@ simple_window_func: ROW_NUMBER_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_row_number(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | RANK_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_rank(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DENSE_RANK_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_dense_rank(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | PERCENT_RANK_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_percent_rank(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CUME_DIST_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_cume_dist(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NTILE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_ntile(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | FIRST_VALUE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_first_value(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LAST_VALUE '(' expr ')' { $$= new (thd->mem_root) Item_sum_last_value(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NTH_VALUE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_sum_nth_value(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | @@ -11192,17 +11218,17 @@ simple_window_func: { /* No second argument defaults to 1. */ Item* item_offset= new (thd->mem_root) Item_uint(thd, 1); - if (item_offset == NULL) + if (unlikely(item_offset == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_lead(thd, $3, item_offset); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LEAD_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_sum_lead(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | @@ -11210,17 +11236,17 @@ simple_window_func: { /* No second argument defaults to 1. */ Item* item_offset= new (thd->mem_root) Item_uint(thd, 1); - if (item_offset == NULL) + if (unlikely(item_offset == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_lag(thd, $3, item_offset); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LAG_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_sum_lag(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -11232,16 +11258,16 @@ inverse_distribution_function: '(' opt_window_partition_clause ')' { LEX *lex= Lex; - if (Select->add_window_spec(thd, lex->win_ref, - Select->group_list, - Select->order_list, - NULL)) + if (unlikely(Select->add_window_spec(thd, lex->win_ref, + Select->group_list, + Select->order_list, + NULL))) MYSQL_YYABORT; $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, thd->lex->win_spec); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; - if (Select->add_window_func((Item_window_func *) $$)) + if (unlikely(Select->add_window_func((Item_window_func *) $$))) MYSQL_YYABORT; } ; @@ -11257,14 +11283,14 @@ percentile_function: { Item *args= new (thd->mem_root) Item_decimal(thd, "0.5", 3, thd->charset()); - if (($$ == NULL) || (thd->is_error())) - { + if (unlikely(args == NULL) || unlikely(thd->is_error())) + MYSQL_YYABORT; + Select->prepare_add_window_spec(thd); + if (unlikely(add_order_to_list(thd, $3,FALSE))) MYSQL_YYABORT; - } - if (add_order_to_list(thd, $3,FALSE)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_percentile_cont(thd, args); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -11273,20 +11299,23 @@ inverse_distribution_function_def: PERCENTILE_CONT_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_percentile_cont(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | PERCENTILE_DISC_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_percentile_disc(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; order_by_single_element_list: ORDER_SYM BY order_ident order_dir - { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_order_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } ; @@ -11294,7 +11323,7 @@ window_name: ident { $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -11302,7 +11331,7 @@ window_name: variable: '@' { - if (! Lex->parsing_options.allows_variable) + if (unlikely(! Lex->parsing_options.allows_variable)) my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0))); } variable_aux @@ -11316,7 +11345,7 @@ variable_aux: { Item_func_set_user_var *item; $$= item= new (thd->mem_root) Item_func_set_user_var(thd, &$1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); @@ -11325,23 +11354,20 @@ variable_aux: | ident_or_text { $$= new (thd->mem_root) Item_func_get_user_var(thd, &$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } - | '@' opt_var_ident_type ident_or_text opt_component + | '@' opt_var_ident_type ident_sysvar_name { - /* disallow "SELECT @@global.global.variable" */ - if ($3.str && $4.str && check_reserved_words(&$3)) - { - thd->parse_error(); + if (unlikely(!($$= Lex->make_item_sysvar(thd, $2, &$3)))) MYSQL_YYABORT; - } - if (!($$= get_system_var(thd, $2, &$3, &$4))) + } + | '@' opt_var_ident_type ident_sysvar_name '.' ident + { + if (unlikely(!($$= Lex->make_item_sysvar(thd, $2, &$3, &$5)))) MYSQL_YYABORT; - if (!((Item_func_get_system_var*) $$)->is_written_to_binlog()) - Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE); } ; @@ -11354,7 +11380,7 @@ opt_gconcat_separator: /* empty */ { $$= new (thd->mem_root) String(",", 1, &my_charset_latin1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SEPARATOR_SYM text_string { $$ = $2; } @@ -11367,9 +11393,15 @@ opt_gorder_clause: gorder_list: gorder_list ',' order_ident order_dir - { if (add_gorder_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_gorder_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + if (unlikely(add_gorder_to_list(thd, $1,(bool) $2))) + MYSQL_YYABORT; + } ; opt_glimit_clause: @@ -11418,7 +11450,7 @@ in_sum_expr: opt_all { LEX *lex= Lex; - if (lex->current_select->inc_in_sum_expr()) + if (unlikely(lex->current_select->inc_in_sum_expr())) { thd->parse_error(); MYSQL_YYABORT; @@ -11472,9 +11504,9 @@ expr_list: expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); } | expr_list ',' expr { @@ -11492,9 +11524,9 @@ ident_list: simple_ident { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); } | ident_list ',' simple_ident { @@ -11507,15 +11539,17 @@ when_list: WHEN_SYM expr THEN_SYM expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + if (unlikely($$->push_back($2, thd->mem_root) || + $$->push_back($4, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($2, thd->mem_root); - $$->push_back($4, thd->mem_root); } | when_list WHEN_SYM expr THEN_SYM expr { - $1->push_back($3, thd->mem_root); - $1->push_back($5, thd->mem_root); + if (unlikely($1->push_back($3, thd->mem_root) || + $1->push_back($5, thd->mem_root))) + MYSQL_YYABORT; $$= $1; } ; @@ -11524,7 +11558,8 @@ when_list_opt_else: when_list | when_list ELSE expr { - $1->push_back($3, thd->mem_root); + if (unlikely($1->push_back($3, thd->mem_root))) + MYSQL_YYABORT; $$= $1; } ; @@ -11536,7 +11571,7 @@ table_ref: | join_table { LEX *lex= Lex; - if (!($$= lex->current_select->nest_last_join(thd))) + if (unlikely(!($$= lex->current_select->nest_last_join(thd)))) { thd->parse_error(); MYSQL_YYABORT; @@ -11591,7 +11626,7 @@ join_table: { MYSQL_YYABORT_UNLESS($1 && $3); /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(thd, $1, $3)) + if (unlikely(push_new_name_resolution_context(thd, $1, $3))) MYSQL_YYABORT; Select->parsing_place= IN_ON; } @@ -11608,7 +11643,7 @@ join_table: MYSQL_YYABORT_UNLESS($1 && $3); } '(' using_list ')' - { + { $3->straight=$2; add_join_natural($1,$3,$7,Select); $$=$3; @@ -11626,7 +11661,7 @@ join_table: { MYSQL_YYABORT_UNLESS($1 && $5); /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(thd, $1, $5)) + if (unlikely(push_new_name_resolution_context(thd, $1, $5))) MYSQL_YYABORT; Select->parsing_place= IN_ON; } @@ -11662,14 +11697,14 @@ join_table: { MYSQL_YYABORT_UNLESS($1 && $5); /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(thd, $1, $5)) + if (unlikely(push_new_name_resolution_context(thd, $1, $5))) MYSQL_YYABORT; Select->parsing_place= IN_ON; } expr { LEX *lex= Lex; - if (!($$= lex->current_select->convert_right_join())) + if (unlikely(!($$= lex->current_select->convert_right_join()))) MYSQL_YYABORT; add_join_on(thd, $$, $8); Lex->pop_context(); @@ -11682,7 +11717,7 @@ join_table: USING '(' using_list ')' { LEX *lex= Lex; - if (!($$= lex->current_select->convert_right_join())) + if (unlikely(!($$= lex->current_select->convert_right_join()))) MYSQL_YYABORT; add_join_natural($$,$5,$9,Select); } @@ -11691,7 +11726,7 @@ join_table: MYSQL_YYABORT_UNLESS($1 && $6); add_join_natural($6,$1,NULL,Select); LEX *lex= Lex; - if (!($$= lex->current_select->convert_right_join())) + if (unlikely(!($$= lex->current_select->convert_right_join()))) MYSQL_YYABORT; } ; @@ -11745,12 +11780,13 @@ table_primary_ident: } table_ident opt_use_partition opt_for_system_time_clause opt_table_alias opt_key_definition { - if (!($$= Select->add_table_to_list(thd, $2, $5, - Select->get_table_join_options(), - YYPS->m_lock_type, - YYPS->m_mdl_type, - Select->pop_index_hints(), - $3))) + if (unlikely(!($$= Select->add_table_to_list(thd, $2, $5, + Select->get_table_join_options(), + YYPS->m_lock_type, + YYPS->m_mdl_type, + Select-> + pop_index_hints(), + $3)))) MYSQL_YYABORT; Select->add_joined_table($$); if ($4) @@ -11801,18 +11837,18 @@ table_primary_derived: SELECT_LEX_UNIT *unit= sel->master_unit(); lex->current_select= sel= unit->outer_select(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; - if (!($$= sel->add_table_to_list(thd, - ti, $6, 0, - TL_READ, MDL_SHARED_READ))) - + if (unlikely(!($$= sel->add_table_to_list(thd, + ti, $6, 0, + TL_READ, + MDL_SHARED_READ)))) MYSQL_YYABORT; sel->add_joined_table($$); lex->pop_context(); lex->nest_level--; } - else if ($6 != NULL) + else if (unlikely($6 != NULL)) { /* Tables with or without joins within parentheses cannot @@ -11851,13 +11887,14 @@ table_primary_derived: SELECT_LEX *sel= $2; SELECT_LEX_UNIT *unit= $5->master_unit(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; $5->set_with_clause($4); lex->current_select= sel; - if (!($$= sel->add_table_to_list(lex->thd, - ti, $9, 0, - TL_READ, MDL_SHARED_READ))) + if (unlikely(!($$= sel->add_table_to_list(lex->thd, + ti, $9, 0, + TL_READ, + MDL_SHARED_READ)))) MYSQL_YYABORT; sel->add_joined_table($$); if ($8) @@ -11888,7 +11925,7 @@ select_derived_union: select_derived | select_derived union_order_or_limit { - if ($1) + if (unlikely($1)) { thd->parse_error(); MYSQL_YYABORT; @@ -11896,7 +11933,7 @@ select_derived_union: } | select_derived union_head_non_top { - if ($1) + if (unlikely($1)) { thd->parse_error(); MYSQL_YYABORT; @@ -11950,9 +11987,9 @@ select_derived: /* for normal joins, $2 != NULL and end_nested_join() != NULL, for derived tables, both must equal NULL */ - if (!($$= $1->end_nested_join(lex->thd)) && $2) + if (unlikely(!($$= $1->end_nested_join(lex->thd)) && $2)) MYSQL_YYABORT; - if (!$2 && $$) + if (unlikely(!$2 && $$)) { thd->parse_error(); MYSQL_YYABORT; @@ -11981,33 +12018,12 @@ derived_query_specification: derived_table_value_constructor: VALUES { - LEX *lex=Lex; - lex->field_list.empty(); - lex->many_values.empty(); - lex->insert_list=0; - } + Lex->tvc_start(); + } values_list { - LEX *lex= Lex; - lex->derived_tables|= DERIVED_SUBQUERY; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) - { - thd->parse_error(); - MYSQL_YYABORT; - } - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || - mysql_new_select(lex, 1, NULL)) + if (Lex->tvc_finalize_derived()) MYSQL_YYABORT; - mysql_init_select(lex); - lex->current_select->linkage= DERIVED_TABLE_TYPE; - - if (!(lex->current_select->tvc= - new (lex->thd->mem_root) table_value_constr(lex->many_values, - lex->current_select, - lex->current_select->options))) - MYSQL_YYABORT; - lex->many_values.empty(); $$= NULL; } ; @@ -12017,14 +12033,14 @@ select_derived2: { LEX *lex= Lex; lex->derived_tables|= DERIVED_SUBQUERY; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) + if (unlikely(!lex->expr_allows_subselect || + lex->sql_command == (int)SQLCOM_PURGE)) { thd->parse_error(); MYSQL_YYABORT; } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || - mysql_new_select(lex, 1, NULL)) + unlikely(mysql_new_select(lex, 1, NULL))) MYSQL_YYABORT; mysql_init_select(lex); lex->current_select->linkage= DERIVED_TABLE_TYPE; @@ -12045,7 +12061,7 @@ get_select_lex_derived: get_select_lex { LEX *lex= Lex; - if ($1->init_nested_join(lex->thd)) + if (unlikely($1->init_nested_join(lex->thd))) MYSQL_YYABORT; } ; @@ -12129,12 +12145,12 @@ key_usage_list: using_list: ident { - if (!($$= new (thd->mem_root) List<String>)) + if (unlikely(!($$= new (thd->mem_root) List<String>))) MYSQL_YYABORT; String *s= new (thd->mem_root) String((const char *) $1.str, $1.length, system_charset_info); - if (s == NULL) + if (unlikely(unlikely(s == NULL))) MYSQL_YYABORT; $$->push_back(s, thd->mem_root); } @@ -12143,9 +12159,10 @@ using_list: String *s= new (thd->mem_root) String((const char *) $3.str, $3.length, system_charset_info); - if (s == NULL) + if (unlikely(unlikely(s == NULL))) + MYSQL_YYABORT; + if (unlikely($1->push_back(s, thd->mem_root))) MYSQL_YYABORT; - $1->push_back(s, thd->mem_root); $$= $1; } ; @@ -12195,7 +12212,7 @@ opt_table_alias: | table_alias ident_table_alias { $$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12249,7 +12266,7 @@ opt_escape: $$= ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ? new (thd->mem_root) Item_string_ascii(thd, "", 0) : new (thd->mem_root) Item_string_ascii(thd, "\\", 1)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12265,9 +12282,15 @@ opt_group_clause: group_list: group_list ',' order_ident order_dir - { if (add_group_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_group_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_group_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + if (unlikely(add_group_to_list(thd, $1,(bool) $2))) + MYSQL_YYABORT; + } ; olap_opt: @@ -12282,7 +12305,7 @@ olap_opt: SQL-2003: GROUP BY ... CUBE(col1, col2, col3) */ LEX *lex=Lex; - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + if (unlikely(lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "WITH CUBE", "global union parameters")); lex->current_select->olap= CUBE_TYPE; @@ -12299,7 +12322,7 @@ olap_opt: SQL-2003: GROUP BY ... ROLLUP(col1, col2, col3) */ LEX *lex= Lex; - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + if (unlikely(lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "WITH ROLLUP", "global union parameters")); lex->current_select->olap= ROLLUP_TYPE; @@ -12327,10 +12350,10 @@ window_def: window_name AS window_spec { LEX *lex= Lex; - if (Select->add_window_def(thd, $1, lex->win_ref, - Select->group_list, - Select->order_list, - lex->win_frame)) + if (unlikely(Select->add_window_def(thd, $1, lex->win_ref, + Select->group_list, + Select->order_list, + lex->win_frame))) MYSQL_YYABORT; } ; @@ -12348,7 +12371,7 @@ opt_window_ref: | ident { thd->lex->win_ref= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - if (thd->lex->win_ref == NULL) + if (unlikely(thd->lex->win_ref == NULL)) MYSQL_YYABORT; } @@ -12372,7 +12395,7 @@ opt_window_frame_clause: lex->frame_top_bound, lex->frame_bottom_bound, $3); - if (lex->win_frame == NULL) + if (unlikely(lex->win_frame == NULL)) MYSQL_YYABORT; } ; @@ -12390,7 +12413,7 @@ window_frame_extent: lex->frame_bottom_bound= new (thd->mem_root) Window_frame_bound(Window_frame_bound::CURRENT, NULL); - if (lex->frame_bottom_bound == NULL) + if (unlikely(lex->frame_bottom_bound == NULL)) MYSQL_YYABORT; } | BETWEEN_SYM window_frame_bound AND_SYM window_frame_bound @@ -12406,21 +12429,21 @@ window_frame_start: { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::PRECEDING, NULL); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CURRENT_SYM ROW_SYM { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::CURRENT, NULL); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | literal PRECEDING_SYM { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::PRECEDING, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12431,14 +12454,14 @@ window_frame_bound: { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::FOLLOWING, NULL); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | literal FOLLOWING_SYM { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::FOLLOWING, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12472,7 +12495,7 @@ alter_order_item: simple_ident_nospvar order_dir { bool ascending= ($2 == 1) ? true : false; - if (add_order_to_list(thd, $1, ascending)) + if (unlikely(add_order_to_list(thd, $1, ascending))) MYSQL_YYABORT; } ; @@ -12492,9 +12515,9 @@ order_clause: LEX *lex=Lex; SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel-> master_unit(); - if (sel->linkage != GLOBAL_OPTIONS_TYPE && - sel->olap != UNSPECIFIED_OLAP_TYPE && - (sel->linkage != UNION_TYPE || sel->braces)) + if (unlikely(sel->linkage != GLOBAL_OPTIONS_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE && + (sel->linkage != UNION_TYPE || sel->braces))) { my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY"); @@ -12508,14 +12531,14 @@ order_clause: executed in the same way as the query SELECT ... ORDER BY order_list unless the SELECT construct contains ORDER BY or LIMIT clauses. - Otherwise we create a fake SELECT_LEX if it has not been created - yet. + Otherwise we create a fake SELECT_LEX if it has not been + created yet. */ SELECT_LEX *first_sl= unit->first_select(); - if (!unit->is_unit_op() && - (first_sl->order_list.elements || - first_sl->select_limit) && - unit->add_fake_select_lex(thd)) + if (unlikely(!unit->is_unit_op() && + (first_sl->order_list.elements || + first_sl->select_limit) && + unit->add_fake_select_lex(thd))) MYSQL_YYABORT; } if (sel->master_unit()->is_unit_op() && !sel->braces) @@ -12538,9 +12561,15 @@ order_clause: order_list: order_list ',' order_ident order_dir - { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_order_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + if (unlikely(add_order_to_list(thd, $1,(bool) $2))) + MYSQL_YYABORT; + } ; order_dir: @@ -12611,42 +12640,36 @@ limit_options: ; limit_option: - ident_with_tok_start - { - LEX *lex= thd->lex; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; - if (!($$= lex->create_item_limit(thd, &$1, - $1.m_pos, lip->get_tok_end()))) - MYSQL_YYABORT; - } - | ident_with_tok_start '.' ident - { - LEX *lex= thd->lex; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; - if (!($$= lex->create_item_limit(thd, &$1, &$3, - $1.m_pos, lip->get_ptr()))) - MYSQL_YYABORT; - } + ident_cli + { + if (unlikely(!($$= Lex->create_item_limit(thd, &$1)))) + MYSQL_YYABORT; + } + | ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->create_item_limit(thd, &$1, &$3)))) + MYSQL_YYABORT; + } | param_marker - { - $1->limit_clause_param= TRUE; - } + { + $1->limit_clause_param= TRUE; + } | ULONGLONG_NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LONG_NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12758,9 +12781,9 @@ procedure_clause: Item_field *item= new (thd->mem_root) Item_field(thd, &lex->current_select->context, NULL, NULL, &$2); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; - if (add_proc_to_list(thd, item)) + if (unlikely(add_proc_to_list(thd, item))) MYSQL_YYABORT; Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); @@ -12792,7 +12815,7 @@ procedure_list2: procedure_item: remember_name expr remember_end { - if (add_proc_to_list(thd, $2)) + if (unlikely(add_proc_to_list(thd, $2))) MYSQL_YYABORT; if (!$2->name.str || $2->name.str == item_empty_name) $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); @@ -12803,7 +12826,8 @@ select_var_list_init: { LEX *lex=Lex; if (!lex->describe && - (!(lex->result= new (thd->mem_root) select_dumpvar(thd)))) + unlikely((!(lex->result= new (thd->mem_root) + select_dumpvar(thd))))) MYSQL_YYABORT; } select_var_list @@ -12819,7 +12843,7 @@ select_var_ident: select_outvar { if (Lex->result) { - if ($1 == NULL) + if (unlikely($1 == NULL)) MYSQL_YYABORT; ((select_dumpvar *)Lex->result)->var_list.push_back($1, thd->mem_root); } @@ -12841,12 +12865,12 @@ select_outvar: } | ident_or_text { - if (!($$= Lex->create_outvar(thd, &$1)) && Lex->result) + if (unlikely(!($$= Lex->create_outvar(thd, &$1)) && Lex->result)) MYSQL_YYABORT; } | ident '.' ident { - if (!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result) + if (unlikely(!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result)) MYSQL_YYABORT; } ; @@ -12860,10 +12884,11 @@ into_destination: { LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - if (!(lex->exchange= - new (thd->mem_root) sql_exchange($2.str, 0)) || - !(lex->result= - new (thd->mem_root) select_export(thd, lex->exchange))) + if (unlikely(!(lex->exchange= + new (thd->mem_root) sql_exchange($2.str, 0))) || + unlikely(!(lex->result= + new (thd->mem_root) + select_export(thd, lex->exchange)))) MYSQL_YYABORT; } opt_load_data_charset @@ -12875,10 +12900,12 @@ into_destination: if (!lex->describe) { lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - if (!(lex->exchange= new (thd->mem_root) sql_exchange($2.str,1))) + if (unlikely(!(lex->exchange= + new (thd->mem_root) sql_exchange($2.str,1)))) MYSQL_YYABORT; - if (!(lex->result= - new (thd->mem_root) select_dump(thd, lex->exchange))) + if (unlikely(!(lex->result= + new (thd->mem_root) + select_dump(thd, lex->exchange)))) MYSQL_YYABORT; } } @@ -12924,16 +12951,16 @@ drop: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::KEY, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->sql_command= SQLCOM_DROP_INDEX; lex->alter_info.reset(); lex->alter_info.flags= ALTER_DROP_INDEX; lex->alter_info.drop_list.push_back(ad, thd->mem_root); - if (!lex->current_select->add_table_to_list(thd, $6, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_UPGRADABLE)) + if (unlikely(!lex->current_select-> + add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_UPGRADABLE))) MYSQL_YYABORT; } | DROP DATABASE opt_if_exists ident @@ -12946,13 +12973,13 @@ drop: { LEX *lex= thd->lex; sp_name *spname; - if ($4.str && check_db_name((LEX_STRING*) &$4)) - my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $4.str)); - if (lex->sphead) + if (unlikely($4.str && check_db_name((LEX_STRING*) &$4))) + my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $4.str)); + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); lex->set_command(SQLCOM_DROP_FUNCTION, $3); spname= new (thd->mem_root) sp_name(&$4, &$6, true); - if (spname == NULL) + if (unlikely(spname == NULL)) MYSQL_YYABORT; lex->spname= spname; } @@ -12961,20 +12988,20 @@ drop: LEX *lex= thd->lex; LEX_CSTRING db= {0, 0}; sp_name *spname; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); - if (thd->db.str && lex->copy_db_to(&db)) + if (thd->db.str && unlikely(lex->copy_db_to(&db))) MYSQL_YYABORT; lex->set_command(SQLCOM_DROP_FUNCTION, $3); spname= new (thd->mem_root) sp_name(&db, &$4, false); - if (spname == NULL) + if (unlikely(spname == NULL)) MYSQL_YYABORT; lex->spname= spname; } | DROP PROCEDURE_SYM opt_if_exists sp_name { LEX *lex=Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE")); lex->set_command(SQLCOM_DROP_PROCEDURE, $3); lex->spname= $4; @@ -13043,10 +13070,10 @@ table_list: table_name: table_ident { - if (!Select->add_table_to_list(thd, $1, NULL, - TL_OPTION_UPDATING, - YYPS->m_lock_type, - YYPS->m_mdl_type)) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, + TL_OPTION_UPDATING, + YYPS->m_lock_type, + YYPS->m_mdl_type))) MYSQL_YYABORT; } ; @@ -13054,12 +13081,12 @@ table_name: table_name_with_opt_use_partition: table_ident opt_use_partition { - if (!Select->add_table_to_list(thd, $1, NULL, - TL_OPTION_UPDATING, - YYPS->m_lock_type, - YYPS->m_mdl_type, - NULL, - $2)) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, + TL_OPTION_UPDATING, + YYPS->m_lock_type, + YYPS->m_mdl_type, + NULL, + $2))) MYSQL_YYABORT; } ; @@ -13072,10 +13099,12 @@ table_alias_ref_list: table_alias_ref: table_ident_opt_wild { - if (!Select->add_table_to_list(thd, $1, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, + if (unlikely(!Select-> + add_table_to_list(thd, $1, NULL, + (TL_OPTION_UPDATING | + TL_OPTION_ALIAS), YYPS->m_lock_type, - YYPS->m_mdl_type)) + YYPS->m_mdl_type))) MYSQL_YYABORT; } ; @@ -13160,10 +13189,9 @@ insert_lock_option: | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; } | DELAYED_SYM { - Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() - - thd->query()); - Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset + - YYLIP->yyLength() + 1; + // QQ: why was +1? + Lex->keyword_delayed_begin_offset= (uint)($1.pos() - thd->query()); + Lex->keyword_delayed_end_offset= (uint)($1.end() - thd->query()); $$= TL_WRITE_DELAYED; } | HIGH_PRIORITY { $$= TL_WRITE; } @@ -13173,10 +13201,8 @@ replace_lock_option: opt_low_priority { $$= $1; } | DELAYED_SYM { - Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() - - thd->query()); - Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset + - YYLIP->yyLength() + 1; + Lex->keyword_delayed_begin_offset= (uint)($1.pos() - thd->query()); + Lex->keyword_delayed_end_offset= (uint)($1.end() - thd->query()); $$= TL_WRITE_DELAYED; } ; @@ -13202,8 +13228,9 @@ insert_field_spec: | SET { LEX *lex=Lex; - if (!(lex->insert_list= new (thd->mem_root) List_item) || - lex->many_values.push_back(lex->insert_list, thd->mem_root)) + if (unlikely(!(lex->insert_list= new (thd->mem_root) List_item)) || + unlikely(lex->many_values.push_back(lex->insert_list, + thd->mem_root))) MYSQL_YYABORT; } ident_eq_list @@ -13235,8 +13262,8 @@ ident_eq_value: simple_ident_nospvar equal expr_or_default { LEX *lex=Lex; - if (lex->field_list.push_back($1, thd->mem_root) || - lex->insert_list->push_back($3, thd->mem_root)) + if (unlikely(lex->field_list.push_back($1, thd->mem_root)) || + unlikely(lex->insert_list->push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -13264,13 +13291,14 @@ opt_by: no_braces: '(' { - if (!(Lex->insert_list= new (thd->mem_root) List_item)) - MYSQL_YYABORT; + if (unlikely(!(Lex->insert_list= new (thd->mem_root) List_item))) + MYSQL_YYABORT; } opt_values ')' { LEX *lex=Lex; - if (lex->many_values.push_back(lex->insert_list, thd->mem_root)) + if (unlikely(lex->many_values.push_back(lex->insert_list, + thd->mem_root))) MYSQL_YYABORT; } ; @@ -13283,12 +13311,12 @@ opt_values: values: values ',' expr_or_default { - if (Lex->insert_list->push_back($3, thd->mem_root)) + if (unlikely(Lex->insert_list->push_back($3, thd->mem_root))) MYSQL_YYABORT; } | expr_or_default { - if (Lex->insert_list->push_back($1, thd->mem_root)) + if (unlikely(Lex->insert_list->push_back($1, thd->mem_root))) MYSQL_YYABORT; } ; @@ -13298,13 +13326,13 @@ expr_or_default: | DEFAULT { $$= new (thd->mem_root) Item_default_value(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | IGNORE_SYM { $$= new (thd->mem_root) Item_ignore_value(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -13338,7 +13366,7 @@ update: LEX *lex= Lex; if (lex->select_lex.table_list.elements > 1) lex->sql_command= SQLCOM_UPDATE_MULTI; - else if (lex->select_lex.get_table_list()->derived) + else if (unlikely(lex->select_lex.get_table_list()->derived)) { /* it is single table update and it is update of derived table */ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), @@ -13363,7 +13391,8 @@ update_list: update_elem: simple_ident_nospvar equal expr_or_default { - if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3)) + if (unlikely(add_item_to_list(thd, $1)) || + unlikely(add_value_to_list(thd, $3))) MYSQL_YYABORT; } ; @@ -13377,8 +13406,8 @@ insert_update_elem: simple_ident_nospvar equal expr_or_default { LEX *lex= Lex; - if (lex->update_list.push_back($1, thd->mem_root) || - lex->value_list.push_back($3, thd->mem_root)) + if (unlikely(lex->update_list.push_back($1, thd->mem_root)) || + unlikely(lex->value_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -13427,11 +13456,12 @@ delete_part2: delete_single_table: FROM table_ident opt_use_partition { - if (!Select->add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING, + if (unlikely(!Select-> + add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING, YYPS->m_lock_type, YYPS->m_mdl_type, NULL, - $3)) + $3))) MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_DEFAULT; YYPS->m_mdl_type= MDL_SHARED_READ; @@ -13452,7 +13482,7 @@ single_multi: } FROM join_table_list opt_where_clause { - if (multi_delete_set_locks_and_link_aux_tables(Lex)) + if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex))) MYSQL_YYABORT; } | FROM table_alias_ref_list @@ -13463,7 +13493,7 @@ single_multi: } USING join_table_list opt_where_clause { - if (multi_delete_set_locks_and_link_aux_tables(Lex)) + if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex))) MYSQL_YYABORT; } ; @@ -13482,27 +13512,31 @@ table_wild_one: ident opt_wild { Table_ident *ti= new (thd->mem_root) Table_ident(&$1); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; - if (!Select->add_table_to_list(thd, + if (unlikely(!Select-> + add_table_to_list(thd, ti, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, + (TL_OPTION_UPDATING | + TL_OPTION_ALIAS), YYPS->m_lock_type, - YYPS->m_mdl_type)) + YYPS->m_mdl_type))) MYSQL_YYABORT; } | ident '.' ident opt_wild { Table_ident *ti= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; - if (!Select->add_table_to_list(thd, + if (unlikely(!Select-> + add_table_to_list(thd, ti, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, + (TL_OPTION_UPDATING | + TL_OPTION_ALIAS), YYPS->m_lock_type, - YYPS->m_mdl_type)) + YYPS->m_mdl_type))) MYSQL_YYABORT; } ; @@ -13540,7 +13574,7 @@ truncate: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -13631,7 +13665,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_DATABASES; - if (prepare_schema_table(thd, lex, 0, SCH_SCHEMATA)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SCHEMATA))) MYSQL_YYABORT; } | opt_full TABLES opt_db wild_and_where @@ -13639,7 +13673,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))) MYSQL_YYABORT; } | opt_full TRIGGERS_SYM opt_db wild_and_where @@ -13647,7 +13681,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TRIGGERS; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))) MYSQL_YYABORT; } | EVENTS_SYM opt_db wild_and_where @@ -13655,7 +13689,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_EVENTS; lex->select_lex.db= $2; - if (prepare_schema_table(thd, lex, 0, SCH_EVENTS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_EVENTS))) MYSQL_YYABORT; } | TABLE_SYM STATUS_SYM opt_db wild_and_where @@ -13663,7 +13697,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLE_STATUS; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_TABLES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_TABLES))) MYSQL_YYABORT; } | OPEN_SYM TABLES opt_db wild_and_where @@ -13671,27 +13705,27 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))) MYSQL_YYABORT; } | PLUGINS_SYM { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_PLUGINS; - if (prepare_schema_table(thd, lex, 0, SCH_PLUGINS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PLUGINS))) MYSQL_YYABORT; } | PLUGINS_SYM SONAME_SYM TEXT_STRING_sys { Lex->ident= $3; Lex->sql_command= SQLCOM_SHOW_PLUGINS; - if (prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS)) + if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS))) MYSQL_YYABORT; } | PLUGINS_SYM SONAME_SYM wild_and_where { Lex->sql_command= SQLCOM_SHOW_PLUGINS; - if (prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS)) + if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS))) MYSQL_YYABORT; } | ENGINE_SYM known_storage_engines show_engine_param @@ -13704,7 +13738,7 @@ show_param: lex->sql_command= SQLCOM_SHOW_FIELDS; if ($5.str) $4->change_db(&$5); - if (prepare_schema_table(thd, lex, $4, SCH_COLUMNS)) + if (unlikely(prepare_schema_table(thd, lex, $4, SCH_COLUMNS))) MYSQL_YYABORT; } | master_or_binary LOGS_SYM @@ -13732,14 +13766,14 @@ show_param: lex->sql_command= SQLCOM_SHOW_KEYS; if ($4.str) $3->change_db(&$4); - if (prepare_schema_table(thd, lex, $3, SCH_STATISTICS)) + if (unlikely(prepare_schema_table(thd, lex, $3, SCH_STATISTICS))) MYSQL_YYABORT; } | opt_storage ENGINES_SYM { LEX *lex=Lex; lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES; - if (prepare_schema_table(thd, lex, 0, SCH_ENGINES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_ENGINES))) MYSQL_YYABORT; } | AUTHORS_SYM @@ -13777,7 +13811,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_PROFILE; - if (prepare_schema_table(thd, lex, NULL, SCH_PROFILES) != 0) + if (unlikely(prepare_schema_table(thd, lex, NULL, SCH_PROFILES))) MYSQL_YYABORT; } | opt_var_type STATUS_SYM wild_and_where @@ -13785,7 +13819,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS; lex->option_type= $1; - if (prepare_schema_table(thd, lex, 0, SCH_SESSION_STATUS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SESSION_STATUS))) MYSQL_YYABORT; } | opt_full PROCESSLIST_SYM @@ -13795,27 +13829,28 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_VARIABLES; lex->option_type= $1; - if (prepare_schema_table(thd, lex, 0, SCH_SESSION_VARIABLES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SESSION_VARIABLES))) MYSQL_YYABORT; } | charset wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_CHARSETS; - if (prepare_schema_table(thd, lex, 0, SCH_CHARSETS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_CHARSETS))) MYSQL_YYABORT; } | COLLATION_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_COLLATIONS; - if (prepare_schema_table(thd, lex, 0, SCH_COLLATIONS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_COLLATIONS))) MYSQL_YYABORT; } | GRANTS { Lex->sql_command= SQLCOM_SHOW_GRANTS; - if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!(Lex->grant_user= + (LEX_USER*)thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; Lex->grant_user->user= current_user_and_current_role; } @@ -13834,7 +13869,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $3, NULL,0))) MYSQL_YYABORT; lex->create_info.storage_media= HA_SM_DEFAULT; } @@ -13842,7 +13877,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_VIEW; } @@ -13850,7 +13885,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_SEQUENCE; } @@ -13910,7 +13945,8 @@ show_param: | CREATE USER_SYM { Lex->sql_command= SQLCOM_SHOW_CREATE_USER; - if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!(Lex->grant_user= + (LEX_USER*)thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; Lex->grant_user->user= current_user; } @@ -13923,28 +13959,28 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PROC; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | FUNCTION_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_FUNC; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | PACKAGE_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | PACKAGE_SYM BODY_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE_BODY; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | PROCEDURE_SYM CODE_SYM sp_name @@ -13970,7 +14006,7 @@ show_param: | describe_command FOR_SYM expr { Lex->sql_command= SQLCOM_SHOW_EXPLAIN; - if (prepare_schema_table(thd, Lex, 0, SCH_EXPLAIN)) + if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_EXPLAIN))) MYSQL_YYABORT; add_value_to_list(thd, $3); } @@ -13980,17 +14016,17 @@ show_param: bool in_plugin; lex->sql_command= SQLCOM_SHOW_GENERIC; ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1, &in_plugin); - if (!table || !table->old_format || !in_plugin) + if (unlikely(!table || !table->old_format || !in_plugin)) { thd->parse_error(ER_SYNTAX_ERROR, $2); MYSQL_YYABORT; } - if (lex->wild && table->idx_field1 < 0) + if (unlikely(lex->wild && table->idx_field1 < 0)) { thd->parse_error(ER_SYNTAX_ERROR, $3); MYSQL_YYABORT; } - if (make_schema_select(thd, Lex->current_select, table)) + if (unlikely(make_schema_select(thd, Lex->current_select, table))) MYSQL_YYABORT; } ; @@ -14045,7 +14081,7 @@ wild_and_where: { Lex->wild= new (thd->mem_root) String($3.str, $3.length, system_charset_info); - if (Lex->wild == NULL) + if (unlikely(Lex->wild == NULL)) MYSQL_YYABORT; $$= $2; } @@ -14068,7 +14104,7 @@ describe: lex->sql_command= SQLCOM_SHOW_FIELDS; lex->select_lex.db= null_clex_str; lex->verbose= 0; - if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS)) + if (unlikely(prepare_schema_table(thd, lex, $2, SCH_COLUMNS))) MYSQL_YYABORT; } opt_describe_column @@ -14114,13 +14150,13 @@ opt_format_json: /* empty */ {} | FORMAT_SYM '=' ident_or_text { - if (!my_strcasecmp(system_charset_info, $3.str, "JSON")) + if (lex_string_eq(&$3, STRING_WITH_LEN("JSON"))) Lex->explain_json= true; - else if (!my_strcasecmp(system_charset_info, $3.str, "TRADITIONAL")) + else if (lex_string_eq(&$3, STRING_WITH_LEN("TRADITIONAL"))) DBUG_ASSERT(Lex->explain_json==false); else my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "EXPLAIN", - $3.str)); + $3.str)); } ; @@ -14132,7 +14168,7 @@ opt_describe_column: Lex->wild= new (thd->mem_root) String((const char*) $1.str, $1.length, system_charset_info); - if (Lex->wild == NULL) + if (unlikely(Lex->wild == NULL)) MYSQL_YYABORT; } ; @@ -14189,8 +14225,9 @@ flush_lock: { Lex->type|= REFRESH_READ_LOCK | $4; } | FOR_SYM { - if (Lex->query_tables == NULL) // Table list can't be empty + if (unlikely(Lex->query_tables == NULL)) { + // Table list can't be empty thd->parse_error(ER_NO_TABLES_USED); MYSQL_YYABORT; } @@ -14218,7 +14255,7 @@ flush_option: | RELAY LOGS_SYM optional_connection_name { LEX *lex= Lex; - if (lex->type & REFRESH_RELAY_LOG) + if (unlikely(lex->type & REFRESH_RELAY_LOG)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "FLUSH", "RELAY LOGS")); lex->type|= REFRESH_RELAY_LOG; lex->relay_log_connection_name= lex->mi.connection_name; @@ -14239,7 +14276,7 @@ flush_option: | SLAVE optional_connection_name { LEX *lex= Lex; - if (lex->type & REFRESH_SLAVE) + if (unlikely(lex->type & REFRESH_SLAVE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "FLUSH","SLAVE")); lex->type|= REFRESH_SLAVE; lex->reset_slave_info.all= false; @@ -14254,14 +14291,15 @@ flush_option: { Lex->type|= REFRESH_GENERIC; ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1); - if (!table || !table->reset_table) + if (unlikely(!table || !table->reset_table)) { thd->parse_error(ER_SYNTAX_ERROR, $2); MYSQL_YYABORT; } - Lex->view_list.push_back((LEX_CSTRING*) - thd->memdup(&$1, sizeof(LEX_CSTRING)), - thd->mem_root); + if (unlikely(Lex->view_list.push_back((LEX_CSTRING*) + thd->memdup(&$1, sizeof(LEX_CSTRING)), + thd->mem_root))) + MYSQL_YYABORT; } ; @@ -14430,7 +14468,7 @@ load: { LEX *lex= thd->lex; - if (lex->sphead) + if (unlikely(lex->sphead)) { my_error(ER_SP_BADSTATEMENT, MYF(0), $2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML"); @@ -14444,14 +14482,17 @@ load: lex->local_file= $5; lex->duplicates= DUP_ERROR; lex->ignore= 0; - if (!(lex->exchange= new (thd->mem_root) sql_exchange($7.str, 0, $2))) + if (unlikely(!(lex->exchange= new (thd->mem_root) + sql_exchange($7.str, 0, $2)))) MYSQL_YYABORT; } opt_duplicate INTO TABLE_SYM table_ident opt_use_partition { LEX *lex=Lex; - if (!Select->add_table_to_list(thd, $12, NULL, TL_OPTION_UPDATING, - $4, MDL_SHARED_WRITE, NULL, $13)) + if (unlikely(!Select->add_table_to_list(thd, $12, NULL, + TL_OPTION_UPDATING, + $4, MDL_SHARED_WRITE, + NULL, $13))) MYSQL_YYABORT; lex->field_list.empty(); lex->update_list.empty(); @@ -14589,7 +14630,7 @@ field_or_var: | '@' ident_or_text { $$= new (thd->mem_root) Item_user_var_as_out_param(thd, &$2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -14608,8 +14649,8 @@ load_data_set_elem: simple_ident_nospvar equal remember_name expr_or_default remember_end { LEX *lex= Lex; - if (lex->update_list.push_back($1, thd->mem_root) || - lex->value_list.push_back($4, thd->mem_root)) + if (unlikely(lex->update_list.push_back($1, thd->mem_root)) || + unlikely(lex->value_list.push_back($4, thd->mem_root))) MYSQL_YYABORT; $4->set_name_no_truncate(thd, $3, (uint) ($5 - $3), thd->charset()); } @@ -14620,22 +14661,22 @@ load_data_set_elem: text_literal: TEXT_STRING { - if (!($$= thd->make_string_literal($1))) + if (unlikely(!($$= thd->make_string_literal($1)))) MYSQL_YYABORT; } | NCHAR_STRING { - if (!($$= thd->make_string_literal_nchar($1))) + if (unlikely(!($$= thd->make_string_literal_nchar($1)))) MYSQL_YYABORT; } | UNDERSCORE_CHARSET TEXT_STRING { - if (!($$= thd->make_string_literal_charset($2, $1))) + if (unlikely(!($$= thd->make_string_literal_charset($2, $1)))) MYSQL_YYABORT; } | text_literal TEXT_STRING_literal { - if (!($$= $1->make_string_literal_concat(thd, &$2))) + if (unlikely(!($$= $1->make_string_literal_concat(thd, &$2)))) MYSQL_YYABORT; } ; @@ -14646,7 +14687,7 @@ text_string: $$= new (thd->mem_root) String($1.str, $1.length, thd->variables.collation_connection); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | hex_or_bin_String { $$= $1; } @@ -14658,7 +14699,7 @@ hex_or_bin_String: { Item *tmp= new (thd->mem_root) Item_hex_hybrid(thd, $1.str, $1.length); - if (tmp == NULL) + if (unlikely(tmp == NULL)) MYSQL_YYABORT; /* it is OK only emulate fix_fields, because we need only @@ -14671,7 +14712,7 @@ hex_or_bin_String: { Item *tmp= new (thd->mem_root) Item_hex_string(thd, $1.str, $1.length); - if (tmp == NULL) + if (unlikely(tmp == NULL)) MYSQL_YYABORT; tmp->quick_fix_field(); $$= tmp->val_str((String*) 0); @@ -14680,7 +14721,7 @@ hex_or_bin_String: { Item *tmp= new (thd->mem_root) Item_bin_string(thd, $1.str, $1.length); - if (tmp == NULL) + if (unlikely(tmp == NULL)) MYSQL_YYABORT; /* it is OK only emulate fix_fields, because we need only @@ -14694,9 +14735,9 @@ hex_or_bin_String: param_marker: PARAM_MARKER { - if (!($$= Lex->add_placeholder(thd, ¶m_clex_str, - YYLIP->get_tok_start(), - YYLIP->get_tok_start() + 1))) + if (unlikely(!($$= Lex->add_placeholder(thd, ¶m_clex_str, + YYLIP->get_tok_start(), + YYLIP->get_tok_start() + 1)))) MYSQL_YYABORT; } ; @@ -14724,38 +14765,38 @@ literal: */ YYLIP->reduce_digest_token(TOK_GENERIC_VALUE, NULL_SYM); $$= new (thd->mem_root) Item_null(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT; } | FALSE_SYM { $$= new (thd->mem_root) Item_bool(thd, (char*) "FALSE",0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TRUE_SYM { $$= new (thd->mem_root) Item_bool(thd, (char*) "TRUE",1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | HEX_NUM { $$= new (thd->mem_root) Item_hex_hybrid(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | HEX_STRING { $$= new (thd->mem_root) Item_hex_string(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIN_NUM { $$= new (thd->mem_root) Item_bin_string(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | UNDERSCORE_CHARSET hex_or_bin_String @@ -14768,7 +14809,8 @@ literal: item_str= new (thd->mem_root) Item_string_with_introducer(thd, NULL, $2->ptr(), $2->length(), $1); - if (!item_str || !item_str->check_well_formed_result(true)) + if (unlikely(!item_str || + !item_str->check_well_formed_result(true))) MYSQL_YYABORT; $$= item_str; @@ -14783,7 +14825,7 @@ NUM_literal: Item_int(thd, $1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LONG_NUM @@ -14793,31 +14835,27 @@ NUM_literal: Item_int(thd, $1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ULONGLONG_NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DECIMAL_NUM { $$= new (thd->mem_root) Item_decimal(thd, $1.str, $1.length, thd->charset()); - if (($$ == NULL) || (thd->is_error())) - { + if (unlikely($$ == NULL) || unlikely(thd->is_error())) MYSQL_YYABORT; - } } | FLOAT_NUM { $$= new (thd->mem_root) Item_float(thd, $1.str, $1.length); - if (($$ == NULL) || (thd->is_error())) - { + if (unlikely($$ == NULL) || unlikely(thd->is_error())) MYSQL_YYABORT; - } } ; @@ -14825,20 +14863,26 @@ NUM_literal: temporal_literal: DATE_SYM TEXT_STRING { - if (!($$= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, - MYSQL_TYPE_DATE, true))) + if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length, + YYCSCL, + MYSQL_TYPE_DATE, + true)))) MYSQL_YYABORT; } | TIME_SYM TEXT_STRING { - if (!($$= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, - MYSQL_TYPE_TIME, true))) + if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length, + YYCSCL, + MYSQL_TYPE_TIME, + true)))) MYSQL_YYABORT; } | TIMESTAMP TEXT_STRING { - if (!($$= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, - MYSQL_TYPE_DATETIME, true))) + if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length, + YYCSCL, + MYSQL_TYPE_DATETIME, + true)))) MYSQL_YYABORT; } ; @@ -14858,7 +14902,7 @@ with_clause: { With_clause *with_clause= new With_clause($2, Lex->curr_with_clause); - if (with_clause == NULL) + if (unlikely(with_clause == NULL)) MYSQL_YYABORT; Lex->derived_tables|= DERIVED_WITH; Lex->curr_with_clause= with_clause; @@ -14889,16 +14933,17 @@ with_list_element: opt_with_column_list { $2= new List<LEX_CSTRING> (Lex->with_column_list); - if ($2 == NULL) + if (unlikely($2 == NULL)) MYSQL_YYABORT; Lex->with_column_list.empty(); } AS '(' remember_name subselect remember_end ')' { With_element *elem= new With_element($1, *$2, $7->master_unit()); - if (elem == NULL || Lex->curr_with_clause->add_with_element(elem)) + if (unlikely(elem == NULL) || + unlikely(Lex->curr_with_clause->add_with_element(elem))) MYSQL_YYABORT; - if (elem->set_unparsed_spec(thd, $6+1, $8)) + if (unlikely(elem->set_unparsed_spec(thd, $6+1, $8))) MYSQL_YYABORT; } ; @@ -14930,7 +14975,7 @@ query_name: ident { $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -14949,24 +14994,26 @@ insert_ident: table_wild: ident '.' '*' { - SELECT_LEX *sel= Select; - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, $1.str, &star_clex_str); - if ($$ == NULL) + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1)))) MYSQL_YYABORT; - sel->with_wild++; } | ident '.' ident '.' '*' { - SELECT_LEX *sel= Select; - const char* schema= thd->client_capabilities & CLIENT_NO_SCHEMA ? - NullS : $1.str; - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - schema, - $3.str, &star_clex_str); - if ($$ == NULL) + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1, &$3)))) + MYSQL_YYABORT; + } + ; + +select_sublist_qualified_asterisk: + ident_cli '.' '*' + { + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1)))) + MYSQL_YYABORT; + } + | ident_cli '.' ident_cli '.' '*' + { + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1, &$3)))) MYSQL_YYABORT; - sel->with_wild++; } ; @@ -14974,21 +15021,27 @@ order_ident: expr { $$=$1; } ; + simple_ident: - ident + ident_cli { - Lex_input_stream *lip= YYLIP; - if (!($$= Lex->create_item_ident(thd, &$1, - lip->get_tok_start_prev(), - lip->get_tok_end()))) + if (unlikely(!($$= Lex->create_item_ident(thd, &$1)))) MYSQL_YYABORT; } - | simple_ident_q2 - | ident '.' ident + | ident_cli '.' ident_cli { - LEX *lex= thd->lex; - if (!($$= lex->create_item_ident(thd, &$1, &$3, - $1.m_pos, YYLIP->get_tok_end()))) + if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3)))) + MYSQL_YYABORT; + } + | '.' ident_cli '.' ident_cli + { + Lex_ident_cli empty($2.pos(), 0); + if (unlikely(!($$= Lex->create_item_ident(thd, &empty, &$2, &$4)))) + MYSQL_YYABORT; + } + | ident_cli '.' ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } ; @@ -14996,7 +15049,7 @@ simple_ident: simple_ident_nospvar: ident { - if (!($$= Lex->create_item_ident_nosp(thd, &$1))) + if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1)))) MYSQL_YYABORT; } | simple_ident_q { $$= $1; } @@ -15005,7 +15058,7 @@ simple_ident_nospvar: simple_ident_q: ident '.' ident { - if (!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3))) + if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3)))) MYSQL_YYABORT; } | simple_ident_q2 @@ -15014,12 +15067,13 @@ simple_ident_q: simple_ident_q2: '.' ident '.' ident { - if (!($$= Lex->create_item_ident(thd, &null_clex_str, &$2, &$4))) + Lex_ident_sys none; + if (unlikely(!($$= Lex->create_item_ident(thd, &none, &$2, &$4)))) MYSQL_YYABORT; } | ident '.' ident '.' ident { - if (!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))) + if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } ; @@ -15029,17 +15083,19 @@ field_ident: | ident '.' ident '.' ident { TABLE_LIST *table= Select->table_list.first; - if (my_strcasecmp(table_alias_charset, $1.str, table->db.str)) + if (unlikely(my_strcasecmp(table_alias_charset, $1.str, + table->db.str))) my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); - if (my_strcasecmp(table_alias_charset, $3.str, - table->table_name.str)) + if (unlikely(my_strcasecmp(table_alias_charset, $3.str, + table->table_name.str))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3.str)); $$=$5; } | ident '.' ident { TABLE_LIST *table= Select->table_list.first; - if (my_strcasecmp(table_alias_charset, $1.str, table->alias.str)) + if (unlikely(my_strcasecmp(table_alias_charset, $1.str, + table->alias.str))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $1.str)); $$=$3; } @@ -15050,20 +15106,20 @@ table_ident: ident { $$= new (thd->mem_root) Table_ident(&$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ident '.' ident { $$= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | '.' ident { /* For Delphi */ $$= new (thd->mem_root) Table_ident(&$2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -15072,13 +15128,13 @@ table_ident_opt_wild: ident opt_wild { $$= new (thd->mem_root) Table_ident(&$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ident '.' ident opt_wild { $$= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -15088,141 +15144,94 @@ table_ident_nodb: { LEX_CSTRING db={(char*) any_db,3}; $$= new (thd->mem_root) Table_ident(thd, &db, &$1, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; -IDENT_sys: - IDENT { $$= $1; } +IDENT_cli: + IDENT | IDENT_QUOTED + ; + +ident_cli: + IDENT + | IDENT_QUOTED + | keyword_ident { $$= $1; } + ; + +IDENT_sys: + IDENT_cli { - if (thd->charset_is_system_charset) - { - CHARSET_INFO *cs= system_charset_info; - size_t wlen= Well_formed_prefix(cs, $1.str, $1.length).length(); - if (wlen < $1.length) - { - ErrConvString err($1.str, $1.length, &my_charset_bin); - my_error(ER_INVALID_CHARACTER_STRING, MYF(0), - cs->csname, err.ptr()); - MYSQL_YYABORT; - } - $$= $1; - } - else - { - LEX_STRING to; - if (thd->convert_with_error(system_charset_info, &to, - thd->charset(), $1.str, $1.length)) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (unlikely(thd->to_ident_sys_alloc(&$$, &$1))) + MYSQL_YYABORT; } ; TEXT_STRING_sys: TEXT_STRING { - if (thd->charset_is_system_charset) - $$= $1; - else - { - LEX_STRING to; - if (thd->convert_string(&to, system_charset_info, - $1.str, $1.length, thd->charset())) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (thd->make_text_string_sys(&$$, &$1)) + MYSQL_YYABORT; } ; TEXT_STRING_literal: TEXT_STRING { - if (thd->charset_is_collation_connection) - $$= $1; - else - { - LEX_STRING to; - if (thd->convert_string(&to, thd->variables.collation_connection, - $1.str, $1.length, thd->charset())) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (thd->make_text_string_connection(&$$, &$1)) + MYSQL_YYABORT; } ; TEXT_STRING_filesystem: TEXT_STRING { - if (thd->charset_is_character_set_filesystem) - $$= $1; - else - { - LEX_STRING to; - if (thd->convert_string(&to, - thd->variables.character_set_filesystem, - $1.str, $1.length, thd->charset())) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (thd->make_text_string_filesystem(&$$, &$1)) + MYSQL_YYABORT; } + ; ident_table_alias: - IDENT_sys { $$= $1; } - | keyword_alias + IDENT_sys + | keyword_table_alias { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; } ; -ident: + +ident_sysvar_name: IDENT_sys + | keyword_sysvar_name { - (LEX_CSTRING &)$$= $1; - $$.m_pos= (char *) YYLIP->get_tok_start_prev(); + if (unlikely($$.copy_keyword(thd, &$1))) + MYSQL_YYABORT; } - | keyword + | TEXT_STRING_sys { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_sys(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; - $$.m_pos= (char *) YYLIP->get_tok_start_prev(); } ; -ident_with_tok_start: + +ident: IDENT_sys + | keyword_ident { - (LEX_CSTRING &)$$= $1; - $$.m_pos= (char *) YYLIP->get_tok_start(); - } - | keyword - { - if (!($$.str= thd->strmake($1.str, $1.length))) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; - $$.m_pos= (char *) YYLIP->get_tok_start(); } ; label_ident: - IDENT_sys { $$=$1; } - | keyword_sp + IDENT_sys + | keyword_label { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; } ; @@ -15235,28 +15244,28 @@ ident_or_text: user_maybe_role: ident_or_text { - if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user = $1; $$->host= null_clex_str; // User or Role, see get_current_user() $$->reset_auth(); - if (check_string_char_length(&$$->user, ER_USERNAME, - username_char_length, - system_charset_info, 0)) + if (unlikely(check_string_char_length(&$$->user, ER_USERNAME, + username_char_length, + system_charset_info, 0))) MYSQL_YYABORT; } | ident_or_text '@' ident_or_text { - if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user = $1; $$->host=$3; $$->reset_auth(); - if (check_string_char_length(&$$->user, ER_USERNAME, - username_char_length, - system_charset_info, 0) || - check_host_name(&$$->host)) + if (unlikely(check_string_char_length(&$$->user, ER_USERNAME, + username_char_length, + system_charset_info, 0)) || + unlikely(check_host_name(&$$->host))) MYSQL_YYABORT; if ($$->host.str[0]) { @@ -15278,7 +15287,7 @@ user_maybe_role: } | CURRENT_USER optional_braces { - if (!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user= current_user; $$->plugin= empty_clex_str; @@ -15297,86 +15306,170 @@ user: user_maybe_role ; /* Keywords which we allow as table aliases. */ -keyword_alias: - keyword_sp {} - | keyword_sp_verb_clause{} - | ASCII_SYM {} - | BACKUP_SYM {} - | BINLOG_SYM {} - | BYTE_SYM {} - | CACHE_SYM {} - | CHARSET {} - | CHECKSUM_SYM {} - | CHECKPOINT_SYM {} - | COLUMN_ADD_SYM {} - | COLUMN_CHECK_SYM {} - | COLUMN_CREATE_SYM {} - | COLUMN_DELETE_SYM {} - | COLUMN_GET_SYM {} - | COMMENT_SYM {} - | CONTAINS_SYM {} - | DEALLOCATE_SYM {} - | EXAMINED_SYM {} - | EXCLUDE_SYM {} - | EXECUTE_SYM {} - | FLUSH_SYM {} - | FOLLOWS_SYM {} - | FOLLOWING_SYM {} - | FORMAT_SYM {} - | GET_SYM {} - | HELP_SYM {} - | HOST_SYM {} - | INSTALL_SYM {} - | LANGUAGE_SYM {} - | NO_SYM {} - | OPTION {} - | OPTIONS_SYM {} - | OTHERS_SYM {} - | OWNER_SYM {} - | PARSER_SYM {} - | PERIOD_SYM {} - | PORT_SYM {} - | PRECEDES_SYM {} - | PRECEDING_SYM {} - | PREPARE_SYM {} - | REMOVE_SYM {} - | RESET_SYM {} - | RESTORE_SYM {} - | SECURITY_SYM {} - | SERVER_SYM {} - | SIGNED_SYM {} - | SOCKET_SYM {} - | SLAVE {} - | SLAVES {} - | SONAME_SYM {} - | START_SYM {} - | STOP_SYM {} - | STORED_SYM {} - | TIES_SYM {} - | UNICODE_SYM {} - | UNINSTALL_SYM {} - | UNBOUNDED_SYM {} - | WITHIN {} - | WRAPPER_SYM {} - | XA_SYM {} - | UPGRADE_SYM {} +keyword_table_alias: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause ; - /* Keyword that we allow for identifiers (except SP labels) */ -keyword: keyword_alias | WINDOW_SYM {}; +keyword_ident: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause + | WINDOW_SYM + ; /* - * Keywords that we allow for labels in SPs. - * Anything that's the beginning of a statement or characteristics - * must be in keyword above, otherwise we get (harmful) shift/reduce - * conflicts. - */ -keyword_sp: - keyword_sp_data_type - | keyword_sp_not_data_type + Keywords that we allow for labels in SPs. + Should not include keywords that start a statement or SP characteristics. +*/ +keyword_label: + keyword_data_type + | keyword_sp_var_and_label + | keyword_sysvar_type + ; + +keyword_sysvar_name: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_verb_clause + | WINDOW_SYM + ; + +keyword_sp_decl: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause + | WINDOW_SYM ; +/* + Keywords that we allow in Oracle-style direct assignments: + xxx := 10; + but do not allow in labels in the default sql_mode: + label: + stmt1; + stmt2; + TODO: check if some of them can migrate to keyword_sp_var_and_label. +*/ +keyword_sp_var_not_label: + ASCII_SYM + | BACKUP_SYM + | BINLOG_SYM + | BYTE_SYM + | CACHE_SYM + | CHECKSUM_SYM + | CHECKPOINT_SYM + | COLUMN_ADD_SYM + | COLUMN_CHECK_SYM + | COLUMN_CREATE_SYM + | COLUMN_DELETE_SYM + | COLUMN_GET_SYM + | COMMENT_SYM + | DEALLOCATE_SYM + | EXAMINED_SYM + | EXCLUDE_SYM + | EXECUTE_SYM + | FLUSH_SYM + | FOLLOWING_SYM + | FORMAT_SYM + | GET_SYM + | HELP_SYM + | HOST_SYM + | INSTALL_SYM + | OPTION + | OPTIONS_SYM + | OTHERS_SYM + | OWNER_SYM + | PARSER_SYM + | PERIOD_SYM + | PORT_SYM + | PRECEDING_SYM + | PREPARE_SYM + | REMOVE_SYM + | RESET_SYM + | RESTORE_SYM + | SECURITY_SYM + | SERVER_SYM + | SIGNED_SYM + | SOCKET_SYM + | SLAVE + | SLAVES + | SONAME_SYM + | START_SYM + | STOP_SYM + | STORED_SYM + | TIES_SYM + | UNICODE_SYM + | UNINSTALL_SYM + | UNBOUNDED_SYM + | WITHIN + | WRAPPER_SYM + | XA_SYM + | UPGRADE_SYM + ; + +/* + Keywords that can start optional clauses in SP or trigger declarations + Allowed as identifiers (e.g. table, column names), + but: + - not allowed as SP label names + - not allowed as variable names in Oracle-style assignments: + xxx := 10; + + If we allowed these variables in assignments, there would be conflicts + with SP characteristics, or verb clauses, or compound statements, e.g.: + CREATE PROCEDURE p1 LANGUAGE ... + would be either: + CREATE PROCEDURE p1 LANGUAGE SQL BEGIN END; + or + CREATE PROCEDURE p1 LANGUAGE:=10; + + Note, these variables can still be assigned using quoted identifiers: + `do`:= 10; + "do":= 10; (when ANSI_QUOTES) + or using a SET statement: + SET do= 10; + + Note, some of these keywords are reserved keywords in Oracle. + In case if heavy grammar conflicts are found in the future, + we'll possibly need to make them reserved for sql_mode=ORACLE. + + TODO: Allow these variables as SP lables when sql_mode=ORACLE. + TODO: Allow assigning of "SP characteristics" marked variables + inside compound blocks. + TODO: Allow "follows" and "precedes" as variables in compound blocks: + BEGIN + follows := 10; + END; + as they conflict only with non-block FOR EACH ROW statement: + CREATE TRIGGER .. FOR EACH ROW follows:= 10; + CREATE TRIGGER .. FOR EACH ROW FOLLOWS tr1 a:= 10; +*/ +keyword_sp_head: + CONTAINS_SYM /* SP characteristic */ + | LANGUAGE_SYM /* SP characteristic */ + | NO_SYM /* SP characteristic */ + | CHARSET /* SET CHARSET utf8; */ + | FOLLOWS_SYM /* Conflicts with assignment in FOR EACH */ + | PRECEDES_SYM /* Conflicts with assignment in FOR EACH */ + ; /* Keywords that start a statement. @@ -15385,383 +15478,395 @@ keyword_sp: - not allowed as variable names in Oracle-style assignments: xxx:=10 */ -keyword_sp_verb_clause: - BEGIN_SYM { /* Compound. Reserved in Oracle */ } - | CLOSE_SYM { /* Verb clause. Reserved in Oracle */ } - | COMMIT_SYM { /* Verb clause. Reserved in Oracle */ } - | DO_SYM { /* Verb clause */ } - | END { /* Compound. Reserved in Oracle */ } - | HANDLER_SYM { /* Verb clause */ } - | OPEN_SYM { /* Verb clause. Reserved in Oracle */ } - | REPAIR { /* Verb clause */ } - | ROLLBACK_SYM { /* Verb clause. Reserved in Oracle */ } - | SAVEPOINT_SYM { /* Verb clause. Reserved in Oracle */ } - | SHUTDOWN { /* Verb clause */ } - | TRUNCATE_SYM { /* Verb clause. Reserved in Oracle */ } - ; +keyword_verb_clause: + CLOSE_SYM /* Verb clause. Reserved in Oracle */ + | COMMIT_SYM /* Verb clause. Reserved in Oracle */ + | DO_SYM /* Verb clause */ + | HANDLER_SYM /* Verb clause */ + | OPEN_SYM /* Verb clause. Reserved in Oracle */ + | REPAIR /* Verb clause */ + | ROLLBACK_SYM /* Verb clause. Reserved in Oracle */ + | SAVEPOINT_SYM /* Verb clause. Reserved in Oracle */ + | SHUTDOWN /* Verb clause */ + | TRUNCATE_SYM /* Verb clause. Reserved in Oracle */ + ; + +/* + Keywords that start an SP block section. +*/ +keyword_sp_block_section: + BEGIN_SYM + | END + ; + +keyword_sysvar_type: + GLOBAL_SYM + | LOCAL_SYM + | SESSION_SYM + ; /* These keywords are generally allowed as identifiers, but not allowed as non-delimited SP variable names in sql_mode=ORACLE. */ -keyword_sp_data_type: - BIT_SYM {} - | BOOLEAN_SYM {} /* PLSQL-R */ - | BOOL_SYM {} - | CLOB {} - | DATE_SYM {} /* Oracle-R, PLSQL-R */ - | DATETIME {} - | ENUM {} - | FIXED_SYM {} - | GEOMETRYCOLLECTION {} - | GEOMETRY_SYM {} - | JSON_SYM {} - | LINESTRING {} - | MEDIUM_SYM {} - | MULTILINESTRING {} - | MULTIPOINT {} - | MULTIPOLYGON {} - | NATIONAL_SYM {} - | NCHAR_SYM {} - | NUMBER_SYM {} /* Oracle-R, PLSQL-R */ - | NVARCHAR_SYM {} - | POINT_SYM {} - | POLYGON {} - | RAW {} /* Oracle-R */ - | ROW_SYM {} - | SERIAL_SYM {} - | TEXT_SYM {} - | TIMESTAMP {} - | TIME_SYM {} /* Oracle-R */ - | VARCHAR2 {} /* Oracle-R, PLSQL-R */ - | YEAR_SYM {} - ; - - -keyword_sp_not_data_type: - ACTION {} - | ADDDATE_SYM {} - | ADMIN_SYM {} - | AFTER_SYM {} - | AGAINST {} - | AGGREGATE_SYM {} - | ALGORITHM_SYM {} - | ALWAYS_SYM {} - | ANY_SYM {} - | AT_SYM {} - | ATOMIC_SYM {} - | AUTHORS_SYM {} - | AUTO_INC {} - | AUTOEXTEND_SIZE_SYM {} - | AUTO_SYM {} - | AVG_ROW_LENGTH {} - | AVG_SYM {} - | BLOCK_SYM {} - | BODY_SYM {} - | BTREE_SYM {} - | CASCADED {} - | CATALOG_NAME_SYM {} - | CHAIN_SYM {} - | CHANGED {} - | CIPHER_SYM {} - | CLIENT_SYM {} - | CLASS_ORIGIN_SYM {} - | COALESCE {} - | CODE_SYM {} - | COLLATION_SYM {} - | COLUMN_NAME_SYM {} - | COLUMNS {} - | COMMITTED_SYM {} - | COMPACT_SYM {} - | COMPLETION_SYM {} - | COMPRESSED_SYM {} - | CONCURRENT {} - | CONNECTION_SYM {} - | CONSISTENT_SYM {} - | CONSTRAINT_CATALOG_SYM {} - | CONSTRAINT_SCHEMA_SYM {} - | CONSTRAINT_NAME_SYM {} - | CONTEXT_SYM {} - | CONTRIBUTORS_SYM {} - | CURRENT_POS_SYM {} - | CPU_SYM {} - | CUBE_SYM {} +keyword_data_type: + BIT_SYM + | BOOLEAN_SYM + | BOOL_SYM + | CLOB + | DATE_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | DATETIME + | ENUM + | FIXED_SYM + | GEOMETRYCOLLECTION + | GEOMETRY_SYM + | JSON_SYM + | LINESTRING + | MEDIUM_SYM + | MULTILINESTRING + | MULTIPOINT + | MULTIPOLYGON + | NATIONAL_SYM + | NCHAR_SYM + | NUMBER_SYM + | NVARCHAR_SYM + | POINT_SYM + | POLYGON + | RAW + | ROW_SYM + | SERIAL_SYM + | TEXT_SYM + | TIMESTAMP %prec PREC_BELOW_CONTRACTION_TOKEN2 + | TIME_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | VARCHAR2 + | YEAR_SYM + ; + + +/* + These keywords are fine for both SP variable names and SP labels. +*/ +keyword_sp_var_and_label: + ACTION + | ADDDATE_SYM + | ADMIN_SYM + | AFTER_SYM + | AGAINST + | AGGREGATE_SYM + | ALGORITHM_SYM + | ALWAYS_SYM + | ANY_SYM + | AT_SYM + | ATOMIC_SYM + | AUTHORS_SYM + | AUTO_INC + | AUTOEXTEND_SIZE_SYM + | AUTO_SYM + | AVG_ROW_LENGTH + | AVG_SYM + | BLOCK_SYM + | BODY_SYM + | BTREE_SYM + | CASCADED + | CATALOG_NAME_SYM + | CHAIN_SYM + | CHANGED + | CIPHER_SYM + | CLIENT_SYM + | CLASS_ORIGIN_SYM + | COALESCE + | CODE_SYM + | COLLATION_SYM + | COLUMN_NAME_SYM + | COLUMNS + | COMMITTED_SYM + | COMPACT_SYM + | COMPLETION_SYM + | COMPRESSED_SYM + | CONCURRENT + | CONNECTION_SYM + | CONSISTENT_SYM + | CONSTRAINT_CATALOG_SYM + | CONSTRAINT_SCHEMA_SYM + | CONSTRAINT_NAME_SYM + | CONTEXT_SYM + | CONTRIBUTORS_SYM + | CURRENT_POS_SYM + | CPU_SYM + | CUBE_SYM /* Although a reserved keyword in SQL:2003 (and :2008), not reserved in MySQL per WL#2111 specification. */ - | CURRENT_SYM {} - | CURSOR_NAME_SYM {} - | CYCLE_SYM {} - | DATA_SYM {} - | DATAFILE_SYM {} - | DATE_FORMAT_SYM {} - | DAY_SYM {} - | DECODE_SYM {} - | DEFINER_SYM {} - | DELAY_KEY_WRITE_SYM {} - | DES_KEY_FILE {} - | DIAGNOSTICS_SYM {} - | DIRECTORY_SYM {} - | DISABLE_SYM {} - | DISCARD {} - | DISK_SYM {} - | DUMPFILE {} - | DUPLICATE_SYM {} - | DYNAMIC_SYM {} - | ELSIF_SYM {} - | ENDS_SYM {} - | ENGINE_SYM {} - | ENGINES_SYM {} - | ERROR_SYM {} - | ERRORS {} - | ESCAPE_SYM {} - | EVENT_SYM {} - | EVENTS_SYM {} - | EVERY_SYM {} - | EXCEPTION_SYM {} - | EXCHANGE_SYM {} - | EXPANSION_SYM {} - | EXPORT_SYM {} - | EXTENDED_SYM {} - | EXTENT_SIZE_SYM {} - | FAULTS_SYM {} - | FAST_SYM {} - | FOUND_SYM {} - | ENABLE_SYM {} - | FULL {} - | FILE_SYM {} - | FIRST_SYM {} - | GENERAL {} - | GENERATED_SYM {} - | GET_FORMAT {} - | GRANTS {} - | GLOBAL_SYM {} - | GOTO_SYM {} - | HASH_SYM {} - | HARD_SYM {} - | HISTORY_SYM {} - | HOSTS_SYM {} - | HOUR_SYM {} - | ID_SYM {} - | IDENTIFIED_SYM {} - | IGNORE_SERVER_IDS_SYM {} - | INCREMENT_SYM {} - | IMMEDIATE_SYM {} /* SQL-2003-R */ - | INVOKER_SYM {} - | IMPORT {} - | INDEXES {} - | INITIAL_SIZE_SYM {} - | IO_SYM {} - | IPC_SYM {} - | ISOLATION {} - | ISOPEN_SYM {} - | ISSUER_SYM {} - | INSERT_METHOD {} - | INVISIBLE_SYM {} - | KEY_BLOCK_SIZE {} - | LAST_VALUE {} - | LAST_SYM {} - | LASTVAL_SYM {} - | LEAVES {} - | LESS_SYM {} - | LEVEL_SYM {} - | LIST_SYM {} - | LOCAL_SYM {} - | LOCKS_SYM {} - | LOGFILE_SYM {} - | LOGS_SYM {} - | MAX_ROWS {} - | MASTER_SYM {} - | MASTER_HEARTBEAT_PERIOD_SYM {} - | MASTER_GTID_POS_SYM {} - | MASTER_HOST_SYM {} - | MASTER_PORT_SYM {} - | MASTER_LOG_FILE_SYM {} - | MASTER_LOG_POS_SYM {} - | MASTER_USER_SYM {} - | MASTER_USE_GTID_SYM {} - | MASTER_PASSWORD_SYM {} - | MASTER_SERVER_ID_SYM {} - | MASTER_CONNECT_RETRY_SYM {} - | MASTER_DELAY_SYM {} - | MASTER_SSL_SYM {} - | MASTER_SSL_CA_SYM {} - | MASTER_SSL_CAPATH_SYM {} - | MASTER_SSL_CERT_SYM {} - | MASTER_SSL_CIPHER_SYM {} - | MASTER_SSL_CRL_SYM {} - | MASTER_SSL_CRLPATH_SYM {} - | MASTER_SSL_KEY_SYM {} - | MAX_CONNECTIONS_PER_HOUR {} - | MAX_QUERIES_PER_HOUR {} - | MAX_SIZE_SYM {} - | MAX_STATEMENT_TIME_SYM {} - | MAX_UPDATES_PER_HOUR {} - | MAX_USER_CONNECTIONS_SYM {} - | MEMORY_SYM {} - | MERGE_SYM {} - | MESSAGE_TEXT_SYM {} - | MICROSECOND_SYM {} - | MIGRATE_SYM {} - | MINUTE_SYM {} - | MINVALUE_SYM {} - | MIN_ROWS {} - | MODIFY_SYM {} - | MODE_SYM {} - | MONTH_SYM {} - | MUTEX_SYM {} - | MYSQL_SYM {} - | MYSQL_ERRNO_SYM {} - | NAME_SYM {} - | NAMES_SYM {} - | NEXT_SYM {} - | NEXTVAL_SYM {} - | NEW_SYM {} - | NOCACHE_SYM {} - | NOCYCLE_SYM {} - | NOMINVALUE_SYM {} - | NOMAXVALUE_SYM {} - | NO_WAIT_SYM {} - | NOWAIT_SYM {} - | NODEGROUP_SYM {} - | NONE_SYM {} - | NOTFOUND_SYM {} - | OF_SYM {} /* SQL-1999-R, Oracle-R */ - | OFFSET_SYM {} - | OLD_PASSWORD_SYM {} - | ONE_SYM {} - | ONLINE_SYM {} - | ONLY_SYM {} - | PACKAGE_SYM {} - | PACK_KEYS_SYM {} - | PAGE_SYM {} - | PARTIAL {} - | PARTITIONING_SYM {} - | PARTITIONS_SYM {} - | PASSWORD_SYM {} - | PERSISTENT_SYM {} - | PHASE_SYM {} - | PLUGIN_SYM {} - | PLUGINS_SYM {} - | PRESERVE_SYM {} - | PREV_SYM {} - | PREVIOUS_SYM {} - | PRIVILEGES {} - | PROCESS {} - | PROCESSLIST_SYM {} - | PROFILE_SYM {} - | PROFILES_SYM {} - | PROXY_SYM {} - | QUARTER_SYM {} - | QUERY_SYM {} - | QUICK {} - | RAISE_SYM {} - | READ_ONLY_SYM {} - | REBUILD_SYM {} - | RECOVER_SYM {} - | REDO_BUFFER_SIZE_SYM {} - | REDOFILE_SYM {} - | REDUNDANT_SYM {} - | RELAY {} - | RELAYLOG_SYM {} - | RELAY_LOG_FILE_SYM {} - | RELAY_LOG_POS_SYM {} - | RELAY_THREAD {} - | RELOAD {} - | REORGANIZE_SYM {} - | REPEATABLE_SYM {} - | REPLICATION {} - | RESOURCES {} - | RESTART_SYM {} - | RESUME_SYM {} - | RETURNED_SQLSTATE_SYM {} - | RETURNS_SYM {} - | REUSE_SYM {} /* Oracle-R */ - | REVERSE_SYM {} - | ROLE_SYM {} - | ROLLUP_SYM {} - | ROUTINE_SYM {} - | ROWCOUNT_SYM {} - | ROWTYPE_SYM {} - | ROW_COUNT_SYM {} - | ROW_FORMAT_SYM {} - | RTREE_SYM {} - | SCHEDULE_SYM {} - | SCHEMA_NAME_SYM {} - | SECOND_SYM {} - | SEQUENCE_SYM {} - | SERIALIZABLE_SYM {} - | SESSION_SYM {} - | SETVAL_SYM {} - | SIMPLE_SYM {} - | SHARE_SYM {} - | SLAVE_POS_SYM {} - | SLOW {} - | SNAPSHOT_SYM {} - | SOFT_SYM {} - | SOUNDS_SYM {} - | SOURCE_SYM {} - | SQL_CACHE_SYM {} - | SQL_BUFFER_RESULT {} - | SQL_NO_CACHE_SYM {} - | SQL_THREAD {} - | STARTS_SYM {} - | STATEMENT_SYM {} - | STATUS_SYM {} - | STORAGE_SYM {} - | STRING_SYM {} - | SUBCLASS_ORIGIN_SYM {} - | SUBDATE_SYM {} - | SUBJECT_SYM {} - | SUBPARTITION_SYM {} - | SUBPARTITIONS_SYM {} - | SUPER_SYM {} - | SUSPEND_SYM {} - | SWAPS_SYM {} - | SWITCHES_SYM {} - | SYSTEM {} - | SYSTEM_TIME_SYM {} - | TABLE_NAME_SYM {} - | TABLES {} - | TABLE_CHECKSUM_SYM {} - | TABLESPACE {} - | TEMPORARY {} - | TEMPTABLE_SYM {} - | THAN_SYM {} - | TRANSACTION_SYM {} - | TRANSACTIONAL_SYM {} - | TRIGGERS_SYM {} - | TRIM_ORACLE {} - | TIMESTAMP_ADD {} - | TIMESTAMP_DIFF {} - | TYPES_SYM {} - | TYPE_SYM {} - | UDF_RETURNS_SYM {} - | FUNCTION_SYM {} - | UNCOMMITTED_SYM {} - | UNDEFINED_SYM {} - | UNDO_BUFFER_SIZE_SYM {} - | UNDOFILE_SYM {} - | UNKNOWN_SYM {} - | UNTIL_SYM {} - | USER_SYM {} - | USE_FRM {} - | VARIABLES {} - | VERSIONING_SYM {} - | VIEW_SYM {} - | VIRTUAL_SYM {} - | VALUE_SYM {} - | WARNINGS {} - | WAIT_SYM {} - | WEEK_SYM {} - | WEIGHT_STRING_SYM {} - | WITHOUT {} - | WORK_SYM {} - | X509_SYM {} - | XML_SYM {} - | VIA_SYM {} + | CURRENT_SYM + | CURSOR_NAME_SYM + | CYCLE_SYM + | DATA_SYM + | DATAFILE_SYM + | DATE_FORMAT_SYM + | DAY_SYM + | DECODE_SYM + | DEFINER_SYM + | DELAY_KEY_WRITE_SYM + | DES_KEY_FILE + | DIAGNOSTICS_SYM + | DIRECTORY_SYM + | DISABLE_SYM + | DISCARD + | DISK_SYM + | DUMPFILE + | DUPLICATE_SYM + | DYNAMIC_SYM + | ELSIF_SYM + | ENDS_SYM + | ENGINE_SYM + | ENGINES_SYM + | ERROR_SYM + | ERRORS + | ESCAPE_SYM + | EVENT_SYM + | EVENTS_SYM + | EVERY_SYM + | EXCEPTION_SYM + | EXCHANGE_SYM + | EXPANSION_SYM + | EXPORT_SYM + | EXTENDED_SYM + | EXTENT_SIZE_SYM + | FAULTS_SYM + | FAST_SYM + | FOUND_SYM + | ENABLE_SYM + | FULL + | FILE_SYM + | FIRST_SYM + | GENERAL + | GENERATED_SYM + | GET_FORMAT + | GRANTS + | GOTO_SYM + | HASH_SYM + | HARD_SYM + | HISTORY_SYM + | HOSTS_SYM + | HOUR_SYM + | ID_SYM + | IDENTIFIED_SYM + | IGNORE_SERVER_IDS_SYM + | INCREMENT_SYM + | IMMEDIATE_SYM + | INVOKER_SYM + | IMPORT + | INDEXES + | INITIAL_SIZE_SYM + | IO_SYM + | IPC_SYM + | ISOLATION + | ISOPEN_SYM + | ISSUER_SYM + | INSERT_METHOD + | INVISIBLE_SYM + | KEY_BLOCK_SIZE + | LAST_VALUE + | LAST_SYM + | LASTVAL_SYM + | LEAVES + | LESS_SYM + | LEVEL_SYM + | LIST_SYM + | LOCKS_SYM + | LOGFILE_SYM + | LOGS_SYM + | MAX_ROWS + | MASTER_SYM + | MASTER_HEARTBEAT_PERIOD_SYM + | MASTER_GTID_POS_SYM + | MASTER_HOST_SYM + | MASTER_PORT_SYM + | MASTER_LOG_FILE_SYM + | MASTER_LOG_POS_SYM + | MASTER_USER_SYM + | MASTER_USE_GTID_SYM + | MASTER_PASSWORD_SYM + | MASTER_SERVER_ID_SYM + | MASTER_CONNECT_RETRY_SYM + | MASTER_DELAY_SYM + | MASTER_SSL_SYM + | MASTER_SSL_CA_SYM + | MASTER_SSL_CAPATH_SYM + | MASTER_SSL_CERT_SYM + | MASTER_SSL_CIPHER_SYM + | MASTER_SSL_CRL_SYM + | MASTER_SSL_CRLPATH_SYM + | MASTER_SSL_KEY_SYM + | MAX_CONNECTIONS_PER_HOUR + | MAX_QUERIES_PER_HOUR + | MAX_SIZE_SYM + | MAX_STATEMENT_TIME_SYM + | MAX_UPDATES_PER_HOUR + | MAX_USER_CONNECTIONS_SYM + | MEMORY_SYM + | MERGE_SYM + | MESSAGE_TEXT_SYM + | MICROSECOND_SYM + | MIGRATE_SYM + | MINUTE_SYM + | MINVALUE_SYM + | MIN_ROWS + | MODIFY_SYM + | MODE_SYM + | MONTH_SYM + | MUTEX_SYM + | MYSQL_SYM + | MYSQL_ERRNO_SYM + | NAME_SYM + | NAMES_SYM + | NEXT_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | NEXTVAL_SYM + | NEW_SYM + | NOCACHE_SYM + | NOCYCLE_SYM + | NOMINVALUE_SYM + | NOMAXVALUE_SYM + | NO_WAIT_SYM + | NOWAIT_SYM + | NODEGROUP_SYM + | NONE_SYM + | NOTFOUND_SYM + | OF_SYM + | OFFSET_SYM + | OLD_PASSWORD_SYM + | ONE_SYM + | ONLINE_SYM + | ONLY_SYM + | PACKAGE_SYM + | PACK_KEYS_SYM + | PAGE_SYM + | PARTIAL + | PARTITIONING_SYM + | PARTITIONS_SYM + | PASSWORD_SYM + | PERSISTENT_SYM + | PHASE_SYM + | PLUGIN_SYM + | PLUGINS_SYM + | PRESERVE_SYM + | PREV_SYM + | PREVIOUS_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | PRIVILEGES + | PROCESS + | PROCESSLIST_SYM + | PROFILE_SYM + | PROFILES_SYM + | PROXY_SYM + | QUARTER_SYM + | QUERY_SYM + | QUICK + | RAISE_SYM + | READ_ONLY_SYM + | REBUILD_SYM + | RECOVER_SYM + | REDO_BUFFER_SIZE_SYM + | REDOFILE_SYM + | REDUNDANT_SYM + | RELAY + | RELAYLOG_SYM + | RELAY_LOG_FILE_SYM + | RELAY_LOG_POS_SYM + | RELAY_THREAD + | RELOAD + | REORGANIZE_SYM + | REPEATABLE_SYM + | REPLICATION + | RESOURCES + | RESTART_SYM + | RESUME_SYM + | RETURNED_SQLSTATE_SYM + | RETURNS_SYM + | REUSE_SYM + | REVERSE_SYM + | ROLE_SYM + | ROLLUP_SYM + | ROUTINE_SYM + | ROWCOUNT_SYM + | ROWTYPE_SYM + | ROW_COUNT_SYM + | ROW_FORMAT_SYM + | RTREE_SYM + | SCHEDULE_SYM + | SCHEMA_NAME_SYM + | SECOND_SYM + | SEQUENCE_SYM + | SERIALIZABLE_SYM + | SETVAL_SYM + | SIMPLE_SYM + | SHARE_SYM + | SLAVE_POS_SYM + | SLOW + | SNAPSHOT_SYM + | SOFT_SYM + | SOUNDS_SYM + | SOURCE_SYM + | SQL_CACHE_SYM + | SQL_BUFFER_RESULT + | SQL_NO_CACHE_SYM + | SQL_THREAD + | STARTS_SYM + | STATEMENT_SYM + | STATUS_SYM + | STORAGE_SYM + | STRING_SYM + | SUBCLASS_ORIGIN_SYM + | SUBDATE_SYM + | SUBJECT_SYM + | SUBPARTITION_SYM + | SUBPARTITIONS_SYM + | SUPER_SYM + | SUSPEND_SYM + | SWAPS_SYM + | SWITCHES_SYM + | SYSTEM + | SYSTEM_TIME_SYM + | TABLE_NAME_SYM + | TABLES + | TABLE_CHECKSUM_SYM + | TABLESPACE + | TEMPORARY + | TEMPTABLE_SYM + | THAN_SYM + | TRANSACTION_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | TRANSACTIONAL_SYM + | TRIGGERS_SYM + | TRIM_ORACLE + | TIMESTAMP_ADD + | TIMESTAMP_DIFF + | TYPES_SYM + | TYPE_SYM + | UDF_RETURNS_SYM + | FUNCTION_SYM + | UNCOMMITTED_SYM + | UNDEFINED_SYM + | UNDO_BUFFER_SIZE_SYM + | UNDOFILE_SYM + | UNKNOWN_SYM + | UNTIL_SYM + | USER_SYM + | USE_FRM + | VARIABLES + | VERSIONING_SYM + | VIEW_SYM + | VIRTUAL_SYM + | VALUE_SYM + | WARNINGS + | WAIT_SYM + | WEEK_SYM + | WEIGHT_STRING_SYM + | WITHOUT + | WORK_SYM + | X509_SYM + | XML_SYM + | VIA_SYM ; /* @@ -15788,7 +15893,7 @@ set: set_stmt_option_value_following_option_type_list { LEX *lex= Lex; - if (lex->table_or_sp_used()) + if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT")); lex->stmt_var_list= lex->var_list; lex->var_list.empty(); @@ -15811,7 +15916,7 @@ set_stmt_option_value_following_option_type_list: start_option_value_list: option_value_no_option_type { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } option_value_list_continued @@ -15821,7 +15926,7 @@ start_option_value_list: } transaction_characteristics { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | option_type @@ -15836,14 +15941,14 @@ start_option_value_list: start_option_value_list_following_option_type: option_value_following_option_type { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } option_value_list_continued | TRANSACTION_SYM transaction_characteristics { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; @@ -15860,8 +15965,8 @@ option_value_list: } option_value { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | option_value_list ',' { @@ -15869,8 +15974,8 @@ option_value_list: } option_value { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; @@ -15908,17 +16013,17 @@ opt_var_ident_type: option_value_following_option_type: ident equal set_expr_or_default { - if (Lex->set_system_variable(Lex->option_type, &$1, $3)) + if (unlikely(Lex->set_system_variable(Lex->option_type, &$1, $3))) MYSQL_YYABORT; } | ident '.' ident equal set_expr_or_default { - if (Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5)) + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default { - if (Lex->set_default_system_variable(Lex->option_type, &$3, $5)) + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) MYSQL_YYABORT; } ; @@ -15927,37 +16032,37 @@ option_value_following_option_type: option_value_no_option_type: ident equal set_expr_or_default { - if (Lex->set_variable(&$1, $3)) + if (unlikely(Lex->set_variable(&$1, $3))) MYSQL_YYABORT; } | ident '.' ident equal set_expr_or_default { - if (Lex->set_variable(&$1, &$3, $5)) + if (unlikely(Lex->set_variable(&$1, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default { - if (Lex->set_default_system_variable(Lex->option_type, &$3, $5)) + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) MYSQL_YYABORT; } | '@' ident_or_text equal expr { - if (Lex->set_user_variable(thd, &$2, $4)) + if (unlikely(Lex->set_user_variable(thd, &$2, $4))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident equal set_expr_or_default + | '@' '@' opt_var_ident_type ident_sysvar_name equal set_expr_or_default { - if (Lex->set_system_variable($3, &$4, $6)) + if (unlikely(Lex->set_system_variable($3, &$4, $6))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident '.' ident equal set_expr_or_default + | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal set_expr_or_default { - if (Lex->set_system_variable(thd, $3, &$4, &$6, $8)) + if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $8))) MYSQL_YYABORT; } | '@' '@' opt_var_ident_type DEFAULT '.' ident equal set_expr_or_default { - if (Lex->set_default_system_variable($3, &$6, $8)) + if (unlikely(Lex->set_default_system_variable($3, &$6, $8))) MYSQL_YYABORT; } | charset old_or_new_charset_name_or_default @@ -15970,7 +16075,7 @@ option_value_no_option_type: set_var_collation_client(cs2, thd->variables.collation_database, cs2)); - if (var == NULL) + if (unlikely(var == NULL)) MYSQL_YYABORT; lex->var_list.push_back(var, thd->mem_root); } @@ -15979,7 +16084,7 @@ option_value_no_option_type: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; LEX_CSTRING names= { STRING_WITH_LEN("names") }; - if (spc && spc->find_variable(&names, false)) + if (unlikely(spc && spc->find_variable(&names, false))) my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); else thd->parse_error(); @@ -15992,7 +16097,7 @@ option_value_no_option_type: CHARSET_INFO *cs3; cs2= $2 ? $2 : global_system_variables.character_set_client; cs3= $3 ? $3 : cs2; - if (!my_charset_same(cs2, cs3)) + if (unlikely(!my_charset_same(cs2, cs3))) { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), cs3->name, cs2->csname); @@ -16000,23 +16105,24 @@ option_value_no_option_type: } set_var_collation_client *var; var= new (thd->mem_root) set_var_collation_client(cs3, cs3, cs3); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } | DEFAULT ROLE_SYM grant_role { LEX *lex = Lex; LEX_USER *user; - if (!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; user->user= current_user; set_var_default_role *var= (new (thd->mem_root) set_var_default_role(user, $3->user)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); + thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; @@ -16026,9 +16132,9 @@ option_value_no_option_type: LEX *lex = Lex; set_var_default_role *var= (new (thd->mem_root) set_var_default_role($5, $3->user)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; @@ -16037,24 +16143,25 @@ option_value_no_option_type: { LEX *lex = Lex; set_var_role *var= new (thd->mem_root) set_var_role($2); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } | PASSWORD_SYM opt_for_user text_or_password { LEX *lex = Lex; set_var_password *var= (new (thd->mem_root) set_var_password(lex->definer)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; } ; + transaction_characteristics: transaction_access_mode | isolation_level @@ -16067,16 +16174,17 @@ transaction_access_mode: { LEX *lex=Lex; Item *item= new (thd->mem_root) Item_int(thd, (int32) $1); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; set_var *var= (new (thd->mem_root) set_var(thd, lex->option_type, find_sys_var(thd, "tx_read_only"), &null_clex_str, item)); - if (var == NULL) + if (unlikely(var == NULL)) + MYSQL_YYABORT; + if (unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } ; @@ -16085,16 +16193,16 @@ isolation_level: { LEX *lex=Lex; Item *item= new (thd->mem_root) Item_int(thd, (int32) $3); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; set_var *var= (new (thd->mem_root) set_var(thd, lex->option_type, find_sys_var(thd, "tx_isolation"), &null_clex_str, item)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } ; @@ -16117,9 +16225,10 @@ opt_for_user: sp_pcontext *spc= lex->spcont; LEX_CSTRING pw= { STRING_WITH_LEN("password") }; - if (spc && spc->find_variable(&pw, false)) + if (unlikely(spc && spc->find_variable(&pw, false))) my_yyabort_error((ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str)); - if (!(lex->definer= (LEX_USER*) thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!(lex->definer= (LEX_USER*) + thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; lex->definer->user= current_user; lex->definer->plugin= empty_clex_str; @@ -16146,19 +16255,19 @@ set_expr_or_default: | ON { $$=new (thd->mem_root) Item_string_sys(thd, "ON", 2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ALL { $$=new (thd->mem_root) Item_string_sys(thd, "ALL", 3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BINARY { $$=new (thd->mem_root) Item_string_sys(thd, "binary", 6); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -16170,7 +16279,7 @@ lock: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK")); lex->sql_command= SQLCOM_LOCK_TABLES; } @@ -16183,14 +16292,14 @@ opt_lock_wait_timeout: {} | WAIT_SYM ulong_num { - if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2) || - set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2)) + if (unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2)) || + unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))) MYSQL_YYABORT; } | NOWAIT_SYM { - if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0) || - set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0)) + if (unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0)) || + unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))) MYSQL_YYABORT; } ; @@ -16210,12 +16319,13 @@ table_lock: { thr_lock_type lock_type= (thr_lock_type) $3; bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE); - if (!Select->add_table_to_list(thd, $1, $2, 0, lock_type, + if (unlikely(!Select-> + add_table_to_list(thd, $1, $2, 0, lock_type, (lock_for_write ? lock_type == TL_WRITE_CONCURRENT_INSERT ? MDL_SHARED_WRITE : MDL_SHARED_NO_READ_WRITE : - MDL_SHARED_READ))) + MDL_SHARED_READ)))) MYSQL_YYABORT; } ; @@ -16237,7 +16347,7 @@ unlock: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK")); lex->sql_command= SQLCOM_UNLOCK_TABLES; } @@ -16253,43 +16363,46 @@ handler: HANDLER_SYM table_ident OPEN_SYM opt_table_alias { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->sql_command = SQLCOM_HA_OPEN; - if (!lex->current_select->add_table_to_list(thd, $2, $4, 0)) + if (unlikely(!lex->current_select->add_table_to_list(thd, $2, $4, + 0))) MYSQL_YYABORT; } | HANDLER_SYM table_ident_nodb CLOSE_SYM { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->sql_command = SQLCOM_HA_CLOSE; - if (!lex->current_select->add_table_to_list(thd, $2, 0, 0)) + if (unlikely(!lex->current_select->add_table_to_list(thd, $2, 0, + 0))) MYSQL_YYABORT; } | HANDLER_SYM table_ident_nodb READ_SYM { LEX *lex=Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->expr_allows_subselect= FALSE; lex->sql_command = SQLCOM_HA_READ; lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ Item *one= new (thd->mem_root) Item_int(thd, (int32) 1); - if (one == NULL) + if (unlikely(one == NULL)) MYSQL_YYABORT; lex->current_select->select_limit= one; lex->current_select->offset_limit= 0; lex->limit_rows_examined= 0; - if (!lex->current_select->add_table_to_list(thd, $2, 0, 0)) + if (unlikely(!lex->current_select->add_table_to_list(thd, $2, 0, + 0))) MYSQL_YYABORT; } handler_read_or_scan opt_where_clause opt_limit_clause { Lex->expr_allows_subselect= TRUE; /* Stored functions are not supported for HANDLER READ. */ - if (Lex->uses_stored_routines()) + if (unlikely(Lex->uses_stored_routines())) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "stored functions in HANDLER ... READ"); @@ -16318,7 +16431,7 @@ handler_rkey_function: LEX *lex=Lex; lex->ha_read_mode = RKEY; lex->ha_rkey_mode=$1; - if (!(lex->insert_list= new (thd->mem_root) List_item)) + if (unlikely(!(lex->insert_list= new (thd->mem_root) List_item))) MYSQL_YYABORT; } '(' values ')' @@ -16349,12 +16462,14 @@ revoke_command: } | grant_privileges ON FUNCTION_SYM grant_ident FROM user_and_role_list { - if (Lex->add_grant_command(thd, SQLCOM_REVOKE, TYPE_ENUM_FUNCTION)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_FUNCTION))) MYSQL_YYABORT; } | grant_privileges ON PROCEDURE_SYM grant_ident FROM user_and_role_list { - if (Lex->add_grant_command(thd, SQLCOM_REVOKE, TYPE_ENUM_PROCEDURE)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } | ALL opt_privileges ',' GRANT OPTION FROM user_and_role_list @@ -16371,7 +16486,7 @@ revoke_command: | admin_option_for_role FROM user_and_role_list { Lex->sql_command= SQLCOM_REVOKE_ROLE; - if (Lex->users_list.push_front($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_front($1, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16399,13 +16514,15 @@ grant_command: | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (Lex->add_grant_command(thd, SQLCOM_GRANT, TYPE_ENUM_FUNCTION)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_FUNCTION))) MYSQL_YYABORT; } | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (Lex->add_grant_command(thd, SQLCOM_GRANT, TYPE_ENUM_PROCEDURE)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } | PROXY_SYM ON user TO_SYM grant_list opt_grant_option @@ -16420,7 +16537,7 @@ grant_command: LEX *lex= Lex; lex->sql_command= SQLCOM_GRANT_ROLE; /* The first role is the one that is granted */ - if (Lex->users_list.push_front($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_front($1, thd->mem_root))) MYSQL_YYABORT; } @@ -16437,12 +16554,12 @@ opt_with_admin_option: role_list: grant_role { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | role_list ',' grant_role { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16450,7 +16567,7 @@ role_list: current_role: CURRENT_ROLE optional_braces { - if (!($$=(LEX_USER*) thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user= current_role; $$->reset_auth(); @@ -16464,17 +16581,17 @@ grant_role: /* trim end spaces (as they'll be lost in mysql.user anyway) */ $1.length= cs->cset->lengthsp(cs, $1.str, $1.length); ((char*) $1.str)[$1.length] = '\0'; - if ($1.length == 0) + if (unlikely($1.length == 0)) my_yyabort_error((ER_INVALID_ROLE, MYF(0), "")); - if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user= $1; $$->host= empty_clex_str; $$->reset_auth(); - if (check_string_char_length(&$$->user, ER_USERNAME, - username_char_length, - cs, 0)) + if (unlikely(check_string_char_length(&$$->user, ER_USERNAME, + username_char_length, + cs, 0))) MYSQL_YYABORT; } | current_role @@ -16560,21 +16677,21 @@ require_list_element: SUBJECT_SYM TEXT_STRING { LEX *lex=Lex; - if (lex->x509_subject) + if (unlikely(lex->x509_subject)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SUBJECT")); lex->x509_subject=$2.str; } | ISSUER_SYM TEXT_STRING { LEX *lex=Lex; - if (lex->x509_issuer) + if (unlikely(lex->x509_issuer)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "ISSUER")); lex->x509_issuer=$2.str; } | CIPHER_SYM TEXT_STRING { LEX *lex=Lex; - if (lex->ssl_cipher) + if (unlikely(lex->ssl_cipher)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CIPHER")); lex->ssl_cipher=$2.str; } @@ -16584,11 +16701,11 @@ grant_ident: '*' { LEX *lex= Lex; - if (lex->copy_db_to(&lex->current_select->db)) + if (unlikely(lex->copy_db_to(&lex->current_select->db))) MYSQL_YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = DB_ACLS & ~GRANT_ACL; - else if (lex->columns.elements) + else if (unlikely(lex->columns.elements)) my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | ident '.' '*' @@ -16597,7 +16714,7 @@ grant_ident: lex->current_select->db= $1; if (lex->grant == GLOBAL_ACLS) lex->grant = DB_ACLS & ~GRANT_ACL; - else if (lex->columns.elements) + else if (unlikely(lex->columns.elements)) my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | '*' '.' '*' @@ -16606,14 +16723,15 @@ grant_ident: lex->current_select->db= null_clex_str; if (lex->grant == GLOBAL_ACLS) lex->grant= GLOBAL_ACLS & ~GRANT_ACL; - else if (lex->columns.elements) + else if (unlikely(lex->columns.elements)) my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | table_ident { LEX *lex=Lex; - if (!lex->current_select->add_table_to_list(thd, $1,NULL, - TL_OPTION_UPDATING)) + if (unlikely(!lex->current_select-> + add_table_to_list(thd, $1,NULL, + TL_OPTION_UPDATING))) MYSQL_YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; @@ -16623,12 +16741,12 @@ grant_ident: user_list: user { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | user_list ',' user { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16636,12 +16754,12 @@ user_list: grant_list: grant_user { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | grant_list ',' grant_user { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16649,12 +16767,12 @@ grant_list: user_and_role_list: user_or_role { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | user_and_role_list ',' user_or_role { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16667,7 +16785,7 @@ grant_user: { $$= $1; $1->pwtext= $4; - if (Lex->sql_command == SQLCOM_REVOKE) + if (unlikely(Lex->sql_command == SQLCOM_REVOKE)) MYSQL_YYABORT; } | user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING @@ -16709,7 +16827,7 @@ column_list_id: ident { String *new_str= new (thd->mem_root) String((const char*) $1.str,$1.length,system_charset_info); - if (new_str == NULL) + if (unlikely(new_str == NULL)) MYSQL_YYABORT; List_iterator <LEX_COLUMN> iter(Lex->columns); class LEX_COLUMN *point; @@ -16727,7 +16845,7 @@ column_list_id: { LEX_COLUMN *col= (new (thd->mem_root) LEX_COLUMN(*new_str,lex->which_columns)); - if (col == NULL) + if (unlikely(col == NULL)) MYSQL_YYABORT; lex->columns.push_back(col, thd->mem_root); } @@ -16936,7 +17054,7 @@ union_clause: union_list: unit_type_decl union_option { - if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) + if (unlikely(Lex->add_select_to_union_list((bool)$2, $1, TRUE))) MYSQL_YYABORT; } union_list_part2 @@ -16952,7 +17070,7 @@ union_list: union_list_view: unit_type_decl union_option { - if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) + if (unlikely(Lex->add_select_to_union_list((bool)$2, $1, TRUE))) MYSQL_YYABORT; } query_expression_body_view @@ -16993,7 +17111,7 @@ order_or_limit: union_head_non_top: unit_type_decl union_option { - if (Lex->add_select_to_union_list((bool)$2, $1, FALSE)) + if (unlikely(Lex->add_select_to_union_list((bool)$2, $1, FALSE))) MYSQL_YYABORT; } ; @@ -17008,27 +17126,20 @@ simple_table: query_specification { $$= $1; } | table_value_constructor { $$= $1; } ; - + table_value_constructor: VALUES { - LEX *lex=Lex; - lex->field_list.empty(); - lex->many_values.empty(); - lex->insert_list=0; + Lex->tvc_start(); } values_list - { - LEX *lex=Lex; - $$= lex->current_select; - mysql_init_select(Lex); - if (!($$->tvc= - new (lex->thd->mem_root) table_value_constr(lex->many_values, $$, $$->options))) - MYSQL_YYABORT; - lex->many_values.empty(); + { + $$= Lex->current_select; + if (Lex->tvc_finalize()) + MYSQL_YYABORT; } ; - + /* Corresponds to the SQL Standard <query specification> ::= @@ -17052,7 +17163,7 @@ query_term_union_not_ready: query_term_union_ready: simple_table opt_select_lock_type { $$= $1; } - | '(' select_paren_derived ')' { $$= $2; } + | '(' select_paren_derived ')' { $$= $2; } ; query_expression_body: @@ -17073,8 +17184,8 @@ subselect: subselect_start: { LEX *lex=Lex; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) + if (unlikely(!lex->expr_allows_subselect || + lex->sql_command == (int)SQLCOM_PURGE)) { thd->parse_error(); MYSQL_YYABORT; @@ -17086,7 +17197,7 @@ subselect_start: (SELECT .. ) UNION ... becomes SELECT * FROM ((SELECT ...) UNION ...) */ - if (mysql_new_select(Lex, 1, NULL)) + if (unlikely(mysql_new_select(Lex, 1, NULL))) MYSQL_YYABORT; } ; @@ -17131,7 +17242,7 @@ query_expression_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } | HIGH_PRIORITY { - if (check_simple_select()) + if (unlikely(Lex->check_simple_select(&$1))) MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_HIGH_PRIORITY; YYPS->m_mdl_type= MDL_SHARED_READ; @@ -17142,13 +17253,13 @@ query_expression_option: | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; } | SQL_BUFFER_RESULT { - if (check_simple_select()) + if (unlikely(Lex->check_simple_select(&$1))) MYSQL_YYABORT; Select->options|= OPTION_BUFFER_RESULT; } | SQL_CALC_FOUND_ROWS { - if (check_simple_select()) + if (unlikely(Lex->check_simple_select(&$1))) MYSQL_YYABORT; Select->options|= OPTION_FOUND_ROWS; } @@ -17307,7 +17418,7 @@ trigger_tail: remember_name opt_if_not_exists { - if (Lex->add_create_options_with_check($2)) + if (unlikely(Lex->add_create_options_with_check($2))) MYSQL_YYABORT; } sp_name @@ -17320,14 +17431,9 @@ trigger_tail: } table_ident /* $10 */ FOR_SYM - remember_name /* $13 */ - { /* $14 */ - /* - FOR token is already passed through (see 'case FOR_SYM' in sql_lex.cc), - so we use _prev() to get it back. - */ - DBUG_ASSERT(YYLIP->lookahead_token >= 0); - Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start_prev(); + remember_name /* $12 */ + { /* $13 */ + Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start(); } EACH_SYM ROW_SYM @@ -17339,7 +17445,7 @@ trigger_tail: LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER")); lex->stmt_definition_begin= $1; @@ -17349,7 +17455,7 @@ trigger_tail: (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17); lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr(); - if (!lex->make_sp_head(thd, $4, &sp_handler_trigger)) + if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger))) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); @@ -17363,7 +17469,7 @@ trigger_tail: sp->set_stmt_end(thd); sp->restore_thd_mem_root(thd); - if (sp->is_not_allowed_in_function("trigger")) + if (unlikely(sp->is_not_allowed_in_function("trigger"))) MYSQL_YYABORT; /* @@ -17371,11 +17477,11 @@ trigger_tail: sp_proc_stmt alternatives are not saving/restoring LEX, so lex->query_tables can be wiped out. */ - if (!lex->select_lex.add_table_to_list(thd, $10, - (LEX_CSTRING*) 0, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (unlikely(!lex->select_lex. + add_table_to_list(thd, $10, (LEX_CSTRING*) 0, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE))) MYSQL_YYABORT; } ; @@ -17391,9 +17497,9 @@ udf_tail: RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys { LEX *lex= thd->lex; - if (lex->add_create_options_with_check($1)) + if (unlikely(lex->add_create_options_with_check($1))) MYSQL_YYABORT; - if (is_native_function(thd, & $2)) + if (unlikely(is_native_function(thd, & $2))) my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $2.str)); lex->sql_command= SQLCOM_CREATE_FUNCTION; lex->udf.name= $2; @@ -17413,7 +17519,8 @@ sf_return_type: } type_with_opt_collate { - if (Lex->sphead->fill_field_definition(thd, Lex->last_field)) + if (unlikely(Lex->sphead->fill_field_definition(thd, + Lex->last_field))) MYSQL_YYABORT; } ; @@ -17423,8 +17530,8 @@ sf_tail: sp_name { Lex->sql_command= SQLCOM_CREATE_SPFUNCTION; - if (!Lex->make_sp_head_no_recursive(thd, $1, $2, - &sp_handler_function)) + if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1, $2, + &sp_handler_function))) MYSQL_YYABORT; } sp_parenthesized_fdparam_list @@ -17439,7 +17546,7 @@ sf_tail: } sp_proc_stmt_in_returns_clause { - if (Lex->sp_body_finalize_function(thd)) + if (unlikely(Lex->sp_body_finalize_function(thd))) MYSQL_YYABORT; } ; @@ -17448,8 +17555,8 @@ sp_tail: opt_if_not_exists sp_name { Lex->sql_command= SQLCOM_CREATE_PROCEDURE; - if (!Lex->make_sp_head_no_recursive(thd, $1, $2, - &sp_handler_procedure)) + if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1, $2, + &sp_handler_procedure))) MYSQL_YYABORT; } sp_parenthesized_pdparam_list @@ -17460,7 +17567,7 @@ sp_tail: } sp_proc_stmt { - if (Lex->sp_body_finalize_procedure(thd)) + if (unlikely(Lex->sp_body_finalize_procedure(thd))) MYSQL_YYABORT; } ; @@ -17499,9 +17606,9 @@ opt_format_xid: /* empty */ { $$= false; } | FORMAT_SYM '=' ident_or_text { - if (!my_strcasecmp(system_charset_info, $3.str, "SQL")) + if (lex_string_eq(&$3, STRING_WITH_LEN("SQL"))) $$= true; - else if (!my_strcasecmp(system_charset_info, $3.str, "RAW")) + else if (lex_string_eq(&$3, STRING_WITH_LEN("RAW"))) $$= false; else { @@ -17516,21 +17623,21 @@ xid: text_string { MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE); - if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))) + if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0); } | text_string ',' text_string { MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); - if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))) + if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length()); } | text_string ',' text_string ',' ulong_num { MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); - if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))) + if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length()); } diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index ec2aeeaefba..f0db33f67ae 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -37,7 +37,7 @@ #include "sql_priv.h" #include "sql_parse.h" /* comp_*_creator */ #include "sql_table.h" /* primary_key_name */ -#include "sql_partition.h" /* mem_alloc_error, partition_info, HASH_PARTITION */ +#include "sql_partition.h" /* partition_info, HASH_PARTITION */ #include "sql_acl.h" /* *_ACL */ #include "sql_class.h" /* Key_part_spec, enum_filetype, Diag_condition_item_name */ #include "slave.h" @@ -67,6 +67,7 @@ #include "lex_token.h" #include "sql_lex.h" #include "sql_sequence.h" +#include "my_base.h" /* this is to get the bison compilation windows warnings out */ #ifdef _MSC_VER @@ -79,7 +80,7 @@ int yylex(void *yylval, void *yythd); #define yyoverflow(A,B,C,D,E,F) \ { \ size_t val= *(F); \ - if (my_yyoverflow((B), (D), &val)) \ + if (unlikely(my_yyoverflow((B), (D), &val))) \ { \ yyerror(thd, (char*) (A)); \ return 2; \ @@ -98,7 +99,7 @@ int yylex(void *yylval, void *yythd); } while (0) #define MYSQL_YYABORT_UNLESS(A) \ - if (!(A)) \ + if (unlikely(!(A))) \ { \ thd->parse_error(); \ MYSQL_YYABORT; \ @@ -155,7 +156,7 @@ void ORAerror(THD *thd, const char *s) #define bincmp_collation(X,Y) \ do \ { \ - if (Lex->set_bincmp(X,Y)) \ + if (unlikely(Lex->set_bincmp(X,Y))) \ MYSQL_YYABORT; \ } while(0) @@ -169,9 +170,10 @@ void ORAerror(THD *thd, const char *s) /* structs */ LEX_CSTRING lex_str; - LEX_SYMBOL symbol; + Lex_ident_cli_st kwd; + Lex_ident_cli_st ident_cli; + Lex_ident_sys_st ident_sys; Lex_string_with_metadata_st lex_string_with_metadata; - Lex_string_with_pos_st lex_string_with_pos; Lex_spblock_st spblock; Lex_spblock_handlers_st spblock_handlers; Lex_length_and_dec_st Lex_length_and_dec; @@ -186,6 +188,7 @@ void ORAerror(THD *thd, const char *s) LEX_CSTRING name; uint offset; } sp_cursor_name_and_offset; + vers_history_point_t vers_history_point; /* pointers */ Create_field *create_field; @@ -267,6 +270,8 @@ void ORAerror(THD *thd, const char *s) enum Window_frame::Frame_exclusion frame_exclusion; enum trigger_order_type trigger_action_order_type; DDL_options_st object_ddl_options; + enum vers_sys_type_t vers_range_unit; + enum Column_definition::enum_column_versioning vers_column_versioning; } %{ @@ -277,10 +282,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 104 shift/reduce conflicts. + Currently there are 63 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 104 +%expect 63 /* Comments for TOKENS. @@ -300,679 +305,277 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); This makes the code grep-able, and helps maintenance. */ - + + +/* + Reserved keywords and operators +*/ %token ABORT_SYM /* INTERNAL (used in lex) */ %token ACCESSIBLE_SYM -%token ACTION /* SQL-2003-N */ %token ADD /* SQL-2003-R */ -%token ADMIN_SYM /* SQL-2003-N */ -%token ADDDATE_SYM /* MYSQL-FUNC */ -%token AFTER_SYM /* SQL-2003-N */ -%token AGAINST -%token AGGREGATE_SYM -%token ALGORITHM_SYM %token ALL /* SQL-2003-R */ %token ALTER /* SQL-2003-R */ -%token ALWAYS_SYM %token ANALYZE_SYM %token AND_AND_SYM /* OPERATOR */ %token AND_SYM /* SQL-2003-R */ -%token ANY_SYM /* SQL-2003-R */ %token AS /* SQL-2003-R */ %token ASC /* SQL-2003-N */ -%token ASCII_SYM /* MYSQL-FUNC */ %token ASENSITIVE_SYM /* FUTURE-USE */ -%token AT_SYM /* SQL-2003-R */ -%token ATOMIC_SYM /* SQL-2003-R */ -%token AUTHORS_SYM -%token AUTOEXTEND_SIZE_SYM -%token AUTO_INC -%token AUTO_SYM -%token AVG_ROW_LENGTH -%token AVG_SYM /* SQL-2003-N */ -%token BACKUP_SYM %token BEFORE_SYM /* SQL-2003-N */ -%token BEGIN_SYM /* SQL-2003-R */ %token BETWEEN_SYM /* SQL-2003-R */ %token BIGINT /* SQL-2003-R */ %token BINARY /* SQL-2003-R */ -%token BINLOG_SYM %token BIN_NUM %token BIT_AND /* MYSQL-FUNC */ %token BIT_OR /* MYSQL-FUNC */ -%token BIT_SYM /* MYSQL-FUNC */ %token BIT_XOR /* MYSQL-FUNC */ %token BLOB_SYM /* SQL-2003-R */ -%token BLOCK_SYM -%token BODY_SYM /* Oracle-R */ -%token BOOLEAN_SYM /* SQL-2003-R */ -%token BOOL_SYM %token BOTH /* SQL-2003-R */ -%token BTREE_SYM %token BY /* SQL-2003-R */ -%token BYTE_SYM -%token CACHE_SYM %token CALL_SYM /* SQL-2003-R */ %token CASCADE /* SQL-2003-N */ -%token CASCADED /* SQL-2003-R */ %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ -%token CATALOG_NAME_SYM /* SQL-2003-N */ -%token CHAIN_SYM /* SQL-2003-N */ %token CHANGE -%token CHANGED -%token CHARSET %token CHAR_SYM /* SQL-2003-R */ -%token CHECKPOINT_SYM -%token CHECKSUM_SYM %token CHECK_SYM /* SQL-2003-R */ -%token CIPHER_SYM -%token CLASS_ORIGIN_SYM /* SQL-2003-N */ -%token CLIENT_SYM -%token CLOSE_SYM /* SQL-2003-R */ -%token CLOB /* SQL-2003-R */ -%token COALESCE /* SQL-2003-N */ -%token CODE_SYM %token COLLATE_SYM /* SQL-2003-R */ -%token COLLATION_SYM /* SQL-2003-N */ -%token COLUMNS -%token COLUMN_ADD_SYM -%token COLUMN_CHECK_SYM -%token COLUMN_CREATE_SYM -%token COLUMN_DELETE_SYM -%token COLUMN_GET_SYM -%token COLUMN_SYM /* SQL-2003-R */ -%token COLUMN_NAME_SYM /* SQL-2003-N */ -%token COMMENT_SYM -%token COMMITTED_SYM /* SQL-2003-N */ -%token COMMIT_SYM /* SQL-2003-R */ -%token COMPACT_SYM -%token COMPLETION_SYM -%token COMPRESSED_SYM -%token CONCURRENT %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ -%token CONNECTION_SYM -%token CONSISTENT_SYM %token CONSTRAINT /* SQL-2003-R */ -%token CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ -%token CONSTRAINT_NAME_SYM /* SQL-2003-N */ -%token CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ -%token CONTAINS_SYM /* SQL-2003-N */ -%token CONTEXT_SYM %token CONTINUE_SYM /* SQL-2003-R */ -%token CONTRIBUTORS_SYM %token CONVERT_SYM /* SQL-2003-N */ %token COUNT_SYM /* SQL-2003-N */ -%token CPU_SYM %token CREATE /* SQL-2003-R */ %token CROSS /* SQL-2003-R */ -%token CUBE_SYM /* SQL-2003-R */ %token CUME_DIST_SYM %token CURDATE /* MYSQL-FUNC */ -%token CURRENT_SYM /* SQL-2003-R */ %token CURRENT_USER /* SQL-2003-R */ %token CURRENT_ROLE /* SQL-2003-R */ -%token CURRENT_POS_SYM %token CURSOR_SYM /* SQL-2003-R */ -%token CURSOR_NAME_SYM /* SQL-2003-N */ %token CURTIME /* MYSQL-FUNC */ -%token CYCLE_SYM %token DATABASE %token DATABASES -%token DATAFILE_SYM -%token DATA_SYM /* SQL-2003-N */ -%token DATETIME %token DATE_ADD_INTERVAL /* MYSQL-FUNC */ -%token DATE_FORMAT_SYM /* MYSQL-FUNC */ %token DATE_SUB_INTERVAL /* MYSQL-FUNC */ -%token DATE_SYM /* SQL-2003-R */ %token DAY_HOUR_SYM %token DAY_MICROSECOND_SYM %token DAY_MINUTE_SYM %token DAY_SECOND_SYM -%token DAY_SYM /* SQL-2003-R */ -%token DEALLOCATE_SYM /* SQL-2003-R */ %token DECIMAL_NUM %token DECIMAL_SYM /* SQL-2003-R */ %token DECLARE_SYM /* SQL-2003-R */ -%token DECODE_SYM /* Oracle function, non-reserved */ %token DEFAULT /* SQL-2003-R */ -%token DEFINER_SYM -%token DELAYED_SYM -%token DELAY_KEY_WRITE_SYM %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ %token DENSE_RANK_SYM %token DESC /* SQL-2003-N */ %token DESCRIBE /* SQL-2003-R */ -%token DES_KEY_FILE %token DETERMINISTIC_SYM /* SQL-2003-R */ -%token DIAGNOSTICS_SYM /* SQL-2003-N */ -%token DIRECTORY_SYM -%token DISABLE_SYM -%token DISCARD -%token DISK_SYM %token DISTINCT /* SQL-2003-R */ %token DIV_SYM %token DOUBLE_SYM /* SQL-2003-R */ %token DO_DOMAIN_IDS_SYM -%token DO_SYM %token DOT_DOT_SYM %token DROP /* SQL-2003-R */ %token DUAL_SYM -%token DUMPFILE -%token DUPLICATE_SYM -%token DYNAMIC_SYM /* SQL-2003-R */ %token EACH_SYM /* SQL-2003-R */ %token ELSE /* SQL-2003-R */ %token ELSEIF_SYM -%token ELSIF_SYM /* Oracle, reserved in PL/SQL*/ -%token ENABLE_SYM %token ENCLOSED -%token END /* SQL-2003-R */ -%token ENDS_SYM %token END_OF_INPUT /* INTERNAL */ -%token ENGINES_SYM -%token ENGINE_SYM -%token ENUM %token EQUAL_SYM /* OPERATOR */ -%token ERROR_SYM -%token ERRORS %token ESCAPED -%token ESCAPE_SYM /* SQL-2003-R */ -%token EVENTS_SYM -%token EVENT_SYM -%token EVERY_SYM /* SQL-2003-N */ -%token EXCHANGE_SYM -%token EXAMINED_SYM %token EXCEPT_SYM /* SQL-2003-R */ -%token EXCLUDE_SYM /* SQL-2011-N */ -%token EXECUTE_SYM /* SQL-2003-R */ -%token EXCEPTION_SYM /* SQL-2003-N, Oracle-PLSQL-R */ %token EXISTS /* SQL-2003-R */ -%token EXIT_SYM -%token EXPANSION_SYM -%token EXPORT_SYM -%token EXTENDED_SYM -%token EXTENT_SIZE_SYM %token EXTRACT_SYM /* SQL-2003-N */ %token FALSE_SYM /* SQL-2003-R */ -%token FAST_SYM -%token FAULTS_SYM %token FETCH_SYM /* SQL-2003-R */ -%token FILE_SYM %token FIRST_VALUE_SYM /* SQL-2011 */ -%token FIRST_SYM /* SQL-2003-N */ -%token FIXED_SYM %token FLOAT_NUM %token FLOAT_SYM /* SQL-2003-R */ -%token FLUSH_SYM -%token FOLLOWS_SYM /* MYSQL trigger*/ -%token FOLLOWING_SYM /* SQL-2011-N */ -%token FORCE_SYM %token FOREIGN /* SQL-2003-R */ %token FOR_SYM /* SQL-2003-R */ %token FOR_SYSTEM_TIME_SYM /* INTERNAL */ -%token FORMAT_SYM -%token FOUND_SYM /* SQL-2003-R */ %token FROM -%token FULL /* SQL-2003-R */ %token FULLTEXT_SYM -%token FUNCTION_SYM /* SQL-2003-R */ %token GE -%token GENERAL -%token GENERATED_SYM -%token GEOMETRYCOLLECTION -%token GEOMETRY_SYM -%token GET_FORMAT /* MYSQL-FUNC */ -%token GET_SYM /* SQL-2003-R */ -%token GLOBAL_SYM /* SQL-2003-R */ -%token GOTO_SYM /* Oracle, reserved in PL/SQL*/ %token GRANT /* SQL-2003-R */ -%token GRANTS %token GROUP_SYM /* SQL-2003-R */ %token GROUP_CONCAT_SYM %token LAG_SYM /* SQL-2011 */ %token LEAD_SYM /* SQL-2011 */ -%token HANDLER_SYM -%token HARD_SYM -%token HASH_SYM %token HAVING /* SQL-2003-R */ -%token HELP_SYM %token HEX_NUM %token HEX_STRING -%token HIGH_PRIORITY -%token HISTORY_SYM /* MYSQL */ -%token HOST_SYM -%token HOSTS_SYM %token HOUR_MICROSECOND_SYM %token HOUR_MINUTE_SYM %token HOUR_SECOND_SYM -%token HOUR_SYM /* SQL-2003-R */ -%token ID_SYM /* MYSQL */ %token IDENT -%token IDENTIFIED_SYM %token IDENT_QUOTED %token IF_SYM %token IGNORE_DOMAIN_IDS_SYM %token IGNORE_SYM -%token IGNORE_SERVER_IDS_SYM -%token IMMEDIATE_SYM /* SQL-2003-R */ -%token IMPORT -%token INCREMENT_SYM -%token INDEXES %token INDEX_SYM %token INFILE -%token INITIAL_SIZE_SYM %token INNER_SYM /* SQL-2003-R */ %token INOUT_SYM /* SQL-2003-R */ %token INSENSITIVE_SYM /* SQL-2003-R */ %token INSERT /* SQL-2003-R */ -%token INSERT_METHOD -%token INSTALL_SYM %token INTERSECT_SYM /* SQL-2003-R */ %token INTERVAL_SYM /* SQL-2003-R */ %token INTO /* SQL-2003-R */ %token INT_SYM /* SQL-2003-R */ -%token INVOKER_SYM %token IN_SYM /* SQL-2003-R */ -%token IO_SYM -%token IPC_SYM %token IS /* SQL-2003-R */ -%token ISOLATION /* SQL-2003-R */ -%token ISOPEN_SYM /* Oracle-N */ -%token ISSUER_SYM %token ITERATE_SYM -%token INVISIBLE_SYM %token JOIN_SYM /* SQL-2003-R */ -%token JSON_SYM %token KEYS -%token KEY_BLOCK_SIZE %token KEY_SYM /* SQL-2003-N */ %token KILL_SYM -%token LANGUAGE_SYM /* SQL-2003-R */ -%token LAST_SYM /* SQL-2003-N */ -%token LAST_VALUE -%token LASTVAL_SYM /* PostgreSQL sequence function */ %token LE /* OPERATOR */ %token LEADING /* SQL-2003-R */ -%token LEAVES %token LEAVE_SYM %token LEFT /* SQL-2003-R */ -%token LESS_SYM -%token LEVEL_SYM %token LEX_HOSTNAME %token LIKE /* SQL-2003-R */ %token LIMIT %token LINEAR_SYM %token LINES -%token LINESTRING -%token LIST_SYM %token LOAD -%token LOCAL_SYM /* SQL-2003-R */ %token LOCATOR_SYM /* SQL-2003-N */ -%token LOCKS_SYM %token LOCK_SYM -%token LOGFILE_SYM -%token LOGS_SYM %token LONGBLOB %token LONGTEXT %token LONG_NUM %token LONG_SYM %token LOOP_SYM %token LOW_PRIORITY -%token MASTER_CONNECT_RETRY_SYM -%token MASTER_DELAY_SYM -%token MASTER_GTID_POS_SYM -%token MASTER_HOST_SYM -%token MASTER_LOG_FILE_SYM -%token MASTER_LOG_POS_SYM -%token MASTER_PASSWORD_SYM -%token MASTER_PORT_SYM -%token MASTER_SERVER_ID_SYM -%token MASTER_SSL_CAPATH_SYM -%token MASTER_SSL_CA_SYM -%token MASTER_SSL_CERT_SYM -%token MASTER_SSL_CIPHER_SYM -%token MASTER_SSL_CRL_SYM -%token MASTER_SSL_CRLPATH_SYM -%token MASTER_SSL_KEY_SYM -%token MASTER_SSL_SYM %token MASTER_SSL_VERIFY_SERVER_CERT_SYM -%token MASTER_SYM -%token MASTER_USER_SYM -%token MASTER_USE_GTID_SYM -%token MASTER_HEARTBEAT_PERIOD_SYM %token MATCH /* SQL-2003-R */ -%token MAX_CONNECTIONS_PER_HOUR -%token MAX_QUERIES_PER_HOUR -%token MAX_ROWS -%token MAX_SIZE_SYM %token MAX_SYM /* SQL-2003-N */ -%token MAX_UPDATES_PER_HOUR -%token MAX_STATEMENT_TIME_SYM -%token MAX_USER_CONNECTIONS_SYM %token MAXVALUE_SYM /* SQL-2003-N */ %token MEDIAN_SYM %token MEDIUMBLOB %token MEDIUMINT %token MEDIUMTEXT -%token MEDIUM_SYM -%token MEMORY_SYM -%token MERGE_SYM /* SQL-2003-R */ -%token MESSAGE_TEXT_SYM /* SQL-2003-N */ -%token MICROSECOND_SYM /* MYSQL-FUNC */ -%token MIGRATE_SYM %token MINUTE_MICROSECOND_SYM %token MINUTE_SECOND_SYM -%token MINUTE_SYM /* SQL-2003-R */ -%token MINVALUE_SYM -%token MIN_ROWS %token MIN_SYM /* SQL-2003-N */ -%token MODE_SYM %token MODIFIES_SYM /* SQL-2003-R */ -%token MODIFY_SYM %token MOD_SYM /* SQL-2003-N */ -%token MONTH_SYM /* SQL-2003-R */ -%token MULTILINESTRING -%token MULTIPOINT -%token MULTIPOLYGON -%token MUTEX_SYM -%token MYSQL_SYM -%token MYSQL_ERRNO_SYM -%token NAMES_SYM /* SQL-2003-N */ -%token NAME_SYM /* SQL-2003-N */ -%token NATIONAL_SYM /* SQL-2003-R */ +%token MYSQL_CONCAT_SYM /* OPERATOR */ %token NATURAL /* SQL-2003-R */ %token NCHAR_STRING -%token NCHAR_SYM /* SQL-2003-R */ %token NE /* OPERATOR */ %token NEG -%token NEW_SYM /* SQL-2003-R */ -%token NEXT_SYM /* SQL-2003-N */ -%token NEXTVAL_SYM /* PostgreSQL sequence function */ -%token NOCACHE_SYM -%token NOCYCLE_SYM -%token NODEGROUP_SYM -%token NONE_SYM /* SQL-2003-R */ %token NOT2_SYM %token NOT_SYM /* SQL-2003-R */ -%token NOTFOUND_SYM /* Oracle-R */ %token NOW_SYM -%token NO_SYM /* SQL-2003-R */ -%token NOMAXVALUE_SYM -%token NOMINVALUE_SYM -%token NO_WAIT_SYM -%token NOWAIT_SYM %token NO_WRITE_TO_BINLOG %token NTILE_SYM %token NULL_SYM /* SQL-2003-R */ %token NUM -%token NUMBER_SYM /* SQL-2003-N */ %token NUMERIC_SYM /* SQL-2003-R */ %token NTH_VALUE_SYM /* SQL-2011 */ -%token NVARCHAR_SYM -%token OF_SYM /* SQL-1992-R, Oracle-R */ -%token OFFSET_SYM -%token OLD_PASSWORD_SYM %token ON /* SQL-2003-R */ -%token ONE_SYM -%token ONLY_SYM /* SQL-2003-R */ -%token ONLINE_SYM -%token OPEN_SYM /* SQL-2003-R */ %token OPTIMIZE -%token OPTIONS_SYM -%token OPTION /* SQL-2003-N */ %token OPTIONALLY +%token ORACLE_CONCAT_SYM /* INTERNAL */ %token OR2_SYM %token ORDER_SYM /* SQL-2003-R */ -%token OR_OR_SYM /* OPERATOR */ %token OR_SYM /* SQL-2003-R */ -%token OTHERS_SYM /* SQL-2011-N */ %token OUTER %token OUTFILE %token OUT_SYM /* SQL-2003-R */ %token OVER_SYM -%token OWNER_SYM -%token PACKAGE_SYM /* Oracle-R */ -%token PACK_KEYS_SYM -%token PAGE_SYM %token PAGE_CHECKSUM_SYM %token PARAM_MARKER -%token PARSER_SYM %token PARSE_VCOL_EXPR_SYM -%token PARTIAL /* SQL-2003-N */ %token PARTITION_SYM /* SQL-2003-R */ -%token PARTITIONS_SYM -%token PARTITIONING_SYM -%token PASSWORD_SYM %token PERCENT_RANK_SYM %token PERCENTILE_CONT_SYM %token PERCENTILE_DISC_SYM -%token PERIOD_SYM /* SQL-2011-R */ -%token PERSISTENT_SYM -%token PHASE_SYM -%token PLUGINS_SYM -%token PLUGIN_SYM -%token POINT_SYM -%token POLYGON -%token PORT_SYM %token POSITION_SYM /* SQL-2003-N */ -%token PRECEDES_SYM /* MYSQL */ -%token PRECEDING_SYM /* SQL-2011-N */ %token PRECISION /* SQL-2003-R */ -%token PREPARE_SYM /* SQL-2003-R */ -%token PRESERVE_SYM -%token PREV_SYM -%token PREVIOUS_SYM %token PRIMARY_SYM /* SQL-2003-R */ -%token PRIVILEGES /* SQL-2003-N */ %token PROCEDURE_SYM /* SQL-2003-R */ -%token PROCESS -%token PROCESSLIST_SYM -%token PROFILE_SYM -%token PROFILES_SYM -%token PROXY_SYM %token PURGE -%token QUARTER_SYM -%token QUERY_SYM -%token QUICK -%token RAISE_SYM /* Oracle-PLSQL-R */ %token RANGE_SYM /* SQL-2003-R */ %token RANK_SYM -%token RAW /* Oracle */ %token READS_SYM /* SQL-2003-R */ -%token READ_ONLY_SYM %token READ_SYM /* SQL-2003-N */ %token READ_WRITE_SYM %token REAL /* SQL-2003-R */ -%token REBUILD_SYM -%token RECOVER_SYM %token RECURSIVE_SYM -%token REDOFILE_SYM -%token REDO_BUFFER_SIZE_SYM -%token REDUNDANT_SYM +%token REF_SYSTEM_ID_SYM %token REFERENCES /* SQL-2003-R */ %token REGEXP -%token RELAY -%token RELAYLOG_SYM -%token RELAY_LOG_FILE_SYM -%token RELAY_LOG_POS_SYM -%token RELAY_THREAD %token RELEASE_SYM /* SQL-2003-R */ -%token RELOAD -%token REMOVE_SYM %token RENAME -%token REORGANIZE_SYM -%token REPAIR -%token REPEATABLE_SYM /* SQL-2003-N */ %token REPEAT_SYM /* MYSQL-FUNC */ %token REPLACE /* MYSQL-FUNC */ -%token REPLICATION %token REQUIRE_SYM -%token RESET_SYM -%token RESTART_SYM %token RESIGNAL_SYM /* SQL-2003-R */ -%token RESOURCES -%token RESTORE_SYM %token RESTRICT -%token RESUME_SYM -%token RETURNED_SQLSTATE_SYM /* SQL-2003-N */ %token RETURNING_SYM -%token RETURNS_SYM /* SQL-2003-R */ %token RETURN_SYM /* SQL-2003-R */ -%token REUSE_SYM /* Oracle-R */ -%token REVERSE_SYM %token REVOKE /* SQL-2003-R */ %token RIGHT /* SQL-2003-R */ -%token ROLE_SYM -%token ROLLBACK_SYM /* SQL-2003-R */ -%token ROLLUP_SYM /* SQL-2003-R */ -%token ROUTINE_SYM /* SQL-2003-N */ -%token ROWCOUNT_SYM /* Oracle-N */ -%token ROW_SYM /* SQL-2003-R */ %token ROWS_SYM /* SQL-2003-R */ -%token ROWTYPE_SYM /* Oracle-PLSQL-R */ -%token ROW_COUNT_SYM /* SQL-2003-N */ -%token ROW_FORMAT_SYM %token ROW_NUMBER_SYM -%token RTREE_SYM -%token SAVEPOINT_SYM /* SQL-2003-R */ -%token SCHEDULE_SYM -%token SCHEMA_NAME_SYM /* SQL-2003-N */ %token SECOND_MICROSECOND_SYM -%token SECOND_SYM /* SQL-2003-R */ -%token SECURITY_SYM /* SQL-2003-N */ %token SELECT_SYM /* SQL-2003-R */ %token SENSITIVE_SYM /* FUTURE-USE */ %token SEPARATOR_SYM -%token SEQUENCE_SYM -%token SERIALIZABLE_SYM /* SQL-2003-N */ -%token SERIAL_SYM -%token SESSION_SYM /* SQL-2003-N */ -%token SERVER_SYM %token SERVER_OPTIONS %token SET /* SQL-2003-R */ -%token SETVAL_SYM /* PostgreSQL sequence function */ %token SET_VAR -%token SHARE_SYM %token SHIFT_LEFT /* OPERATOR */ %token SHIFT_RIGHT /* OPERATOR */ %token SHOW -%token SHUTDOWN %token SIGNAL_SYM /* SQL-2003-R */ -%token SIGNED_SYM -%token SIMPLE_SYM /* SQL-2003-N */ -%token SLAVE -%token SLAVES -%token SLAVE_POS_SYM -%token SLOW %token SMALLINT /* SQL-2003-R */ -%token SNAPSHOT_SYM -%token SOCKET_SYM -%token SOFT_SYM -%token SONAME_SYM -%token SOUNDS_SYM -%token SOURCE_SYM %token SPATIAL_SYM %token SPECIFIC_SYM /* SQL-2003-R */ %token SQLEXCEPTION_SYM /* SQL-2003-R */ %token SQLSTATE_SYM /* SQL-2003-R */ %token SQLWARNING_SYM /* SQL-2003-R */ %token SQL_BIG_RESULT -%token SQL_BUFFER_RESULT -%token SQL_CACHE_SYM -%token SQL_CALC_FOUND_ROWS -%token SQL_NO_CACHE_SYM %token SQL_SMALL_RESULT %token SQL_SYM /* SQL-2003-R */ -%token SQL_THREAD -%token REF_SYSTEM_ID_SYM %token SSL_SYM %token STARTING -%token STARTS_SYM -%token START_SYM /* SQL-2003-R */ -%token STATEMENT_SYM %token STATS_AUTO_RECALC_SYM %token STATS_PERSISTENT_SYM %token STATS_SAMPLE_PAGES_SYM -%token STATUS_SYM %token STDDEV_SAMP_SYM /* SQL-2003-N */ %token STD_SYM -%token STOP_SYM -%token STORAGE_SYM -%token STORED_SYM %token STRAIGHT_JOIN -%token STRING_SYM -%token SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ -%token SUBDATE_SYM -%token SUBJECT_SYM -%token SUBPARTITIONS_SYM -%token SUBPARTITION_SYM %token SUBSTRING /* SQL-2003-N */ %token SUM_SYM /* SQL-2003-N */ -%token SUPER_SYM -%token SUSPEND_SYM -%token SWAPS_SYM -%token SWITCHES_SYM %token SYSDATE -%token SYSTEM /* SQL-2011-R */ -%token SYSTEM_TIME_SYM /* SQL-2011-R */ -%token TABLES -%token TABLESPACE %token TABLE_REF_PRIORITY %token TABLE_SYM /* SQL-2003-R */ -%token TABLE_CHECKSUM_SYM -%token TABLE_NAME_SYM /* SQL-2003-N */ -%token TEMPORARY /* SQL-2003-N */ -%token TEMPTABLE_SYM %token TERMINATED %token TEXT_STRING -%token TEXT_SYM -%token THAN_SYM %token THEN_SYM /* SQL-2003-R */ -%token TIES_SYM /* SQL-2011-N */ -%token TIMESTAMP /* SQL-2003-R */ -%token TIMESTAMP_ADD -%token TIMESTAMP_DIFF -%token TIME_SYM /* SQL-2003-R */ %token TINYBLOB %token TINYINT %token TINYTEXT %token TO_SYM /* SQL-2003-R */ %token TRAILING /* SQL-2003-R */ -%token TRANSACTION_SYM -%token TRANSACTIONAL_SYM -%token TRIGGERS_SYM %token TRIGGER_SYM /* SQL-2003-R */ %token TRIM /* SQL-2003-N */ -%token TRIM_ORACLE %token TRUE_SYM /* SQL-2003-R */ -%token TRUNCATE_SYM -%token TYPES_SYM -%token TYPE_SYM /* SQL-2003-N */ -%token UDF_RETURNS_SYM %token ULONGLONG_NUM -%token UNBOUNDED_SYM /* SQL-2011-N */ -%token UNCOMMITTED_SYM /* SQL-2003-N */ -%token UNDEFINED_SYM %token UNDERSCORE_CHARSET -%token UNDOFILE_SYM -%token UNDO_BUFFER_SIZE_SYM %token UNDO_SYM /* FUTURE-USE */ -%token UNICODE_SYM -%token UNINSTALL_SYM %token UNION_SYM /* SQL-2003-R */ %token UNIQUE_SYM -%token UNKNOWN_SYM /* SQL-2003-R */ %token UNLOCK_SYM %token UNSIGNED -%token UNTIL_SYM %token UPDATE_SYM /* SQL-2003-R */ -%token UPGRADE_SYM %token USAGE /* SQL-2003-N */ -%token USER_SYM /* SQL-2003-R */ -%token USE_FRM %token USE_SYM %token USING /* SQL-2003-R */ %token UTC_DATE_SYM @@ -981,83 +584,598 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token VALUES /* SQL-2003-R */ %token VALUES_IN_SYM %token VALUES_LESS_SYM -%token VALUE_SYM /* SQL-2003-R */ %token VARBINARY %token VARCHAR /* SQL-2003-R */ -%token VARCHAR2 /* Oracle */ -%token VARIABLES %token VARIANCE_SYM %token VARYING /* SQL-2003-R */ %token VAR_SAMP_SYM -%token VERSIONING_SYM /* SQL-2011-R */ -%token VIA_SYM -%token VIEW_SYM /* SQL-2003-N */ -%token VIRTUAL_SYM -%token WAIT_SYM -%token WARNINGS -%token WEEK_SYM -%token WEIGHT_STRING_SYM %token WHEN_SYM /* SQL-2003-R */ %token WHERE /* SQL-2003-R */ -%token WINDOW_SYM %token WHILE_SYM %token WITH /* SQL-2003-R */ -%token WITHIN -%token WITHOUT /* SQL-2003-R */ %token WITH_CUBE_SYM /* INTERNAL */ %token WITH_ROLLUP_SYM /* INTERNAL */ %token WITH_SYSTEM_SYM /* INTERNAL */ -%token WORK_SYM /* SQL-2003-N */ -%token WRAPPER_SYM -%token WRITE_SYM /* SQL-2003-N */ -%token X509_SYM -%token XA_SYM -%token XML_SYM %token XOR %token YEAR_MONTH_SYM -%token YEAR_SYM /* SQL-2003-R */ %token ZEROFILL -%token IMPOSSIBLE_ACTION /* To avoid warning for yyerrlab1 */ +%token IMPOSSIBLE_ACTION /* To avoid warning for yyerrlab1 */ + + +/* + Keywords that have different reserved status in std/oracle modes. +*/ +%token BODY_SYM /* Oracle-R */ +%token COMMENT_SYM +%token ELSIF_SYM /* Oracle, reserved in PL/SQL*/ +%token GOTO_SYM /* Oracle, reserved in PL/SQL*/ +%token OTHERS_SYM /* SQL-2011-N */ +%token PACKAGE_SYM /* Oracle-R */ +%token RAISE_SYM /* Oracle-PLSQL-R */ +%token ROWTYPE_SYM /* Oracle-PLSQL-R */ + +/* + Non-reserved keywords +*/ + +%token <kwd> ACTION /* SQL-2003-N */ +%token <kwd> ADMIN_SYM /* SQL-2003-N */ +%token <kwd> ADDDATE_SYM /* MYSQL-FUNC */ +%token <kwd> AFTER_SYM /* SQL-2003-N */ +%token <kwd> AGAINST +%token <kwd> AGGREGATE_SYM +%token <kwd> ALGORITHM_SYM +%token <kwd> ALWAYS_SYM +%token <kwd> ANY_SYM /* SQL-2003-R */ +%token <kwd> ASCII_SYM /* MYSQL-FUNC */ +%token <kwd> AT_SYM /* SQL-2003-R */ +%token <kwd> ATOMIC_SYM /* SQL-2003-R */ +%token <kwd> AUTHORS_SYM +%token <kwd> AUTOEXTEND_SIZE_SYM +%token <kwd> AUTO_INC +%token <kwd> AUTO_SYM +%token <kwd> AVG_ROW_LENGTH +%token <kwd> AVG_SYM /* SQL-2003-N */ +%token <kwd> BACKUP_SYM +%token <kwd> BEGIN_SYM /* SQL-2003-R, PLSQL-R */ +%token <kwd> BINLOG_SYM +%token <kwd> BIT_SYM /* MYSQL-FUNC */ +%token <kwd> BLOCK_SYM +%token <kwd> BOOL_SYM +%token <kwd> BOOLEAN_SYM /* SQL-2003-R, PLSQL-R */ +%token <kwd> BTREE_SYM +%token <kwd> BYTE_SYM +%token <kwd> CACHE_SYM +%token <kwd> CASCADED /* SQL-2003-R */ +%token <kwd> CATALOG_NAME_SYM /* SQL-2003-N */ +%token <kwd> CHAIN_SYM /* SQL-2003-N */ +%token <kwd> CHANGED +%token <kwd> CHARSET +%token <kwd> CHECKPOINT_SYM +%token <kwd> CHECKSUM_SYM +%token <kwd> CIPHER_SYM +%token <kwd> CLASS_ORIGIN_SYM /* SQL-2003-N */ +%token <kwd> CLIENT_SYM +%token <kwd> CLOB /* SQL-2003-R */ +%token <kwd> CLOSE_SYM /* SQL-2003-R */ +%token <kwd> COALESCE /* SQL-2003-N */ +%token <kwd> CODE_SYM +%token <kwd> COLLATION_SYM /* SQL-2003-N */ +%token <kwd> COLUMNS +%token <kwd> COLUMN_ADD_SYM +%token <kwd> COLUMN_CHECK_SYM +%token <kwd> COLUMN_CREATE_SYM +%token <kwd> COLUMN_DELETE_SYM +%token <kwd> COLUMN_GET_SYM +%token <kwd> COLUMN_SYM /* SQL-2003-R */ +%token <kwd> COLUMN_NAME_SYM /* SQL-2003-N */ +%token <kwd> COMMITTED_SYM /* SQL-2003-N */ +%token <kwd> COMMIT_SYM /* SQL-2003-R */ +%token <kwd> COMPACT_SYM +%token <kwd> COMPLETION_SYM +%token <kwd> COMPRESSED_SYM +%token <kwd> CONCURRENT +%token <kwd> CONNECTION_SYM +%token <kwd> CONSISTENT_SYM +%token <kwd> CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ +%token <kwd> CONSTRAINT_NAME_SYM /* SQL-2003-N */ +%token <kwd> CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ +%token <kwd> CONTAINS_SYM /* SQL-2003-N */ +%token <kwd> CONTEXT_SYM +%token <kwd> CONTRIBUTORS_SYM +%token <kwd> CPU_SYM +%token <kwd> CUBE_SYM /* SQL-2003-R */ +%token <kwd> CURRENT_SYM /* SQL-2003-R */ +%token <kwd> CURRENT_POS_SYM +%token <kwd> CURSOR_NAME_SYM /* SQL-2003-N */ +%token <kwd> CYCLE_SYM +%token <kwd> DATAFILE_SYM +%token <kwd> DATA_SYM /* SQL-2003-N */ +%token <kwd> DATETIME +%token <kwd> DATE_FORMAT_SYM /* MYSQL-FUNC */ +%token <kwd> DATE_SYM /* SQL-2003-R, Oracle-R, PLSQL-R */ +%token <kwd> DAY_SYM /* SQL-2003-R */ +%token <kwd> DEALLOCATE_SYM /* SQL-2003-R */ +%token <kwd> DECODE_SYM /* Oracle function, non-reserved */ +%token <kwd> DEFINER_SYM +%token <kwd> DELAYED_SYM +%token <kwd> DELAY_KEY_WRITE_SYM +%token <kwd> DES_KEY_FILE +%token <kwd> DIAGNOSTICS_SYM /* SQL-2003-N */ +%token <kwd> DIRECTORY_SYM +%token <kwd> DISABLE_SYM +%token <kwd> DISCARD +%token <kwd> DISK_SYM +%token <kwd> DO_SYM +%token <kwd> DUMPFILE +%token <kwd> DUPLICATE_SYM +%token <kwd> DYNAMIC_SYM /* SQL-2003-R */ +%token <kwd> ENABLE_SYM +%token <kwd> END /* SQL-2003-R, PLSQL-R */ +%token <kwd> ENDS_SYM +%token <kwd> ENGINES_SYM +%token <kwd> ENGINE_SYM +%token <kwd> ENUM +%token <kwd> ERROR_SYM +%token <kwd> ERRORS +%token <kwd> ESCAPE_SYM /* SQL-2003-R */ +%token <kwd> EVENTS_SYM +%token <kwd> EVENT_SYM +%token <kwd> EVERY_SYM /* SQL-2003-N */ +%token <kwd> EXCHANGE_SYM +%token <kwd> EXAMINED_SYM +%token <kwd> EXCLUDE_SYM /* SQL-2011-N */ +%token <kwd> EXECUTE_SYM /* SQL-2003-R */ +%token <kwd> EXCEPTION_SYM /* SQL-2003-N, Oracle-PLSQL-R */ +%token <kwd> EXIT_SYM +%token <kwd> EXPANSION_SYM +%token <kwd> EXPORT_SYM +%token <kwd> EXTENDED_SYM +%token <kwd> EXTENT_SIZE_SYM +%token <kwd> FAST_SYM +%token <kwd> FAULTS_SYM +%token <kwd> FILE_SYM +%token <kwd> FIRST_SYM /* SQL-2003-N */ +%token <kwd> FIXED_SYM +%token <kwd> FLUSH_SYM +%token <kwd> FOLLOWS_SYM /* MYSQL trigger*/ +%token <kwd> FOLLOWING_SYM /* SQL-2011-N */ +%token <kwd> FORCE_SYM +%token <kwd> FORMAT_SYM +%token <kwd> FOUND_SYM /* SQL-2003-R */ +%token <kwd> FULL /* SQL-2003-R */ +%token <kwd> FUNCTION_SYM /* SQL-2003-R, Oracle-PLSQL-R */ +%token <kwd> GENERAL +%token <kwd> GENERATED_SYM +%token <kwd> GEOMETRYCOLLECTION +%token <kwd> GEOMETRY_SYM +%token <kwd> GET_FORMAT /* MYSQL-FUNC */ +%token <kwd> GET_SYM /* SQL-2003-R */ +%token <kwd> GLOBAL_SYM /* SQL-2003-R */ +%token <kwd> GRANTS +%token <kwd> HANDLER_SYM +%token <kwd> HARD_SYM +%token <kwd> HASH_SYM +%token <kwd> HELP_SYM +%token <kwd> HIGH_PRIORITY +%token <kwd> HISTORY_SYM /* MYSQL */ +%token <kwd> HOST_SYM +%token <kwd> HOSTS_SYM +%token <kwd> HOUR_SYM /* SQL-2003-R */ +%token <kwd> ID_SYM /* MYSQL */ +%token <kwd> IDENTIFIED_SYM +%token <kwd> IGNORE_SERVER_IDS_SYM +%token <kwd> IMMEDIATE_SYM /* SQL-2003-R */ +%token <kwd> IMPORT +%token <kwd> INCREMENT_SYM +%token <kwd> INDEXES +%token <kwd> INITIAL_SIZE_SYM +%token <kwd> INSERT_METHOD +%token <kwd> INSTALL_SYM +%token <kwd> INVOKER_SYM +%token <kwd> IO_SYM +%token <kwd> IPC_SYM +%token <kwd> ISOLATION /* SQL-2003-R */ +%token <kwd> ISOPEN_SYM /* Oracle-N */ +%token <kwd> ISSUER_SYM +%token <kwd> INVISIBLE_SYM +%token <kwd> JSON_SYM +%token <kwd> KEY_BLOCK_SIZE +%token <kwd> LANGUAGE_SYM /* SQL-2003-R */ +%token <kwd> LAST_SYM /* SQL-2003-N */ +%token <kwd> LAST_VALUE +%token <kwd> LASTVAL_SYM /* PostgreSQL sequence function */ +%token <kwd> LEAVES +%token <kwd> LESS_SYM +%token <kwd> LEVEL_SYM +%token <kwd> LINESTRING +%token <kwd> LIST_SYM +%token <kwd> LOCAL_SYM /* SQL-2003-R */ +%token <kwd> LOCKS_SYM +%token <kwd> LOGFILE_SYM +%token <kwd> LOGS_SYM +%token <kwd> MASTER_CONNECT_RETRY_SYM +%token <kwd> MASTER_DELAY_SYM +%token <kwd> MASTER_GTID_POS_SYM +%token <kwd> MASTER_HOST_SYM +%token <kwd> MASTER_LOG_FILE_SYM +%token <kwd> MASTER_LOG_POS_SYM +%token <kwd> MASTER_PASSWORD_SYM +%token <kwd> MASTER_PORT_SYM +%token <kwd> MASTER_SERVER_ID_SYM +%token <kwd> MASTER_SSL_CAPATH_SYM +%token <kwd> MASTER_SSL_CA_SYM +%token <kwd> MASTER_SSL_CERT_SYM +%token <kwd> MASTER_SSL_CIPHER_SYM +%token <kwd> MASTER_SSL_CRL_SYM +%token <kwd> MASTER_SSL_CRLPATH_SYM +%token <kwd> MASTER_SSL_KEY_SYM +%token <kwd> MASTER_SSL_SYM +%token <kwd> MASTER_SYM +%token <kwd> MASTER_USER_SYM +%token <kwd> MASTER_USE_GTID_SYM +%token <kwd> MASTER_HEARTBEAT_PERIOD_SYM +%token <kwd> MAX_CONNECTIONS_PER_HOUR +%token <kwd> MAX_QUERIES_PER_HOUR +%token <kwd> MAX_ROWS +%token <kwd> MAX_SIZE_SYM +%token <kwd> MAX_UPDATES_PER_HOUR +%token <kwd> MAX_STATEMENT_TIME_SYM +%token <kwd> MAX_USER_CONNECTIONS_SYM +%token <kwd> MEDIUM_SYM +%token <kwd> MEMORY_SYM +%token <kwd> MERGE_SYM /* SQL-2003-R */ +%token <kwd> MESSAGE_TEXT_SYM /* SQL-2003-N */ +%token <kwd> MICROSECOND_SYM /* MYSQL-FUNC */ +%token <kwd> MIGRATE_SYM +%token <kwd> MINUTE_SYM /* SQL-2003-R */ +%token <kwd> MINVALUE_SYM +%token <kwd> MIN_ROWS +%token <kwd> MODE_SYM +%token <kwd> MODIFY_SYM +%token <kwd> MONTH_SYM /* SQL-2003-R */ +%token <kwd> MULTILINESTRING +%token <kwd> MULTIPOINT +%token <kwd> MULTIPOLYGON +%token <kwd> MUTEX_SYM +%token <kwd> MYSQL_SYM +%token <kwd> MYSQL_ERRNO_SYM +%token <kwd> NAMES_SYM /* SQL-2003-N */ +%token <kwd> NAME_SYM /* SQL-2003-N */ +%token <kwd> NATIONAL_SYM /* SQL-2003-R */ +%token <kwd> NCHAR_SYM /* SQL-2003-R */ +%token <kwd> NEW_SYM /* SQL-2003-R */ +%token <kwd> NEXT_SYM /* SQL-2003-N */ +%token <kwd> NEXTVAL_SYM /* PostgreSQL sequence function */ +%token <kwd> NOCACHE_SYM +%token <kwd> NOCYCLE_SYM +%token <kwd> NODEGROUP_SYM +%token <kwd> NONE_SYM /* SQL-2003-R */ +%token <kwd> NOTFOUND_SYM /* Oracle-R */ +%token <kwd> NO_SYM /* SQL-2003-R */ +%token <kwd> NOMAXVALUE_SYM +%token <kwd> NOMINVALUE_SYM +%token <kwd> NO_WAIT_SYM +%token <kwd> NOWAIT_SYM +%token <kwd> NUMBER_SYM /* SQL-2003-N, Oracle-R, PLSQL-R */ +%token <kwd> NVARCHAR_SYM +%token <kwd> OF_SYM /* SQL-1992-R, Oracle-R */ +%token <kwd> OFFSET_SYM +%token <kwd> OLD_PASSWORD_SYM +%token <kwd> ONE_SYM +%token <kwd> ONLY_SYM /* SQL-2003-R */ +%token <kwd> ONLINE_SYM +%token <kwd> OPEN_SYM /* SQL-2003-R */ +%token <kwd> OPTIONS_SYM +%token <kwd> OPTION /* SQL-2003-N */ +%token <kwd> OWNER_SYM +%token <kwd> PACK_KEYS_SYM +%token <kwd> PAGE_SYM +%token <kwd> PARSER_SYM +%token <kwd> PARTIAL /* SQL-2003-N */ +%token <kwd> PARTITIONS_SYM +%token <kwd> PARTITIONING_SYM +%token <kwd> PASSWORD_SYM +%token <kwd> PERIOD_SYM /* SQL-2011-R */ +%token <kwd> PERSISTENT_SYM +%token <kwd> PHASE_SYM +%token <kwd> PLUGINS_SYM +%token <kwd> PLUGIN_SYM +%token <kwd> POINT_SYM +%token <kwd> POLYGON +%token <kwd> PORT_SYM +%token <kwd> PRECEDES_SYM /* MYSQL */ +%token <kwd> PRECEDING_SYM /* SQL-2011-N */ +%token <kwd> PREPARE_SYM /* SQL-2003-R */ +%token <kwd> PRESERVE_SYM +%token <kwd> PREV_SYM +%token <kwd> PREVIOUS_SYM +%token <kwd> PRIVILEGES /* SQL-2003-N */ +%token <kwd> PROCESS +%token <kwd> PROCESSLIST_SYM +%token <kwd> PROFILE_SYM +%token <kwd> PROFILES_SYM +%token <kwd> PROXY_SYM +%token <kwd> QUARTER_SYM +%token <kwd> QUERY_SYM +%token <kwd> QUICK +%token <kwd> RAW /* Oracle-R */ +%token <kwd> READ_ONLY_SYM +%token <kwd> REBUILD_SYM +%token <kwd> RECOVER_SYM +%token <kwd> REDOFILE_SYM +%token <kwd> REDO_BUFFER_SIZE_SYM +%token <kwd> REDUNDANT_SYM +%token <kwd> RELAY +%token <kwd> RELAYLOG_SYM +%token <kwd> RELAY_LOG_FILE_SYM +%token <kwd> RELAY_LOG_POS_SYM +%token <kwd> RELAY_THREAD +%token <kwd> RELOAD +%token <kwd> REMOVE_SYM +%token <kwd> REORGANIZE_SYM +%token <kwd> REPAIR +%token <kwd> REPEATABLE_SYM /* SQL-2003-N */ +%token <kwd> REPLICATION +%token <kwd> RESET_SYM +%token <kwd> RESTART_SYM +%token <kwd> RESOURCES +%token <kwd> RESTORE_SYM +%token <kwd> RESUME_SYM +%token <kwd> RETURNED_SQLSTATE_SYM /* SQL-2003-N */ +%token <kwd> RETURNS_SYM /* SQL-2003-R */ +%token <kwd> REUSE_SYM /* Oracle-R */ +%token <kwd> REVERSE_SYM +%token <kwd> ROLE_SYM +%token <kwd> ROLLBACK_SYM /* SQL-2003-R */ +%token <kwd> ROLLUP_SYM /* SQL-2003-R */ +%token <kwd> ROUTINE_SYM /* SQL-2003-N */ +%token <kwd> ROWCOUNT_SYM /* Oracle-N */ +%token <kwd> ROW_SYM /* SQL-2003-R */ +%token <kwd> ROW_COUNT_SYM /* SQL-2003-N */ +%token <kwd> ROW_FORMAT_SYM +%token <kwd> RTREE_SYM +%token <kwd> SAVEPOINT_SYM /* SQL-2003-R */ +%token <kwd> SCHEDULE_SYM +%token <kwd> SCHEMA_NAME_SYM /* SQL-2003-N */ +%token <kwd> SECOND_SYM /* SQL-2003-R */ +%token <kwd> SECURITY_SYM /* SQL-2003-N */ +%token <kwd> SEQUENCE_SYM +%token <kwd> SERIALIZABLE_SYM /* SQL-2003-N */ +%token <kwd> SERIAL_SYM +%token <kwd> SESSION_SYM /* SQL-2003-N */ +%token <kwd> SERVER_SYM +%token <kwd> SETVAL_SYM /* PostgreSQL sequence function */ +%token <kwd> SHARE_SYM +%token <kwd> SHUTDOWN +%token <kwd> SIGNED_SYM +%token <kwd> SIMPLE_SYM /* SQL-2003-N */ +%token <kwd> SLAVE +%token <kwd> SLAVES +%token <kwd> SLAVE_POS_SYM +%token <kwd> SLOW +%token <kwd> SNAPSHOT_SYM +%token <kwd> SOCKET_SYM +%token <kwd> SOFT_SYM +%token <kwd> SONAME_SYM +%token <kwd> SOUNDS_SYM +%token <kwd> SOURCE_SYM +%token <kwd> SQL_BUFFER_RESULT +%token <kwd> SQL_CACHE_SYM +%token <kwd> SQL_CALC_FOUND_ROWS +%token <kwd> SQL_NO_CACHE_SYM +%token <kwd> SQL_THREAD +%token <kwd> STARTS_SYM +%token <kwd> START_SYM /* SQL-2003-R */ +%token <kwd> STATEMENT_SYM +%token <kwd> STATUS_SYM +%token <kwd> STOP_SYM +%token <kwd> STORAGE_SYM +%token <kwd> STORED_SYM +%token <kwd> STRING_SYM +%token <kwd> SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ +%token <kwd> SUBDATE_SYM +%token <kwd> SUBJECT_SYM +%token <kwd> SUBPARTITIONS_SYM +%token <kwd> SUBPARTITION_SYM +%token <kwd> SUPER_SYM +%token <kwd> SUSPEND_SYM +%token <kwd> SWAPS_SYM +%token <kwd> SWITCHES_SYM +%token <kwd> SYSTEM /* SQL-2011-R */ +%token <kwd> SYSTEM_TIME_SYM /* SQL-2011-R */ +%token <kwd> TABLES +%token <kwd> TABLESPACE +%token <kwd> TABLE_CHECKSUM_SYM +%token <kwd> TABLE_NAME_SYM /* SQL-2003-N */ +%token <kwd> TEMPORARY /* SQL-2003-N */ +%token <kwd> TEMPTABLE_SYM +%token <kwd> TEXT_SYM +%token <kwd> THAN_SYM +%token <kwd> TIES_SYM /* SQL-2011-N */ +%token <kwd> TIMESTAMP /* SQL-2003-R */ +%token <kwd> TIMESTAMP_ADD +%token <kwd> TIMESTAMP_DIFF +%token <kwd> TIME_SYM /* SQL-2003-R, Oracle-R */ +%token <kwd> TRANSACTION_SYM +%token <kwd> TRANSACTIONAL_SYM +%token <kwd> TRIGGERS_SYM +%token <kwd> TRIM_ORACLE +%token <kwd> TRUNCATE_SYM +%token <kwd> TYPES_SYM +%token <kwd> TYPE_SYM /* SQL-2003-N */ +%token <kwd> UDF_RETURNS_SYM +%token <kwd> UNBOUNDED_SYM /* SQL-2011-N */ +%token <kwd> UNCOMMITTED_SYM /* SQL-2003-N */ +%token <kwd> UNDEFINED_SYM +%token <kwd> UNDOFILE_SYM +%token <kwd> UNDO_BUFFER_SIZE_SYM +%token <kwd> UNICODE_SYM +%token <kwd> UNINSTALL_SYM +%token <kwd> UNKNOWN_SYM /* SQL-2003-R */ +%token <kwd> UNTIL_SYM +%token <kwd> UPGRADE_SYM +%token <kwd> USER_SYM /* SQL-2003-R */ +%token <kwd> USE_FRM +%token <kwd> VALUE_SYM /* SQL-2003-R */ +%token <kwd> VARCHAR2 /* Oracle-R, PLSQL-R */ +%token <kwd> VARIABLES +%token <kwd> VERSIONING_SYM /* SQL-2011-R */ +%token <kwd> VIA_SYM +%token <kwd> VIEW_SYM /* SQL-2003-N */ +%token <kwd> VIRTUAL_SYM +%token <kwd> WAIT_SYM +%token <kwd> WARNINGS +%token <kwd> WEEK_SYM +%token <kwd> WEIGHT_STRING_SYM +%token <kwd> WINDOW_SYM /* SQL-2003-R */ +%token <kwd> WITHIN +%token <kwd> WITHOUT /* SQL-2003-R */ +%token <kwd> WORK_SYM /* SQL-2003-N */ +%token <kwd> WRAPPER_SYM +%token <kwd> WRITE_SYM /* SQL-2003-N */ +%token <kwd> X509_SYM +%token <kwd> XA_SYM +%token <kwd> XML_SYM +%token <kwd> YEAR_SYM /* SQL-2003-R */ + %left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT /* A dummy token to force the priority of table_ref production in a join. */ %left TABLE_REF_PRIORITY %left SET_VAR -%left OR_OR_SYM OR_SYM OR2_SYM +%left OR_SYM OR2_SYM %left XOR %left AND_SYM AND_AND_SYM + +%left PREC_BELOW_NOT +%left NOT_SYM + %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE %left '=' EQUAL_SYM GE '>' LE '<' NE IS LIKE REGEXP IN_SYM %left '|' %left '&' %left SHIFT_LEFT SHIFT_RIGHT -%left '-' '+' +%left '-' '+' ORACLE_CONCAT_SYM %left '*' '/' DIV_SYM MOD_SYM %left '^' -%left NEG '~' -%right NOT_SYM NOT2_SYM -%right BINARY COLLATE_SYM -%left INTERVAL_SYM +%left MYSQL_CONCAT_SYM +%left NEG '~' NOT2_SYM BINARY +%left COLLATE_SYM + +/* + Tokens that can change their meaning from identifier to something else + in certain context. + + - TRANSACTION: identifier, history unit: + SELECT transaction FROM t1; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION @var; + + - TIMESTAMP: identifier, literal, history unit: + SELECT timestamp FROM t1; + SELECT TIMESTAMP '2001-01-01 10:20:30'; + SELECT * FROM t1 FOR SYSTEM_TIME AS OF TIMESTAMP CONCAT(@date,' ',@time); + + - PERIOD: identifier, period for sytem time: + SELECT period FROM t1; + ALTER TABLE DROP PERIOD FOR SYSTEM TIME; + + - SYSTEM: identifier, system versioning: + SELECT system FROM t1; + ALTER TABLE DROP SYSTEM VERSIONIONG; + + Note, we need here only tokens that cause shirt/reduce conflicts + with keyword identifiers. For example: + opt_clause1: %empty | KEYWORD ... ; + clause2: opt_clause1 ident; + KEYWORD can appear both in opt_clause1 and in "ident" through the "keyword" + rule. So the parser reports a conflict on how to interpret KEYWORD: + - as a start of non-empty branch in opt_clause1, or + - as an identifier which follows the empty branch in opt_clause1. + + Example#1: + alter_list_item: + DROP opt_column opt_if_exists_table_element field_ident + | DROP SYSTEM VERSIONING_SYM + SYSTEM can be a keyword in field_ident, or can be a start of + SYSTEM VERSIONING. + + Example#2: + system_time_expr: AS OF_SYM history_point + history_point: opt_history_unit bit_expr + opt_history_unit: | TRANSACTION_SYM + TRANSACTION can be a non-empty history unit, or can be an identifier + in bit_expr. + + In the grammar below we use %prec to explicitely tell Bison to go + through the empty branch in the optional rule only when the lookahead + token does not belong to a small set of selected tokens. + + Tokens NEXT_SYM and PREVIOUS_SYM also change their meaning from + identifiers to sequence operations when followed by VALUE_SYM: + SELECT NEXT VALUE FOR s1, PREVIOUS VALUE FOR s1; + but we don't need to list them here as they do not seem to cause + conflicts (according to bison -v), as both meanings + (as identifier, and as a sequence operation) are parts of the same target + column_default_non_parenthesized_expr, and there are no any optional + clauses between the start of column_default_non_parenthesized_expr + and until NEXT_SYM / PREVIOUS_SYM. +*/ +%left PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE +%left TRANSACTION_SYM TIMESTAMP PERIOD_SYM SYSTEM + + +/* + Tokens that can appear in a token contraction on the second place + and change the meaning of the previous token. + + - TEXT_STRING: changes the meaning of TIMESTAMP/TIME/DATE + from identifier to literal: + SELECT timestamp FROM t1; + SELECT TIMESTAMP'2001-01-01 00:00:00' FROM t1; + + - Parenthesis: changes the meaning of TIMESTAMP/TIME/DATE + from identifiers to CAST-alike functions: + SELECT timestamp FROM t1; + SELECT timestamp(1) FROM t1; + + - VALUE: changes NEXT and PREVIOUS from identifier to sequence operation: + SELECT next, previous FROM t1; + SELECT NEXT VALUE FOR s1, PREVIOUS VALUE FOR s1; + + - VERSIONING: changes SYSTEM from identifier to SYSTEM VERSIONING + SELECT system FROM t1; + ALTER TABLE t1 ADD SYSTEM VERSIONING; +*/ +%left PREC_BELOW_CONTRACTION_TOKEN2 +%left TEXT_STRING '(' VALUE_SYM VERSIONING_SYM %type <lex_str> - IDENT IDENT_QUOTED DECIMAL_NUM FLOAT_NUM NUM LONG_NUM + DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM HEX_STRING LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident_or_text - IDENT_sys TEXT_STRING_sys TEXT_STRING_literal - opt_component key_cache_name - sp_opt_label BIN_NUM TEXT_STRING_filesystem ident_or_empty + TEXT_STRING_sys TEXT_STRING_literal + key_cache_name + sp_opt_label BIN_NUM TEXT_STRING_filesystem opt_constraint constraint opt_ident - ident_directly_assignable opt_package_routine_end_name - sp_decl_ident sp_block_label opt_place opt_db %type <lex_str> - label_ident label_declaration_oracle labels_declaration_oracle +%type <ident_sys> + IDENT_sys + ident + label_ident + sp_decl_ident + ident_or_empty + ident_table_alias + ident_sysvar_name + ident_directly_assignable + %type <lex_string_with_metadata> TEXT_STRING NCHAR_STRING @@ -1065,8 +1183,26 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <lex_str_ptr> opt_table_alias -%type <lex_string_with_pos> - ident ident_with_tok_start +%type <ident_cli> + IDENT + IDENT_QUOTED + IDENT_cli + ident_cli + +%type <kwd> + keyword_data_type + keyword_ident + keyword_label + keyword_sp_block_section + keyword_sp_decl + keyword_sp_head + keyword_sp_var_and_label + keyword_sp_var_not_label + keyword_sysvar_name + keyword_sysvar_type + keyword_table_alias + keyword_verb_clause + keyword_directly_assignable %type <table> table_ident table_ident_nodb references xid @@ -1082,6 +1218,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <const_simple_string> field_length opt_field_length opt_field_length_default_1 + opt_compression_method %type <string> text_string hex_or_bin_String opt_gconcat_separator @@ -1118,7 +1255,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); optional_flush_tables_arguments opt_time_precision kill_type kill_option int_num opt_default_time_precision - case_stmt_body opt_bin_mod + case_stmt_body opt_bin_mod opt_for_system_time_clause opt_if_exists_table_element opt_if_not_exists_table_element opt_recursive opt_format_xid @@ -1142,7 +1279,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <ulong_num> ulong_num real_ulong_num merge_insert_types - ws_nweights + ws_nweights opt_versioning_interval_start ws_level_flag_desc ws_level_flag_reverse ws_level_flags opt_ws_levels ws_level_list ws_level_list_item ws_level_number ws_level_range ws_level_list_or_range bool @@ -1164,11 +1301,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); variable variable_aux bool_pri predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr + primary_expr string_factor_expr mysql_concatenation_expr + select_sublist_qualified_asterisk expr_or_default set_expr_or_default geometry_function signed_literal expr_or_literal opt_escape sp_opt_default - simple_ident_nospvar simple_ident_q simple_ident_q2 + simple_ident_nospvar field_or_var limit_option part_func_expr window_func_expr @@ -1179,6 +1318,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); inverse_distribution_function_def explicit_cursor_attr function_call_keyword + function_call_keyword_timestamp function_call_nonkeyword function_call_generic function_call_conflict kill_expr @@ -1233,7 +1373,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); table_primary_ident table_primary_derived select_derived derived_table_list select_derived_union + derived_simple_table derived_query_specification + derived_table_value_constructor %type <date_time_type> date_time_type; %type <interval> interval @@ -1253,13 +1395,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); opt_field_length_default_sp_param_varchar opt_field_length_default_sp_param_char -%type <symbol> keyword keyword_sp - keyword_directly_assignable - keyword_directly_not_assignable - sp_decl_ident_keyword - keyword_sp_data_type - keyword_sp_not_data_type - %type <lex_user> user grant_user grant_role user_or_role current_role admin_option_for_role user_maybe_role @@ -1277,11 +1412,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <select_lex> subselect get_select_lex get_select_lex_derived + simple_table query_specification query_term_union_not_ready query_term_union_ready query_expression_body select_paren_derived + table_value_constructor %type <boolfunc2creator> comp_op @@ -1352,12 +1489,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keep_gcc_happy key_using_alg part_column_list + period_for_system_time server_def server_options_list server_option definer_opt no_definer definer get_diagnostics parse_vcol_expr vcol_opt_specifier vcol_opt_attribute vcol_opt_attribute_list vcol_attribute opt_serial_attribute opt_serial_attribute_list serial_attribute - explainable_command opt_lock_wait_timeout + explainable_command + opt_lock_wait_timeout + opt_delete_gtid_domain + asrow_attribute set_assign sf_tail_standalone sp_tail_standalone @@ -1440,12 +1581,11 @@ END_OF_INPUT %type <frame_exclusion> opt_window_frame_exclusion; %type <window_frame_bound> window_frame_start window_frame_bound; - %type <NONE> '-' '+' '*' '/' '%' '(' ')' - ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM + ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM BETWEEN_SYM CASE_SYM THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM - ROLE_SYM + MYSQL_CONCAT_SYM ORACLE_CONCAT_SYM %type <with_clause> opt_with_clause with_clause @@ -1453,6 +1593,9 @@ END_OF_INPUT %type <lex_str_list> opt_with_column_list +%type <vers_range_unit> opt_history_unit +%type <vers_history_point> history_point +%type <vers_column_versioning> with_or_without_system %% @@ -1480,8 +1623,8 @@ rule: <-- starts at col 1 query: END_OF_INPUT { - if (!thd->bootstrap && - (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) + if (likely(!thd->bootstrap) && + unlikely(!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) my_yyabort_error((ER_EMPTY_QUERY, MYF(0))); thd->lex->sql_command= SQLCOM_EMPTY_QUERY; @@ -1609,7 +1752,7 @@ prepare: PREPARE_SYM ident FROM prepare_src { LEX *lex= thd->lex; - if (lex->table_or_sp_used()) + if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "PREPARE..FROM")); lex->sql_command= SQLCOM_PREPARE; @@ -1637,7 +1780,7 @@ execute: {} | EXECUTE_SYM IMMEDIATE_SYM prepare_src { - if (Lex->table_or_sp_used()) + if (unlikely(Lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "EXECUTE IMMEDIATE")); Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE; @@ -1651,7 +1794,7 @@ execute_using: | USING { Lex->expr_allows_subselect= false; } execute_var_list { - if (Lex->table_or_sp_used()) + if (unlikely(Lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "EXECUTE..USING")); Lex->expr_allows_subselect= true; @@ -1666,7 +1809,8 @@ execute_var_list: execute_var_ident: expr_or_default { - if (Lex->prepared_stmt_params.push_back($1, thd->mem_root)) + if (unlikely(Lex->prepared_stmt_params.push_back($1, + thd->mem_root))) MYSQL_YYABORT; } ; @@ -1676,7 +1820,7 @@ execute_var_ident: help: HELP_SYM { - if (Lex->sphead) + if (unlikely(Lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HELP")); } ident_or_text @@ -1776,20 +1920,21 @@ master_def: | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal { Lex->mi.heartbeat_period= (float) $3->val_real(); - if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD || - Lex->mi.heartbeat_period < 0.0) + if (unlikely(Lex->mi.heartbeat_period > + SLAVE_MAX_HEARTBEAT_PERIOD) || + unlikely(Lex->mi.heartbeat_period < 0.0)) my_yyabort_error((ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), SLAVE_MAX_HEARTBEAT_PERIOD)); - if (Lex->mi.heartbeat_period > slave_net_timeout) + if (unlikely(Lex->mi.heartbeat_period > slave_net_timeout)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); } - if (Lex->mi.heartbeat_period < 0.001) + if (unlikely(Lex->mi.heartbeat_period < 0.001)) { - if (Lex->mi.heartbeat_period != 0.0) + if (unlikely(Lex->mi.heartbeat_period != 0.0)) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN, @@ -1887,19 +2032,19 @@ master_file_def: } | MASTER_USE_GTID_SYM '=' CURRENT_POS_SYM { - if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) + if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_CURRENT_POS; } | MASTER_USE_GTID_SYM '=' SLAVE_POS_SYM { - if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) + if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_SLAVE_POS; } | MASTER_USE_GTID_SYM '=' NO_SYM { - if (Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED) + if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid")); Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_NO; } @@ -1919,7 +2064,7 @@ connection_name: { Lex->mi.connection_name= $1; #ifdef HAVE_REPLICATION - if (check_master_connection_name(&$1)) + if (unlikely(check_master_connection_name(&$1))) my_yyabort_error((ER_WRONG_ARGUMENTS, MYF(0), "MASTER_CONNECTION_NAME")); #endif } @@ -1932,11 +2077,13 @@ create: { LEX *lex= thd->lex; lex->create_info.init(); - if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4)) + if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, + $1 | $4))) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, + MDL_EXCLUSIVE))) MYSQL_YYABORT; lex->alter_info.reset(); /* @@ -1968,12 +2115,14 @@ create: { LEX *lex= thd->lex; lex->create_info.init(); - if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4)) + if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, + $1 | $4))) MYSQL_YYABORT; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_WRITE, MDL_EXCLUSIVE)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_WRITE, + MDL_EXCLUSIVE))) MYSQL_YYABORT; /* @@ -1985,15 +2134,15 @@ create: lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; lex->name= null_clex_str; lex->create_last_non_select_table= lex->last_table(); - if (!(lex->create_info.seq_create_info= new (thd->mem_root) - sequence_definition())) + if (unlikely(!(lex->create_info.seq_create_info= + new (thd->mem_root) sequence_definition()))) MYSQL_YYABORT; } opt_sequence opt_create_table_options { LEX *lex= thd->lex; - if (lex->create_info.seq_create_info->check_and_adjust(1)) + if (unlikely(lex->create_info.seq_create_info->check_and_adjust(1))) { my_error(ER_SEQUENCE_INVALID_DATA, MYF(0), lex->select_lex.table_list.first->db.str, @@ -2002,7 +2151,8 @@ create: } /* No fields specified, generate them */ - if (prepare_sequence_fields(thd, &lex->alter_info.create_list)) + if (unlikely(prepare_sequence_fields(thd, + &lex->alter_info.create_list))) MYSQL_YYABORT; /* CREATE SEQUENCE always creates a sequence */ @@ -2010,8 +2160,9 @@ create: Lex->create_info.sequence= 1; lex->current_select= &lex->select_lex; - if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && - !lex->create_info.db_type) + if (unlikely((lex->create_info.used_fields & + HA_CREATE_USED_ENGINE) && + !lex->create_info.db_type)) { lex->create_info.use_default_db_type(thd); push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, @@ -2026,9 +2177,9 @@ create: opt_key_algorithm_clause ON table_ident { - if (Lex->add_create_index_prepare($8)) + if (unlikely(Lex->add_create_index_prepare($8))) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, $6, $1 | $4)) + if (unlikely(Lex->add_create_index($2, &$5, $6, $1 | $4))) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout normal_key_options @@ -2036,9 +2187,10 @@ create: | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident ON table_ident { - if (Lex->add_create_index_prepare($7)) + if (unlikely(Lex->add_create_index_prepare($7))) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (unlikely(Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, + $1 | $4))) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout fulltext_key_options @@ -2046,9 +2198,10 @@ create: | create_or_replace spatial INDEX_SYM opt_if_not_exists ident ON table_ident { - if (Lex->add_create_index_prepare($7)) + if (unlikely(Lex->add_create_index_prepare($7))) MYSQL_YYABORT; - if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (unlikely(Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, + $1 | $4))) MYSQL_YYABORT; } '(' key_list ')' opt_lock_wait_timeout spatial_key_options @@ -2061,15 +2214,17 @@ create: opt_create_database_options { LEX *lex=Lex; - if (lex->set_command_with_check(SQLCOM_CREATE_DB, 0, $1 | $3)) + if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_DB, 0, + $1 | $3))) MYSQL_YYABORT; lex->name= $4; } | create_or_replace definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident { - if (Lex->add_create_view(thd, $1 | $5, - DTYPE_ALGORITHM_UNDEFINED, $3, $6)) + if (unlikely(Lex->add_create_view(thd, $1 | $5, + DTYPE_ALGORITHM_UNDEFINED, $3, + $6))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -2077,7 +2232,7 @@ create: | create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM opt_if_not_exists table_ident { - if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7)) + if (unlikely(Lex->add_create_view(thd, $1 | $6, $2, $4, $7))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -2112,13 +2267,15 @@ create: | create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list opt_require_clause opt_resource_options { - if (Lex->set_command_with_check(SQLCOM_CREATE_USER, $1 | $3)) + if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER, + $1 | $3))) MYSQL_YYABORT; } | create_or_replace ROLE_SYM opt_if_not_exists clear_privileges role_list opt_with_admin { - if (Lex->set_command_with_check(SQLCOM_CREATE_ROLE, $1 | $3)) + if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_ROLE, + $1 | $3))) MYSQL_YYABORT; } | CREATE LOGFILE_SYM GROUP_SYM logfile_group_info @@ -2138,17 +2295,18 @@ create: remember_name { sp_package *pkg; - if (!(pkg= Lex->create_package_start(thd, - SQLCOM_CREATE_PACKAGE, - &sp_handler_package_spec, - $5, $1 | $4))) + if (unlikely(!(pkg= Lex-> + create_package_start(thd, + SQLCOM_CREATE_PACKAGE, + &sp_handler_package_spec, + $5, $1 | $4)))) MYSQL_YYABORT; pkg->set_chistics(Lex->sp_chistics); } opt_package_specification_element_list END remember_end_opt opt_sp_name { - if (Lex->create_package_finalize(thd, $5, $13, $8, $12)) + if (unlikely(Lex->create_package_finalize(thd, $5, $13, $8, $12))) MYSQL_YYABORT; } | create_or_replace definer_opt PACKAGE_SYM BODY_SYM @@ -2157,28 +2315,29 @@ create: remember_name { sp_package *pkg; - if (!(pkg= Lex->create_package_start(thd, - SQLCOM_CREATE_PACKAGE_BODY, - &sp_handler_package_body, - $6, $1 | $5))) + if (unlikely(!(pkg= Lex-> + create_package_start(thd, + SQLCOM_CREATE_PACKAGE_BODY, + &sp_handler_package_body, + $6, $1 | $5)))) MYSQL_YYABORT; pkg->set_chistics(Lex->sp_chistics); Lex->sp_block_init(thd); } package_implementation_declare_section { - if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } package_implementation_executable_section { $11.hndlrs+= $13.hndlrs; - if (Lex->sp_block_finalize(thd, $11)) + if (unlikely(Lex->sp_block_finalize(thd, $11))) MYSQL_YYABORT; } remember_end_opt opt_sp_name { - if (Lex->create_package_finalize(thd, $6, $16, $9, $15)) + if (unlikely(Lex->create_package_finalize(thd, $6, $16, $9, $15))) MYSQL_YYABORT; } ; @@ -2186,7 +2345,7 @@ create: package_implementation_executable_section: END { - if (Lex->sp_block_with_exceptions_add_empty(thd)) + if (unlikely(Lex->sp_block_with_exceptions_add_empty(thd))) MYSQL_YYABORT; $$.init(0); } @@ -2221,7 +2380,8 @@ package_implementation_declare_section_list2: package_routine_lex: { - if (!($$= new (thd->mem_root) sp_lex_local(thd, thd->lex))) + if (unlikely(!($$= new (thd->mem_root) + sp_lex_local(thd, thd->lex)))) MYSQL_YYABORT; thd->m_parser_state->m_yacc.reset_before_substatement(); } @@ -2234,11 +2394,11 @@ package_specification_function: DBUG_ASSERT($1->sphead->get_package()); $2->sql_command= SQLCOM_CREATE_FUNCTION; sp_name *spname= $1->make_sp_name_package_routine(thd, &$3); - if (!spname) + if (unlikely(!spname)) MYSQL_YYABORT; thd->lex= $2; - if (!$2->make_sp_head_no_recursive(thd, spname, - &sp_handler_package_function)) + if (unlikely(!$2->make_sp_head_no_recursive(thd, spname, + &sp_handler_package_function))) MYSQL_YYABORT; $1->sphead->get_package()->m_current_routine= $2; (void) is_native_function_with_warn(thd, &$3); @@ -2260,11 +2420,11 @@ package_specification_procedure: DBUG_ASSERT($1->sphead->get_package()); $2->sql_command= SQLCOM_CREATE_PROCEDURE; sp_name *spname= $1->make_sp_name_package_routine(thd, &$3); - if (!spname) + if (unlikely(!spname)) MYSQL_YYABORT; thd->lex= $2; - if (!$2->make_sp_head_no_recursive(thd, spname, - &sp_handler_package_procedure)) + if (unlikely(!$2->make_sp_head_no_recursive(thd, spname, + &sp_handler_package_procedure))) MYSQL_YYABORT; $1->sphead->get_package()->m_current_routine= $2; } @@ -2285,7 +2445,7 @@ package_implementation_routine_definition: package_implementation_function_body ';' { sp_package *pkg= Lex->get_sp_package(); - if (pkg->add_routine_implementation($2)) + if (unlikely(pkg->add_routine_implementation($2))) MYSQL_YYABORT; pkg->m_current_routine= NULL; $$.init(); @@ -2294,7 +2454,7 @@ package_implementation_routine_definition: package_implementation_procedure_body ';' { sp_package *pkg= Lex->get_sp_package(); - if (pkg->add_routine_implementation($2)) + if (unlikely(pkg->add_routine_implementation($2))) MYSQL_YYABORT; pkg->m_current_routine= NULL; $$.init(); @@ -2314,13 +2474,13 @@ package_implementation_function_body: } sp_body opt_package_routine_end_name { - if (Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR) + if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)) { my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0))); } Lex->sphead->set_chistics_agg_type(NOT_AGGREGATE); - if (thd->lex->sp_body_finalize_function(thd) || - thd->lex->sphead->check_package_routine_end_name($5)) + if (unlikely(thd->lex->sp_body_finalize_function(thd) || + thd->lex->sphead->check_package_routine_end_name($5))) MYSQL_YYABORT; thd->lex= $2; } @@ -2337,8 +2497,8 @@ package_implementation_procedure_body: } sp_body opt_package_routine_end_name { - if (thd->lex->sp_body_finalize_procedure(thd) || - thd->lex->sphead->check_package_routine_end_name($5)) + if (unlikely(thd->lex->sp_body_finalize_procedure(thd) || + thd->lex->sphead->check_package_routine_end_name($5))) MYSQL_YYABORT; thd->lex= $2; } @@ -2363,14 +2523,14 @@ package_specification_element: FUNCTION_SYM package_specification_function ';' { sp_package *pkg= Lex->get_sp_package(); - if (pkg->add_routine_declaration($2)) + if (unlikely(pkg->add_routine_declaration($2))) MYSQL_YYABORT; pkg->m_current_routine= NULL; } | PROCEDURE_SYM package_specification_procedure ';' { sp_package *pkg= Lex->get_sp_package(); - if (pkg->add_routine_declaration($2)) + if (unlikely(pkg->add_routine_declaration($2))) MYSQL_YYABORT; pkg->m_current_routine= NULL; } @@ -2399,105 +2559,105 @@ sequence_def: } | NO_SYM MINVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; } | NOMINVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; } | MAXVALUE_SYM opt_equal longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_max_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_max_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE")); Lex->create_info.seq_create_info->max_value= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; } | NO_SYM MAXVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; } | NOMAXVALUE_SYM { - if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value) + if (unlikely(Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; } | START_SYM opt_with longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_start) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_start)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "START")); Lex->create_info.seq_create_info->start= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_start; } | INCREMENT_SYM opt_by longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_increment) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_increment)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "INCREMENT")); Lex->create_info.seq_create_info->increment= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment; } | CACHE_SYM opt_equal longlong_num { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cache) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cache)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE")); Lex->create_info.seq_create_info->cache= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache; } | NOCACHE_SYM { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cache) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cache)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE")); Lex->create_info.seq_create_info->cache= 0; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache; } | CYCLE_SYM { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cycle) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cycle)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE")); Lex->create_info.seq_create_info->cycle= 1; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle; } | NOCYCLE_SYM { - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_cycle) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_cycle)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE")); Lex->create_info.seq_create_info->cycle= 0; Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle; } | RESTART_SYM { - if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE) + if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE)) { thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); YYABORT; } - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_restart) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_restart)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART")); Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart; } | RESTART_SYM opt_with longlong_num { - if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE) + if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE)) { thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); YYABORT; } - if (Lex->create_info.seq_create_info->used_fields & - seq_field_used_restart) + if (unlikely(Lex->create_info.seq_create_info->used_fields & + seq_field_used_restart)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART")); Lex->create_info.seq_create_info->restart= $3; Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value; @@ -2507,7 +2667,7 @@ sequence_def: server_def: SERVER_SYM opt_if_not_exists ident_or_text { - if (Lex->add_create_options_with_check($2)) + if (unlikely(Lex->add_create_options_with_check($2))) MYSQL_YYABORT; Lex->server_options.reset($3); } @@ -2566,9 +2726,10 @@ event_tail: LEX *lex=Lex; lex->stmt_definition_begin= $1; - if (lex->add_create_options_with_check($2)) + if (unlikely(lex->add_create_options_with_check($2))) MYSQL_YYABORT; - if (!(lex->event_parse_data= Event_parse_data::new_instance(thd))) + if (unlikely(!(lex->event_parse_data= + Event_parse_data::new_instance(thd)))) MYSQL_YYABORT; lex->event_parse_data->identifier= $3; lex->event_parse_data->on_completion= @@ -2631,7 +2792,7 @@ ev_starts: /* empty */ { Item *item= new (thd->mem_root) Item_func_now_local(thd, 0); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; Lex->event_parse_data->item_starts= item; } @@ -2695,11 +2856,12 @@ ev_sql_stmt: (the nested ALTER EVENT can have anything but DO clause) - CREATE PROCEDURE ... BEGIN DROP EVENT ... END| */ - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_EVENT_RECURSION_FORBIDDEN, MYF(0))); - if (!lex->make_sp_head(thd, lex->event_parse_data->identifier, - &sp_handler_procedure)) + if (unlikely(!lex->make_sp_head(thd, + lex->event_parse_data->identifier, + &sp_handler_procedure))) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_ptr()); @@ -2734,12 +2896,12 @@ clear_privileges: sp_name: ident '.' ident { - if (!($$= Lex->make_sp_name(thd, &$1, &$3))) + if (unlikely(!($$= Lex->make_sp_name(thd, &$1, &$3)))) MYSQL_YYABORT; } | ident { - if (!($$= Lex->make_sp_name(thd, &$1))) + if (unlikely(!($$= Lex->make_sp_name(thd, &$1)))) MYSQL_YYABORT; } ; @@ -2813,7 +2975,7 @@ sp_suid: call: CALL_SYM sp_name { - if (Lex->call_statement_start(thd, $2)) + if (unlikely(Lex->call_statement_start(thd, $2))) MYSQL_YYABORT; } opt_sp_cparam_list {} @@ -2855,7 +3017,7 @@ sp_fdparams: sp_param_name: ident { - if (!($$= Lex->sp_param_init(&$1))) + if (unlikely(!($$= Lex->sp_param_init(&$1)))) MYSQL_YYABORT; } ; @@ -2863,32 +3025,32 @@ sp_param_name: sp_param_name_and_type: sp_param_name sp_param_type_with_opt_collate { - if (Lex->sp_param_fill_definition($$= $1)) + if (unlikely(Lex->sp_param_fill_definition($$= $1))) MYSQL_YYABORT; } | sp_param_name sp_decl_ident '.' ident '%' TYPE_SYM { - if (Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4)) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4))) MYSQL_YYABORT; } | sp_param_name sp_decl_ident '.' ident '.' ident '%' TYPE_SYM { - if (Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6)) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6))) MYSQL_YYABORT; } | sp_param_name sp_decl_ident '%' ROWTYPE_SYM { - if (Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2)) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2))) MYSQL_YYABORT; } | sp_param_name sp_decl_ident '.' ident '%' ROWTYPE_SYM { - if (Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2, $4)) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2, $4))) MYSQL_YYABORT; } | sp_param_name ROW_SYM row_type_body { - if (Lex->sphead->spvar_fill_row(thd, $$= $1, $3)) + if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3))) MYSQL_YYABORT; } ; @@ -2908,37 +3070,37 @@ sp_pdparam: sp_param_name sp_opt_inout sp_param_type_with_opt_collate { $1->mode= $2; - if (Lex->sp_param_fill_definition($1)) + if (unlikely(Lex->sp_param_fill_definition($1))) MYSQL_YYABORT; } | sp_param_name sp_opt_inout sp_decl_ident '.' ident '%' TYPE_SYM { $1->mode= $2; - if (Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5)) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5))) MYSQL_YYABORT; } | sp_param_name sp_opt_inout sp_decl_ident '.' ident '.' ident '%' TYPE_SYM { $1->mode= $2; - if (Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5, $7)) + if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $1, $3, $5, $7))) MYSQL_YYABORT; } | sp_param_name sp_opt_inout sp_decl_ident '%' ROWTYPE_SYM { $1->mode= $2; - if (Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3)) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3))) MYSQL_YYABORT; } | sp_param_name sp_opt_inout sp_decl_ident '.' ident '%' ROWTYPE_SYM { $1->mode= $2; - if (Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3, $5)) + if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3, $5))) MYSQL_YYABORT; } | sp_param_name sp_opt_inout ROW_SYM row_type_body { $1->mode= $2; - if (Lex->sphead->spvar_fill_row(thd, $1, $4)) + if (unlikely(Lex->sphead->spvar_fill_row(thd, $1, $4))) MYSQL_YYABORT; } ; @@ -3009,7 +3171,7 @@ sp_proc_stmts1_implicit_block: } sp_proc_stmts1 { - if (Lex->sp_block_finalize(thd)) + if (unlikely(Lex->sp_block_finalize(thd))) MYSQL_YYABORT; } ; @@ -3025,7 +3187,7 @@ opt_sp_decl_body_list: sp_decl_body_list: sp_decl_non_handler_list { - if (Lex->sphead->sp_add_instr_cpush_for_cursors(thd, Lex->spcont)) + if (unlikely(Lex->sphead->sp_add_instr_cpush_for_cursors(thd, Lex->spcont))) MYSQL_YYABORT; } opt_sp_decl_handler_list @@ -3059,18 +3221,20 @@ opt_sp_decl_handler_list: optionally_qualified_column_ident: sp_decl_ident { - if (!($$= new (thd->mem_root) Qualified_column_ident(&$1))) + if (unlikely(!($$= new (thd->mem_root) + Qualified_column_ident(&$1)))) MYSQL_YYABORT; } | sp_decl_ident '.' ident { - if (!($$= new (thd->mem_root) Qualified_column_ident(&$1, &$3))) + if (unlikely(!($$= new (thd->mem_root) + Qualified_column_ident(&$1, &$3)))) MYSQL_YYABORT; } | sp_decl_ident '.' ident '.' ident { - if (!($$= new (thd->mem_root) Qualified_column_ident(thd, - &$1, &$3, &$5))) + if (unlikely(!($$= new (thd->mem_root) + Qualified_column_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } ; @@ -3078,10 +3242,10 @@ optionally_qualified_column_ident: row_field_name: ident_directly_assignable { - if (check_string_char_length(&$1, 0, NAME_CHAR_LEN, - system_charset_info, 1)) + if (unlikely(check_string_char_length(&$1, 0, NAME_CHAR_LEN, + system_charset_info, 1))) my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str)); - if (!($$= new (thd->mem_root) Spvar_definition())) + if (unlikely(!($$= new (thd->mem_root) Spvar_definition()))) MYSQL_YYABORT; Lex->init_last_field($$, &$1, thd->variables.collation_database); } @@ -3094,17 +3258,18 @@ row_field_definition: row_field_definition_list: row_field_definition { - if (!($$= new (thd->mem_root) Row_definition_list())) + if (unlikely(!($$= new (thd->mem_root) Row_definition_list())) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); } | row_field_definition_list ',' row_field_definition { uint unused; - if ($1->find_row_field_by_name(&$3->field_name, &unused)) + if (unlikely($1->find_row_field_by_name(&$3->field_name, &unused))) my_yyabort_error((ER_DUP_FIELDNAME, MYF(0), $3->field_name.str)); $$= $1; - $$->push_back($3, thd->mem_root); + if (unlikely($$->push_back($3, thd->mem_root))) + MYSQL_YYABORT; } ; @@ -3124,8 +3289,9 @@ sp_decl_vars: type_with_opt_collate sp_opt_default { - if (Lex->sp_variable_declarations_finalize(thd, $1, - &Lex->last_field[0], $3)) + if (unlikely(Lex->sp_variable_declarations_finalize(thd, $1, + &Lex->last_field[0], + $3))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3133,7 +3299,7 @@ sp_decl_vars: optionally_qualified_column_ident '%' TYPE_SYM sp_opt_default { - if (Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $2, $5)) + if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $2, $5))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3141,7 +3307,7 @@ sp_decl_vars: optionally_qualified_column_ident '%' ROWTYPE_SYM sp_opt_default { - if (Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $2, $5)) + if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $2, $5))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3149,7 +3315,7 @@ sp_decl_vars: ROW_SYM row_type_body sp_opt_default { - if (Lex->sp_variable_declarations_row_finalize(thd, $1, $3, $4)) + if (unlikely(Lex->sp_variable_declarations_row_finalize(thd, $1, $3, $4))) MYSQL_YYABORT; $$.init_using_vars($1); } @@ -3159,7 +3325,7 @@ sp_decl_non_handler: sp_decl_vars | ident_directly_assignable CONDITION_SYM FOR_SYM sp_cond { - if (Lex->spcont->declare_condition(thd, &$1, $4)) + if (unlikely(Lex->spcont->declare_condition(thd, &$1, $4))) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -3168,8 +3334,8 @@ sp_decl_non_handler: { sp_condition_value *spcond= new (thd->mem_root) sp_condition_value_user_defined(); - if (!spcond || - Lex->spcont->declare_condition(thd, &$1, spcond)) + if (unlikely(!spcond) || + unlikely(Lex->spcont->declare_condition(thd, &$1, spcond))) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -3182,9 +3348,9 @@ sp_decl_non_handler: IS sp_cursor_stmt { sp_pcontext *param_ctx= Lex->spcont; - if (Lex->sp_block_finalize(thd)) + if (unlikely(Lex->sp_block_finalize(thd))) MYSQL_YYABORT; - if (Lex->sp_declare_cursor(thd, &$2, $6, param_ctx, false)) + if (unlikely(Lex->sp_declare_cursor(thd, &$2, $6, param_ctx, false))) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; @@ -3194,12 +3360,12 @@ sp_decl_non_handler: sp_decl_handler: sp_handler_type HANDLER_SYM FOR_SYM { - if (Lex->sp_handler_declaration_init(thd, $1)) + if (unlikely(Lex->sp_handler_declaration_init(thd, $1))) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt { - if (Lex->sp_handler_declaration_finalize(thd, $1)) + if (unlikely(Lex->sp_handler_declaration_finalize(thd, $1))) MYSQL_YYABORT; $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= 1; @@ -3215,7 +3381,8 @@ opt_parenthesized_cursor_formal_parameters: sp_cursor_stmt_lex: { DBUG_ASSERT(thd->lex->sphead); - if (!($$= new (thd->mem_root) sp_lex_cursor(thd, thd->lex))) + if (unlikely(!($$= new (thd->mem_root) + sp_lex_cursor(thd, thd->lex)))) MYSQL_YYABORT; } ; @@ -3229,8 +3396,8 @@ sp_cursor_stmt: select { DBUG_ASSERT(Lex == $1); - if ($1->stmt_finalize(thd) || - $1->sphead->restore_lex(thd)) + if (unlikely($1->stmt_finalize(thd)) || + unlikely($1->sphead->restore_lex(thd))) MYSQL_YYABORT; $$= $1; } @@ -3256,7 +3423,7 @@ sp_hcond_element: sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont->parent_context(); - if (ctx->check_duplicate_handler($1)) + if (unlikely(ctx->check_duplicate_handler($1))) my_yyabort_error((ER_SP_DUP_HANDLER, MYF(0))); sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); @@ -3267,10 +3434,10 @@ sp_hcond_element: sp_cond: ulong_num { /* mysql errno */ - if ($1 == 0) + if (unlikely($1 == 0)) my_yyabort_error((ER_WRONG_VALUE, MYF(0), "CONDITION", "0")); $$= new (thd->mem_root) sp_condition_value($1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | sqlstate @@ -3287,10 +3454,11 @@ sqlstate: allowed to SIGNAL, or declare a handler for the completion condition. */ - if (!is_sqlstate_valid(&$3) || is_sqlstate_completion($3.str)) + if (unlikely(!is_sqlstate_valid(&$3) || + is_sqlstate_completion($3.str))) my_yyabort_error((ER_SP_BAD_SQLSTATE, MYF(0), $3.str)); $$= new (thd->mem_root) sp_condition_value($3.str); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3308,25 +3476,25 @@ sp_hcond: | ident /* CONDITION name */ { $$= Lex->spcont->find_declared_or_predefined_condition(&$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); } | SQLWARNING_SYM /* SQLSTATEs 01??? */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::WARNING); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | not FOUND_SYM /* SQLSTATEs 02??? */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::NOT_FOUND); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | OTHERS_SYM /* All other SQLSTATEs */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::EXCEPTION); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3335,12 +3503,12 @@ sp_hcond: raise_stmt: RAISE_SYM opt_set_signal_information { - if (Lex->add_resignal_statement(thd, NULL)) + if (unlikely(Lex->add_resignal_statement(thd, NULL))) MYSQL_YYABORT; } | RAISE_SYM signal_value opt_set_signal_information { - if (Lex->add_signal_statement(thd, $2)) + if (unlikely(Lex->add_signal_statement(thd, $2))) MYSQL_YYABORT; } ; @@ -3348,7 +3516,7 @@ raise_stmt: signal_stmt: SIGNAL_SYM signal_value opt_set_signal_information { - if (Lex->add_signal_statement(thd, $2)) + if (unlikely(Lex->add_signal_statement(thd, $2))) MYSQL_YYABORT; } ; @@ -3360,12 +3528,12 @@ signal_value: sp_condition_value *cond; /* SIGNAL foo cannot be used outside of stored programs */ - if (lex->spcont == NULL) + if (unlikely(lex->spcont == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); cond= lex->spcont->find_declared_or_predefined_condition(&$1); - if (cond == NULL) + if (unlikely(cond == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); - if (!cond->has_sql_state()) + if (unlikely(!cond->has_sql_state())) my_yyabort_error((ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0))); $$= cond; } @@ -3403,7 +3571,7 @@ signal_information_item_list: Set_signal_information *info; info= &thd->m_parser_state->m_yacc.m_set_signal_info; int index= (int) $3; - if (info->m_item[index] != NULL) + if (unlikely(info->m_item[index] != NULL)) my_yyabort_error((ER_DUP_SIGNAL_SET, MYF(0), Diag_condition_item_names[index].str)); info->m_item[index]= $5; @@ -3421,7 +3589,7 @@ signal_allowed_expr: if ($1->type() == Item::FUNC_ITEM) { Item_func *item= (Item_func*) $1; - if (item->functype() == Item_func::SUSERVAR_FUNC) + if (unlikely(item->functype() == Item_func::SUSERVAR_FUNC)) { /* Don't allow the following syntax: @@ -3469,7 +3637,7 @@ signal_condition_information_item_name: resignal_stmt: RESIGNAL_SYM opt_signal_value opt_set_signal_information { - if (Lex->add_resignal_statement(thd, $2)) + if (unlikely(Lex->add_resignal_statement(thd, $2))) MYSQL_YYABORT; } ; @@ -3484,7 +3652,7 @@ get_diagnostics: Lex->sql_command= SQLCOM_GET_DIAGNOSTICS; Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_get_diagnostics(info); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -3500,13 +3668,13 @@ diagnostics_information: statement_information { $$= new (thd->mem_root) Statement_information($1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CONDITION_SYM condition_number condition_information { $$= new (thd->mem_root) Condition_information($2, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3515,12 +3683,13 @@ statement_information: statement_information_item { $$= new (thd->mem_root) List<Statement_information_item>; - if ($$ == NULL || $$->push_back($1, thd->mem_root)) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; } | statement_information ',' statement_information_item { - if ($1->push_back($3, thd->mem_root)) + if (unlikely($1->push_back($3, thd->mem_root))) MYSQL_YYABORT; $$= $1; } @@ -3530,24 +3699,20 @@ statement_information_item: simple_target_specification '=' statement_information_item_name { $$= new (thd->mem_root) Statement_information_item($3, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } simple_target_specification: - ident + ident_cli { - Lex_input_stream *lip= &thd->m_parser_state->m_lip; - $$= thd->lex->create_item_for_sp_var(&$1, NULL, - lip->get_tok_start(), - lip->get_ptr()); - if ($$ == NULL) + if (unlikely(!($$= thd->lex->create_item_for_sp_var(&$1, NULL)))) MYSQL_YYABORT; } | '@' ident_or_text { $$= new (thd->mem_root) Item_func_get_user_var(thd, &$2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -3572,12 +3737,13 @@ condition_information: condition_information_item { $$= new (thd->mem_root) List<Condition_information_item>; - if ($$ == NULL || $$->push_back($1, thd->mem_root)) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; } | condition_information ',' condition_information_item { - if ($1->push_back($3, thd->mem_root)) + if (unlikely($1->push_back($3, thd->mem_root))) MYSQL_YYABORT; $$= $1; } @@ -3587,7 +3753,7 @@ condition_information_item: simple_target_specification '=' condition_information_item_name { $$= new (thd->mem_root) Condition_information_item($3, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } @@ -3622,21 +3788,13 @@ condition_information_item_name: sp_decl_ident: IDENT_sys - | sp_decl_ident_keyword + | keyword_sp_decl { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_ident_cli(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; } ; -sp_decl_ident_keyword: - keyword_directly_assignable - | keyword_sp_not_data_type - ; - - sp_decl_idents: sp_decl_ident { @@ -3645,7 +3803,7 @@ sp_decl_idents: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_variable(&$1, TRUE)) + if (unlikely(spc->find_variable(&$1, TRUE))) my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $1.str)); spc->add_variable(thd, &$1); $$= 1; @@ -3657,7 +3815,7 @@ sp_decl_idents: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_variable(&$3, TRUE)) + if (unlikely(spc->find_variable(&$3, TRUE))) my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $3.str)); spc->add_variable(thd, &$3); $$= $1 + 1; @@ -3705,7 +3863,7 @@ sp_proc_stmt_compound_ok: sp_proc_stmt_if: IF_SYM { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sphead->new_cont_backpatch(NULL); } @@ -3718,13 +3876,13 @@ sp_statement: | ident_directly_assignable { // Direct procedure call (without the CALL keyword) - if (Lex->call_statement_start(thd, &$1)) + if (unlikely(Lex->call_statement_start(thd, &$1))) MYSQL_YYABORT; } opt_sp_cparam_list | ident_directly_assignable '.' ident { - if (Lex->call_statement_start(thd, &$1, &$3)) + if (unlikely(Lex->call_statement_start(thd, &$1, &$3))) MYSQL_YYABORT; } opt_sp_cparam_list @@ -3746,7 +3904,7 @@ sp_proc_stmt_statement: sp->m_flags|= sp_get_flags_for_command(lex); /* "USE db" doesn't work in a procedure */ - if (lex->sql_command == SQLCOM_CHANGE_DB) + if (unlikely(lex->sql_command == SQLCOM_CHANGE_DB)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "USE")); /* Don't add an instruction for SET statements, since all @@ -3759,7 +3917,7 @@ sp_proc_stmt_statement: { sp_instr_stmt *i=new (thd->mem_root) sp_instr_stmt(sp->instructions(), lex->spcont, lex); - if (i == NULL) + if (unlikely(i == NULL)) MYSQL_YYABORT; /* @@ -3771,13 +3929,13 @@ sp_proc_stmt_statement: i->m_query.length= lip->get_ptr() - sp->m_tmp_query; else i->m_query.length= lip->get_tok_start() - sp->m_tmp_query;; - if (!(i->m_query.str= strmake_root(thd->mem_root, - sp->m_tmp_query, - i->m_query.length)) || - sp->add_instr(i)) + if (unlikely(!(i->m_query.str= strmake_root(thd->mem_root, + sp->m_tmp_query, + i->m_query.length))) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } - if (sp->restore_lex(thd)) + if (unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -3789,16 +3947,17 @@ sp_proc_stmt_return: { LEX *lex= Lex; sp_head *sp= lex->sphead; - if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, - $3, lex) || - sp->restore_lex(thd)) + if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, lex->spcont, + $3, lex)) || + unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } | RETURN_SYM { LEX *lex= Lex; sp_head *sp= lex->sphead; - if (sp->m_handler->add_instr_preturn(thd, sp, lex->spcont)) + if (unlikely(sp->m_handler->add_instr_preturn(thd, sp, + lex->spcont))) MYSQL_YYABORT; } ; @@ -3810,24 +3969,24 @@ reset_lex_expr: sp_proc_stmt_exit: EXIT_SYM { - if (Lex->sp_exit_statement(thd, NULL)) + if (unlikely(Lex->sp_exit_statement(thd, NULL))) MYSQL_YYABORT; } | EXIT_SYM label_ident { - if (Lex->sp_exit_statement(thd, &$2, NULL)) + if (unlikely(Lex->sp_exit_statement(thd, &$2, NULL))) MYSQL_YYABORT; } | EXIT_SYM WHEN_SYM reset_lex_expr { - if (Lex->sp_exit_statement(thd, $3) || - Lex->sphead->restore_lex(thd)) + if (unlikely(Lex->sp_exit_statement(thd, $3)) || + unlikely(Lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } | EXIT_SYM label_ident WHEN_SYM reset_lex_expr { - if (Lex->sp_exit_statement(thd, &$2, $4) || - Lex->sphead->restore_lex(thd)) + if (unlikely(Lex->sp_exit_statement(thd, &$2, $4)) || + unlikely(Lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -3835,24 +3994,24 @@ sp_proc_stmt_exit: sp_proc_stmt_continue: CONTINUE_SYM { - if (Lex->sp_continue_statement(thd, NULL)) + if (unlikely(Lex->sp_continue_statement(thd, NULL))) MYSQL_YYABORT; } | CONTINUE_SYM label_ident { - if (Lex->sp_continue_statement(thd, &$2, NULL)) + if (unlikely(Lex->sp_continue_statement(thd, &$2, NULL))) MYSQL_YYABORT; } | CONTINUE_SYM WHEN_SYM reset_lex_expr { - if (Lex->sp_continue_statement(thd, $3) || - Lex->sphead->restore_lex(thd)) + if (unlikely(Lex->sp_continue_statement(thd, $3)) || + unlikely(Lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } | CONTINUE_SYM label_ident WHEN_SYM reset_lex_expr { - if (Lex->sp_continue_statement(thd, &$2, $4) || - Lex->sphead->restore_lex(thd)) + if (unlikely(Lex->sp_continue_statement(thd, &$2, $4)) || + unlikely(Lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -3861,7 +4020,7 @@ sp_proc_stmt_continue: sp_proc_stmt_leave: LEAVE_SYM label_ident { - if (Lex->sp_leave_statement(thd, &$2)) + if (unlikely(Lex->sp_leave_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -3869,7 +4028,7 @@ sp_proc_stmt_leave: sp_proc_stmt_iterate: ITERATE_SYM label_ident { - if (Lex->sp_iterate_statement(thd, &$2)) + if (unlikely(Lex->sp_iterate_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -3877,7 +4036,7 @@ sp_proc_stmt_iterate: sp_proc_stmt_goto: GOTO_SYM label_ident { - if (Lex->sp_goto_statement(thd, &$2)) + if (unlikely(Lex->sp_goto_statement(thd, &$2))) MYSQL_YYABORT; } ; @@ -3892,7 +4051,8 @@ remember_lex: assignment_source_lex: { DBUG_ASSERT(Lex->sphead); - if (!($$= new (thd->mem_root) sp_assignment_lex(thd, thd->lex))) + if (unlikely(!($$= new (thd->mem_root) + sp_assignment_lex(thd, thd->lex)))) MYSQL_YYABORT; } ; @@ -3910,7 +4070,7 @@ assignment_source_expr: $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, thd->free_list); thd->free_list= NULL; - if ($$->sphead->restore_lex(thd)) + if (unlikely($$->sphead->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -3926,7 +4086,7 @@ for_loop_bound_expr: $$= $1; $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, NULL); - if ($$->sphead->restore_lex(thd)) + if (unlikely($$->sphead->restore_lex(thd))) MYSQL_YYABORT; } ; @@ -3934,7 +4094,7 @@ for_loop_bound_expr: cursor_actual_parameters: assignment_source_expr { - if (!($$= new (thd->mem_root) List<sp_assignment_lex>)) + if (unlikely(!($$= new (thd->mem_root) List<sp_assignment_lex>))) MYSQL_YYABORT; $$->push_back($1, thd->mem_root); } @@ -3953,7 +4113,7 @@ opt_parenthesized_cursor_actual_parameters: sp_proc_stmt_open: OPEN_SYM ident opt_parenthesized_cursor_actual_parameters { - if (Lex->sp_open_cursor(thd, &$2, $3)) + if (unlikely(Lex->sp_open_cursor(thd, &$2, $3))) MYSQL_YYABORT; } ; @@ -3961,17 +4121,17 @@ sp_proc_stmt_open: sp_proc_stmt_fetch_head: FETCH_SYM ident INTO { - if (Lex->sp_add_cfetch(thd, &$2)) + if (unlikely(Lex->sp_add_cfetch(thd, &$2))) MYSQL_YYABORT; } | FETCH_SYM FROM ident INTO { - if (Lex->sp_add_cfetch(thd, &$3)) + if (unlikely(Lex->sp_add_cfetch(thd, &$3))) MYSQL_YYABORT; } | FETCH_SYM NEXT_SYM FROM ident INTO { - if (Lex->sp_add_cfetch(thd, &$4)) + if (unlikely(Lex->sp_add_cfetch(thd, &$4))) MYSQL_YYABORT; } ; @@ -3988,12 +4148,12 @@ sp_proc_stmt_close: uint offset; sp_instr_cclose *i; - if (! lex->spcont->find_cursor(&$2, &offset, false)) + if (unlikely(!lex->spcont->find_cursor(&$2, &offset, false))) my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $2.str)); i= new (thd->mem_root) sp_instr_cclose(sp->instructions(), lex->spcont, offset); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } ; @@ -4006,7 +4166,7 @@ sp_fetch_list: sp_pcontext *spc= lex->spcont; sp_variable *spv; - if (!spc || !(spv = spc->find_variable(&$1, false))) + if (unlikely(!spc || !(spv = spc->find_variable(&$1, false)))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str)); /* An SP local variable */ @@ -4020,7 +4180,7 @@ sp_fetch_list: sp_pcontext *spc= lex->spcont; sp_variable *spv; - if (!spc || !(spv = spc->find_variable(&$3, false))) + if (unlikely(!spc || !(spv = spc->find_variable(&$3, false)))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $3.str)); /* An SP local variable */ @@ -4039,12 +4199,12 @@ sp_if: uint ip= sp->instructions(); sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(ip, ctx, $2, lex); - if (i == NULL || - sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)) || - sp->add_cont_backpatch(i) || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0))) || + unlikely(sp->add_cont_backpatch(i)) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; - if (sp->restore_lex(thd)) + if (unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } sp_proc_stmts1_implicit_block @@ -4053,8 +4213,8 @@ sp_if: sp_pcontext *ctx= Lex->spcont; uint ip= sp->instructions(); sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, ctx); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; sp->backpatch(ctx->pop_label()); sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)); @@ -4076,7 +4236,7 @@ sp_elseifs: case_stmt_specification: CASE_SYM { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; /** @@ -4147,10 +4307,9 @@ case_stmt_body: { Lex->sphead->reset_lex(thd); /* For expr $2 */ } expr { - if (Lex->case_stmt_action_expr($2)) + if (unlikely(Lex->case_stmt_action_expr($2))) MYSQL_YYABORT; - - if (Lex->sphead->restore_lex(thd)) + if (unlikely(Lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } simple_when_clause_list @@ -4179,16 +4338,16 @@ simple_when_clause: /* Simple case: <caseval> = <whenval> */ LEX *lex= Lex; - if (lex->case_stmt_action_when($3, true)) + if (unlikely(lex->case_stmt_action_when($3, true))) MYSQL_YYABORT; /* For expr $3 */ - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } THEN_SYM sp_proc_stmts1_implicit_block { - if (Lex->case_stmt_action_then()) + if (unlikely(Lex->case_stmt_action_then())) MYSQL_YYABORT; } ; @@ -4201,16 +4360,16 @@ searched_when_clause: expr { LEX *lex= Lex; - if (lex->case_stmt_action_when($3, false)) + if (unlikely(lex->case_stmt_action_when($3, false))) MYSQL_YYABORT; /* For expr $3 */ - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } THEN_SYM sp_proc_stmts1_implicit_block { - if (Lex->case_stmt_action_then()) + if (unlikely(Lex->case_stmt_action_then())) MYSQL_YYABORT; } ; @@ -4223,8 +4382,8 @@ else_clause_opt: uint ip= sp->instructions(); sp_instr_error *i= new (thd->mem_root) sp_instr_error(ip, lex->spcont, ER_SP_CASE_NOT_FOUND); - if (i == NULL || - sp->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(sp->add_instr(i))) MYSQL_YYABORT; } | ELSE sp_proc_stmts1_implicit_block @@ -4238,7 +4397,7 @@ sp_opt_label: sp_block_label: labels_declaration_oracle { - if (Lex->spcont->block_label_declare(&$1)) + if (unlikely(Lex->spcont->block_label_declare(&$1))) MYSQL_YYABORT; $$= $1; } @@ -4249,14 +4408,14 @@ sp_labeled_block: BEGIN_SYM { Lex->sp_block_init(thd, &$1); - if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } sp_block_statements_and_exceptions END sp_opt_label { - if (Lex->sp_block_finalize(thd, Lex_spblock($4), &$6)) + if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4), &$6))) MYSQL_YYABORT; } | sp_block_label @@ -4266,7 +4425,7 @@ sp_labeled_block: } sp_decl_body_list { - if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } BEGIN_SYM @@ -4275,7 +4434,7 @@ sp_labeled_block: sp_opt_label { $4.hndlrs+= $7.hndlrs; - if (Lex->sp_block_finalize(thd, $4, &$9)) + if (unlikely(Lex->sp_block_finalize(thd, $4, &$9))) MYSQL_YYABORT; } ; @@ -4288,27 +4447,27 @@ opt_not_atomic: sp_unlabeled_block: BEGIN_SYM opt_not_atomic { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sp_block_init(thd); - if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } sp_block_statements_and_exceptions END { - if (Lex->sp_block_finalize(thd, Lex_spblock($4))) + if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4)))) MYSQL_YYABORT; } | DECLARE_SYM { - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sp_block_init(thd); } sp_decl_body_list { - if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } BEGIN_SYM @@ -4316,7 +4475,7 @@ sp_unlabeled_block: END { $3.hndlrs+= $6.hndlrs; - if (Lex->sp_block_finalize(thd, $3)) + if (unlikely(Lex->sp_block_finalize(thd, $3))) MYSQL_YYABORT; } ; @@ -4331,14 +4490,14 @@ sp_body: } opt_sp_decl_body_list { - if (Lex->sp_block_with_exceptions_finalize_declarations(thd)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } BEGIN_SYM sp_block_statements_and_exceptions { $2.hndlrs+= $5.hndlrs; - if (Lex->sp_block_finalize(thd, $2)) + if (unlikely(Lex->sp_block_finalize(thd, $2))) MYSQL_YYABORT; } END @@ -4348,13 +4507,12 @@ sp_block_statements_and_exceptions: sp_instr_addr sp_proc_stmts { - if (Lex->sp_block_with_exceptions_finalize_executable_section(thd, - $1)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_executable_section(thd, $1))) MYSQL_YYABORT; } opt_exception_clause { - if (Lex->sp_block_with_exceptions_finalize_exceptions(thd, $1, $4)) + if (unlikely(Lex->sp_block_with_exceptions_finalize_exceptions(thd, $1, $4))) MYSQL_YYABORT; $$.init($4); } @@ -4373,14 +4531,14 @@ exception_handlers: exception_handler: WHEN_SYM { - if (Lex->sp_handler_declaration_init(thd, sp_handler::EXIT)) + if (unlikely(Lex->sp_handler_declaration_init(thd, sp_handler::EXIT))) MYSQL_YYABORT; } sp_hcond_list THEN_SYM sp_proc_stmts1_implicit_block { - if (Lex->sp_handler_declaration_finalize(thd, sp_handler::EXIT)) + if (unlikely(Lex->sp_handler_declaration_finalize(thd, sp_handler::EXIT))) MYSQL_YYABORT; } ; @@ -4394,7 +4552,7 @@ opt_sp_for_loop_direction: sp_for_loop_index_and_bounds: ident_directly_assignable sp_for_loop_bounds { - if (Lex->sp_for_loop_declarations(thd, &$$, &$1, $2)) + if (unlikely(Lex->sp_for_loop_declarations(thd, &$$, &$1, $2))) MYSQL_YYABORT; } ; @@ -4417,7 +4575,8 @@ sp_for_loop_bounds: } | IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')' { - if (Lex->sp_for_loop_implicit_cursor_statement(thd, &$$, $4)) + if (unlikely(Lex->sp_for_loop_implicit_cursor_statement(thd, &$$, + $4))) MYSQL_YYABORT; } ; @@ -4430,8 +4589,8 @@ loop_body: sp_label *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, lex->spcont, lab->ip); - if (i == NULL || - lex->sphead->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(lex->sphead->add_instr(i))) MYSQL_YYABORT; } ; @@ -4440,14 +4599,14 @@ while_body: expr LOOP_SYM { LEX *lex= Lex; - if (lex->sp_while_loop_expression(thd, $1)) + if (unlikely(lex->sp_while_loop_expression(thd, $1))) MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } sp_proc_stmts1 END LOOP_SYM { - if (Lex->sp_while_loop_finalize(thd)) + if (unlikely(Lex->sp_while_loop_finalize(thd))) MYSQL_YYABORT; } ; @@ -4462,10 +4621,10 @@ repeat_body: sp_label *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(ip, lex->spcont, $4, lab->ip, lex); - if (i == NULL || - lex->sphead->add_instr(i)) + if (unlikely(i == NULL) || + unlikely(lex->sphead->add_instr(i))) MYSQL_YYABORT; - if (lex->sphead->restore_lex(thd)) + if (unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; /* We can shortcut the cont_backpatch here */ i->m_cont_dest= ip+1; @@ -4475,7 +4634,7 @@ repeat_body: pop_sp_loop_label: sp_opt_label { - if (Lex->sp_pop_loop_label(thd, &$1)) + if (unlikely(Lex->sp_pop_loop_label(thd, &$1))) MYSQL_YYABORT; } ; @@ -4483,14 +4642,14 @@ pop_sp_loop_label: sp_labeled_control: labels_declaration_oracle LOOP_SYM { - if (Lex->sp_push_loop_label(thd, &$1)) + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; } loop_body pop_sp_loop_label { } | labels_declaration_oracle WHILE_SYM { - if (Lex->sp_push_loop_label(thd, &$1)) + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); } @@ -4503,28 +4662,28 @@ sp_labeled_control: } sp_for_loop_index_and_bounds { - if (Lex->sp_push_loop_label(thd, &$1)) // The inner WHILE block + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) // The inner WHILE block MYSQL_YYABORT; - if (Lex->sp_for_loop_condition_test(thd, $4)) + if (unlikely(Lex->sp_for_loop_condition_test(thd, $4))) MYSQL_YYABORT; } LOOP_SYM sp_proc_stmts1 END LOOP_SYM { - if (Lex->sp_for_loop_finalize(thd, $4)) + if (unlikely(Lex->sp_for_loop_finalize(thd, $4))) MYSQL_YYABORT; } pop_sp_loop_label // The inner WHILE block { Lex_spblock tmp; tmp.curs= MY_TEST($4.m_implicit_cursor); - if (Lex->sp_block_finalize(thd, tmp)) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END MYSQL_YYABORT; } | labels_declaration_oracle REPEAT_SYM { - if (Lex->sp_push_loop_label(thd, &$1)) + if (unlikely(Lex->sp_push_loop_label(thd, &$1))) MYSQL_YYABORT; } repeat_body pop_sp_loop_label @@ -4534,7 +4693,7 @@ sp_labeled_control: sp_unlabeled_control: LOOP_SYM { - if (Lex->sp_push_loop_empty_label(thd)) + if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; } loop_body @@ -4543,7 +4702,7 @@ sp_unlabeled_control: } | WHILE_SYM { - if (Lex->sp_push_loop_empty_label(thd)) + if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); } @@ -4554,15 +4713,15 @@ sp_unlabeled_control: | FOR_SYM { // See "The FOR LOOP statement" comments in sql_lex.cc - if (Lex->maybe_start_compound_statement(thd)) + if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block } sp_for_loop_index_and_bounds { - if (Lex->sp_push_loop_empty_label(thd)) // The inner WHILE block + if (unlikely(Lex->sp_push_loop_empty_label(thd))) // The inner WHILE block MYSQL_YYABORT; - if (Lex->sp_for_loop_condition_test(thd, $3)) + if (unlikely(Lex->sp_for_loop_condition_test(thd, $3))) MYSQL_YYABORT; } LOOP_SYM @@ -4571,15 +4730,15 @@ sp_unlabeled_control: { Lex_spblock tmp; tmp.curs= MY_TEST($3.m_implicit_cursor); - if (Lex->sp_for_loop_finalize(thd, $3)) + if (unlikely(Lex->sp_for_loop_finalize(thd, $3))) MYSQL_YYABORT; Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block - if (Lex->sp_block_finalize(thd, tmp)) // The outer DECLARE..BEGIN..END + if (unlikely(Lex->sp_block_finalize(thd, tmp))) // The outer DECLARE..BEGIN..END MYSQL_YYABORT; } | REPEAT_SYM { - if (Lex->sp_push_loop_empty_label(thd)) + if (unlikely(Lex->sp_push_loop_empty_label(thd))) MYSQL_YYABORT; } repeat_body @@ -4798,7 +4957,7 @@ tablespace_name: LEX *lex= Lex; lex->alter_tablespace_info= (new (thd->mem_root) st_alter_tablespace()); - if (lex->alter_tablespace_info == NULL) + if (unlikely(lex->alter_tablespace_info == NULL)) MYSQL_YYABORT; lex->alter_tablespace_info->tablespace_name= $1.str; lex->sql_command= SQLCOM_ALTER_TABLESPACE; @@ -4811,7 +4970,7 @@ logfile_group_name: LEX *lex= Lex; lex->alter_tablespace_info= (new (thd->mem_root) st_alter_tablespace()); - if (lex->alter_tablespace_info == NULL) + if (unlikely(lex->alter_tablespace_info == NULL)) MYSQL_YYABORT; lex->alter_tablespace_info->logfile_group_name= $1.str; lex->sql_command= SQLCOM_ALTER_TABLESPACE; @@ -4888,7 +5047,7 @@ opt_ts_nodegroup: NODEGROUP_SYM opt_equal real_ulong_num { LEX *lex= Lex; - if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP) + if (unlikely(lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP")); lex->alter_tablespace_info->nodegroup_id= $3; } @@ -4898,7 +5057,7 @@ opt_ts_comment: COMMENT_SYM opt_equal TEXT_STRING_sys { LEX *lex= Lex; - if (lex->alter_tablespace_info->ts_comment != NULL) + if (unlikely(lex->alter_tablespace_info->ts_comment != NULL)) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT")); lex->alter_tablespace_info->ts_comment= $3.str; } @@ -4908,7 +5067,7 @@ opt_ts_engine: opt_storage ENGINE_SYM opt_equal storage_engines { LEX *lex= Lex; - if (lex->alter_tablespace_info->storage_engine != NULL) + if (unlikely(lex->alter_tablespace_info->storage_engine != NULL)) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE, MYF(0), "STORAGE ENGINE")); lex->alter_tablespace_info->storage_engine= $4; @@ -4929,7 +5088,7 @@ ts_wait: | NO_WAIT_SYM { LEX *lex= Lex; - if (!(lex->alter_tablespace_info->wait_until_completed)) + if (unlikely(!(lex->alter_tablespace_info->wait_until_completed))) my_yyabort_error((ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT")); lex->alter_tablespace_info->wait_until_completed= FALSE; } @@ -4939,40 +5098,8 @@ size_number: real_ulonglong_num { $$= $1;} | IDENT_sys { - ulonglong number; - uint text_shift_number= 0; - longlong prefix_number; - const char *start_ptr= $1.str; - size_t str_len= $1.length; - const char *end_ptr= start_ptr + str_len; - int error; - prefix_number= my_strtoll10(start_ptr, (char**) &end_ptr, &error); - if ((start_ptr + str_len - 1) == end_ptr) - { - switch (end_ptr[0]) - { - case 'g': - case 'G': - text_shift_number+=10; - /* fall through */ - case 'm': - case 'M': - text_shift_number+=10; - /* fall through */ - case 'k': - case 'K': - text_shift_number+=10; - break; - default: - my_yyabort_error((ER_WRONG_SIZE_NUMBER, MYF(0))); - } - if (prefix_number >> 31) - my_yyabort_error((ER_SIZE_OVERFLOW_ERROR, MYF(0))); - number= prefix_number << text_shift_number; - } - else - my_yyabort_error((ER_WRONG_SIZE_NUMBER, MYF(0))); - $$= number; + if ($1.to_size_number(&$$)) + MYSQL_YYABORT; } ; @@ -5001,7 +5128,7 @@ create_body: Lex->create_info.add(DDL_options_st::OPT_LIKE); TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd, $1, NULL, 0, TL_READ, MDL_SHARED_READ); - if (! src_table) + if (unlikely(! src_table)) MYSQL_YYABORT; /* CREATE TABLE ... LIKE is not allowed for views. */ src_table->required_type= TABLE_TYPE_NORMAL; @@ -5015,7 +5142,7 @@ create_like: opt_create_select: /* empty */ {} - | opt_duplicate opt_as create_select_query_expression + | opt_duplicate opt_as create_select_query_expression opt_versioning_option ; create_select_query_expression: @@ -5085,11 +5212,8 @@ partitioning: { LEX *lex= Lex; lex->part_info= new (thd->mem_root) partition_info(); - if (!lex->part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!lex->part_info)) MYSQL_YYABORT; - } if (lex->sql_command == SQLCOM_ALTER_TABLE) { lex->alter_info.partition_flags|= ALTER_PARTITION_INFO; @@ -5103,7 +5227,7 @@ have_partitioning: { #ifdef WITH_PARTITION_STORAGE_ENGINE LEX_CSTRING partition_name={STRING_WITH_LEN("partition")}; - if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN)) + if (unlikely(!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))) my_yyabort_error((ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-partition")); #else @@ -5116,12 +5240,12 @@ have_partitioning: partition_entry: PARTITION_SYM { - LEX *lex= Lex; - if (!lex->part_info) + if (unlikely(!Lex->part_info)) { thd->parse_error(ER_PARTITION_ENTRY_ERROR); MYSQL_YYABORT; } + DBUG_ASSERT(Lex->part_info->table); /* We enter here when opening the frm file to translate partition info string into part_info data structure. @@ -5162,6 +5286,12 @@ part_type_def: } | LIST_SYM part_column_list { Lex->part_info->part_type= LIST_PARTITION; } + | SYSTEM_TIME_SYM + { + if (unlikely(Lex->part_info->vers_init_info(thd))) + MYSQL_YYABORT; + } + opt_versioning_rotation ; opt_linear: @@ -5204,12 +5334,10 @@ part_field_item: { partition_info *part_info= Lex->part_info; part_info->num_columns++; - if (part_info->part_field_list.push_back($1.str, thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(part_info->part_field_list.push_back($1.str, + thd->mem_root))) MYSQL_YYABORT; - } - if (part_info->num_columns > MAX_REF_PARTS) + if (unlikely(part_info->num_columns > MAX_REF_PARTS)) my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), "list of partition fields")); } @@ -5229,8 +5357,8 @@ part_func: '(' remember_name part_func_expr remember_end ')' { partition_info *part_info= Lex->part_info; - if (part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE)) - { MYSQL_YYABORT; } + if (unlikely(part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE))) + MYSQL_YYABORT; part_info->num_columns= 1; part_info->column_list= FALSE; } @@ -5239,8 +5367,8 @@ part_func: sub_part_func: '(' remember_name part_func_expr remember_end ')' { - if (Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE)) - { MYSQL_YYABORT; } + if (unlikely(Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE))) + MYSQL_YYABORT; } ; @@ -5251,7 +5379,7 @@ opt_num_parts: { uint num_parts= $2; partition_info *part_info= Lex->part_info; - if (num_parts == 0) + if (unlikely(num_parts == 0)) my_yyabort_error((ER_NO_PARTS_ERROR, MYF(0), "partitions")); part_info->num_parts= num_parts; @@ -5283,12 +5411,11 @@ sub_part_field_item: ident { partition_info *part_info= Lex->part_info; - if (part_info->subpart_field_list.push_back($1.str, thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(part_info->subpart_field_list.push_back($1.str, + thd->mem_root))) MYSQL_YYABORT; - } - if (part_info->subpart_field_list.elements > MAX_REF_PARTS) + + if (unlikely(part_info->subpart_field_list.elements > MAX_REF_PARTS)) my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), "list of subpartition fields")); } @@ -5297,7 +5424,7 @@ sub_part_field_item: part_func_expr: bit_expr { - if (!Lex->safe_to_cache_query) + if (unlikely(!Lex->safe_to_cache_query)) { thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); MYSQL_YYABORT; @@ -5312,7 +5439,7 @@ opt_num_subparts: { uint num_parts= $2; LEX *lex= Lex; - if (num_parts == 0) + if (unlikely(num_parts == 0)) my_yyabort_error((ER_NO_PARTS_ERROR, MYF(0), "subpartitions")); lex->part_info->num_subparts= num_parts; lex->part_info->use_default_num_subpartitions= FALSE; @@ -5323,10 +5450,10 @@ part_defs: /* empty */ { partition_info *part_info= Lex->part_info; - if (part_info->part_type == RANGE_PARTITION) + if (unlikely(part_info->part_type == RANGE_PARTITION)) my_yyabort_error((ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "RANGE")); - if (part_info->part_type == LIST_PARTITION) + if (unlikely(part_info->part_type == LIST_PARTITION)) my_yyabort_error((ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "LIST")); } @@ -5336,8 +5463,8 @@ part_defs: uint count_curr_parts= part_info->partitions.elements; if (part_info->num_parts != 0) { - if (part_info->num_parts != - count_curr_parts) + if (unlikely(part_info->num_parts != + count_curr_parts)) { thd->parse_error(ER_PARTITION_WRONG_NO_PART_ERROR); MYSQL_YYABORT; @@ -5362,13 +5489,12 @@ part_definition: partition_info *part_info= Lex->part_info; partition_element *p_elem= new (thd->mem_root) partition_element(); - if (!p_elem || - part_info->partitions.push_back(p_elem, thd->mem_root)) - { - mem_alloc_error(sizeof(partition_element)); + if (unlikely(!p_elem) || + unlikely(part_info->partitions.push_back(p_elem, thd->mem_root))) MYSQL_YYABORT; - } + p_elem->part_state= PART_NORMAL; + p_elem->id= part_info->partitions.elements - 1; part_info->curr_part_elem= p_elem; part_info->current_partition= p_elem; part_info->use_default_partitions= FALSE; @@ -5386,7 +5512,7 @@ part_name: { partition_info *part_info= Lex->part_info; partition_element *p_elem= part_info->curr_part_elem; - if (check_ident_length(&$1)) + if (unlikely(check_ident_length(&$1))) MYSQL_YYABORT; p_elem->partition_name= $1.str; } @@ -5399,12 +5525,12 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type == RANGE_PARTITION) - my_yyabort_error((ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), - "RANGE", "LESS THAN")); - if (part_info->part_type == LIST_PARTITION) - my_yyabort_error((ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), - "LIST", "IN")); + if (unlikely(part_info->error_if_requires_values())) + MYSQL_YYABORT; + if (unlikely(part_info->part_type == VERSIONING_PARTITION)) + my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0), + lex->create_last_non_select_table-> + table_name.str)); } else part_info->part_type= HASH_PARTITION; @@ -5415,7 +5541,7 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type != RANGE_PARTITION) + if (unlikely(part_info->part_type != RANGE_PARTITION)) my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN")); } @@ -5429,7 +5555,7 @@ opt_part_values: partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type != LIST_PARTITION) + if (unlikely(part_info->part_type != LIST_PARTITION)) my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "LIST", "IN")); } @@ -5437,26 +5563,32 @@ opt_part_values: part_info->part_type= LIST_PARTITION; } part_values_in {} + | CURRENT_SYM + { + if (Lex->part_values_current(thd)) + MYSQL_YYABORT; + } + | HISTORY_SYM + { + if (Lex->part_values_history(thd)) + MYSQL_YYABORT; + } | DEFAULT { LEX *lex= Lex; partition_info *part_info= lex->part_info; if (! lex->is_partition_management()) { - if (part_info->part_type != LIST_PARTITION) + if (unlikely(part_info->part_type != LIST_PARTITION)) my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), "LIST", "DEFAULT")); } else part_info->part_type= LIST_PARTITION; - if (part_info->init_column_part(thd)) - { + if (unlikely(part_info->init_column_part(thd))) MYSQL_YYABORT; - } - if (part_info->add_max_value(thd)) - { + if (unlikely(part_info->add_max_value(thd))) MYSQL_YYABORT; - } } ; @@ -5465,8 +5597,8 @@ part_func_max: { partition_info *part_info= Lex->part_info; - if (part_info->num_columns && - part_info->num_columns != 1U) + if (unlikely(part_info->num_columns && + part_info->num_columns != 1U)) { part_info->print_debug("Kilroy II", NULL); thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); @@ -5474,14 +5606,10 @@ part_func_max: } else part_info->num_columns= 1U; - if (part_info->init_column_part(thd)) - { + if (unlikely(part_info->init_column_part(thd))) MYSQL_YYABORT; - } - if (part_info->add_max_value(thd)) - { + if (unlikely(part_info->add_max_value(thd))) MYSQL_YYABORT; - } } | part_value_item {} ; @@ -5495,9 +5623,9 @@ part_values_in: if (part_info->num_columns != 1U) { - if (!lex->is_partition_management() || - part_info->num_columns == 0 || - part_info->num_columns > MAX_REF_PARTS) + if (unlikely(!lex->is_partition_management() || + part_info->num_columns == 0 || + part_info->num_columns > MAX_REF_PARTS)) { part_info->print_debug("Kilroy III", NULL); thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); @@ -5510,16 +5638,14 @@ part_values_in: we ADD or REORGANIZE partitions. Also can only happen for LIST partitions. */ - if (part_info->reorganize_into_single_field_col_val(thd)) - { + if (unlikely(part_info->reorganize_into_single_field_col_val(thd))) MYSQL_YYABORT; - } } } | '(' part_value_list ')' { partition_info *part_info= Lex->part_info; - if (part_info->num_columns < 2U) + if (unlikely(part_info->num_columns < 2U)) { thd->parse_error(ER_ROW_SINGLE_PARTITION_FIELD_ERROR); MYSQL_YYABORT; @@ -5538,12 +5664,10 @@ part_value_item: partition_info *part_info= Lex->part_info; part_info->print_debug("( part_value_item", NULL); /* Initialisation code needed for each list of value expressions */ - if (!(part_info->part_type == LIST_PARTITION && - part_info->num_columns == 1U) && - part_info->init_column_part(thd)) - { + if (unlikely(!(part_info->part_type == LIST_PARTITION && + part_info->num_columns == 1U) && + part_info->init_column_part(thd))) MYSQL_YYABORT; - } } part_value_item_list {} ')' @@ -5552,7 +5676,7 @@ part_value_item: part_info->print_debug(") part_value_item", NULL); if (part_info->num_columns == 0) part_info->num_columns= part_info->curr_list_object; - if (part_info->num_columns != part_info->curr_list_object) + if (unlikely(part_info->num_columns != part_info->curr_list_object)) { /* All value items lists must be of equal length, in some cases @@ -5578,15 +5702,13 @@ part_value_expr_item: MAXVALUE_SYM { partition_info *part_info= Lex->part_info; - if (part_info->part_type == LIST_PARTITION) + if (unlikely(part_info->part_type == LIST_PARTITION)) { thd->parse_error(ER_MAXVALUE_IN_VALUES_IN); MYSQL_YYABORT; } - if (part_info->add_max_value(thd)) - { + if (unlikely(part_info->add_max_value(thd))) MYSQL_YYABORT; - } } | bit_expr { @@ -5594,15 +5716,13 @@ part_value_expr_item: partition_info *part_info= lex->part_info; Item *part_expr= $1; - if (!lex->safe_to_cache_query) + if (unlikely(!lex->safe_to_cache_query)) { thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); MYSQL_YYABORT; } - if (part_info->add_column_list_value(thd, part_expr)) - { + if (unlikely(part_info->add_column_list_value(thd, part_expr))) MYSQL_YYABORT; - } } ; @@ -5611,8 +5731,8 @@ opt_sub_partition: /* empty */ { partition_info *part_info= Lex->part_info; - if (part_info->num_subparts != 0 && - !part_info->use_default_subpartitions) + if (unlikely(part_info->num_subparts != 0 && + !part_info->use_default_subpartitions)) { /* We come here when we have defined subpartitions on the first @@ -5627,8 +5747,8 @@ opt_sub_partition: partition_info *part_info= Lex->part_info; if (part_info->num_subparts != 0) { - if (part_info->num_subparts != - part_info->count_curr_subparts) + if (unlikely(part_info->num_subparts != + part_info->count_curr_subparts)) { thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; @@ -5636,7 +5756,7 @@ opt_sub_partition: } else if (part_info->count_curr_subparts > 0) { - if (part_info->partitions.elements > 1) + if (unlikely(part_info->partitions.elements > 1)) { thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; @@ -5659,8 +5779,8 @@ sub_part_definition: partition_element *curr_part= part_info->current_partition; partition_element *sub_p_elem= new (thd->mem_root) partition_element(curr_part); - if (part_info->use_default_subpartitions && - part_info->partitions.elements >= 2) + if (unlikely(part_info->use_default_subpartitions && + part_info->partitions.elements >= 2)) { /* create table t1 (a int) @@ -5676,12 +5796,11 @@ sub_part_definition: thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; } - if (!sub_p_elem || - curr_part->subpartitions.push_back(sub_p_elem, thd->mem_root)) - { - mem_alloc_error(sizeof(partition_element)); + if (unlikely(!sub_p_elem) || + unlikely(curr_part->subpartitions.push_back(sub_p_elem, thd->mem_root))) MYSQL_YYABORT; - } + + sub_p_elem->id= curr_part->subpartitions.elements - 1; part_info->curr_part_elem= sub_p_elem; part_info->use_default_subpartitions= FALSE; part_info->use_default_num_subpartitions= FALSE; @@ -5693,7 +5812,7 @@ sub_part_definition: sub_name: ident_or_text { - if (check_ident_length(&$1)) + if (unlikely(check_ident_length(&$1))) MYSQL_YYABORT; Lex->part_info->curr_part_elem->partition_name= $1.str; } @@ -5738,6 +5857,50 @@ opt_part_option: { Lex->part_info->curr_part_elem->part_comment= $3.str; } ; +opt_versioning_rotation: + /* empty */ {} + | INTERVAL_SYM expr interval opt_versioning_interval_start + { + partition_info *part_info= Lex->part_info; + if (unlikely(part_info->vers_set_interval($2, $3, $4))) + { + my_error(ER_PART_WRONG_VALUE, MYF(0), + Lex->create_last_non_select_table->table_name.str, + "INTERVAL"); + MYSQL_YYABORT; + } + } + | LIMIT ulonglong_num + { + partition_info *part_info= Lex->part_info; + if (unlikely(part_info->vers_set_limit($2))) + { + my_error(ER_PART_WRONG_VALUE, MYF(0), + Lex->create_last_non_select_table->table_name.str, + "LIMIT"); + MYSQL_YYABORT; + } + } + ; + + +opt_versioning_interval_start: + /* empty */ + { + $$= thd->query_start(); + } + | STARTS_SYM ulong_num + { + /* only allowed from mysql_unpack_partition() */ + if (unlikely(!Lex->part_info->table)) + { + thd->parse_error(ER_SYNTAX_ERROR, $1.pos()); + MYSQL_YYABORT; + } + $$= (ulong)$2; + } + ; + /* End of partition parser part */ @@ -5969,7 +6132,7 @@ create_table_option: larger values. 65535 pages, 16kb each means to sample 1GB, which is impractical. If at some point this needs to be extended, then we can store the higher bits from stats_sample_pages in .frm too. */ - if ($3 == 0 || $3 > 0xffff) + if (unlikely($3 == 0 || $3 > 0xffff)) { thd->parse_error(); MYSQL_YYABORT; @@ -6074,43 +6237,70 @@ create_table_option: } | IDENT_sys equal TEXT_STRING_sys { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, true, &Lex->create_info.option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, true, + &Lex->create_info.option_list, + &Lex->option_list_last); } | IDENT_sys equal ident { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, false, &Lex->create_info.option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, false, + &Lex->create_info.option_list, + &Lex->option_list_last); } | IDENT_sys equal real_ulonglong_num { - new (thd->mem_root) - engine_option_value($1, $3, &Lex->create_info.option_list, - &Lex->option_list_last, thd->mem_root); + (void) new (thd->mem_root) + engine_option_value($1, $3, &Lex->create_info.option_list, + &Lex->option_list_last, thd->mem_root); } | IDENT_sys equal DEFAULT { - new (thd->mem_root) - engine_option_value($1, &Lex->create_info.option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, &Lex->create_info.option_list, + &Lex->option_list_last); } | SEQUENCE_SYM opt_equal choice { Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE; Lex->create_info.sequence= ($3 == HA_CHOICE_YES); + } + | versioning_option + ; + +opt_versioning_option: + /* empty */ + | versioning_option + ; + +versioning_option: + WITH_SYSTEM_SYM VERSIONING_SYM + { + if (unlikely(Lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) + { + if (DBUG_EVALUATE_IF("sysvers_force", 0, 1)) + { + my_error(ER_VERS_TEMPORARY, MYF(0)); + MYSQL_YYABORT; + } + } + else + { + Lex->alter_info.flags|= ALTER_ADD_SYSTEM_VERSIONING; + Lex->create_info.options|= HA_VERSIONED_TABLE; + } } ; default_charset: opt_default charset opt_equal charset_name_or_default { - if (Lex->create_info.add_table_option_default_charset($4)) + if (unlikely(Lex->create_info.add_table_option_default_charset($4))) MYSQL_YYABORT; } ; @@ -6119,13 +6309,11 @@ default_collation: opt_default COLLATE_SYM opt_equal collation_name_or_default { HA_CREATE_INFO *cinfo= &Lex->create_info; - if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && - cinfo->default_table_charset && $4 && - !($4= merge_charset_and_collation(cinfo->default_table_charset, - $4))) - { + if (unlikely((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !($4= merge_charset_and_collation(cinfo->default_table_charset, + $4)))) MYSQL_YYABORT; - } Lex->create_info.default_table_charset= $4; Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; @@ -6138,7 +6326,7 @@ storage_engines: plugin_ref plugin= ha_resolve_by_name(thd, &$1, thd->lex->create_info.tmp_table()); - if (plugin) + if (likely(plugin)) $$= plugin_hton(plugin); else { @@ -6157,7 +6345,7 @@ known_storage_engines: ident_or_text { plugin_ref plugin; - if ((plugin= ha_resolve_by_name(thd, &$1, false))) + if (likely((plugin= ha_resolve_by_name(thd, &$1, false)))) $$= plugin_hton(plugin); else my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str)); @@ -6204,6 +6392,7 @@ field_list_item: column_def { } | key_def | constraint_def + | period_for_system_time ; column_def: @@ -6217,28 +6406,28 @@ key_def: key_or_index opt_if_not_exists opt_ident opt_USING_key_algorithm { Lex->option_list= NULL; - if (Lex->add_key(Key::MULTIPLE, &$3, $4, $2)) + if (unlikely(Lex->add_key(Key::MULTIPLE, &$3, $4, $2))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | key_or_index opt_if_not_exists ident TYPE_SYM btree_or_rtree { Lex->option_list= NULL; - if (Lex->add_key(Key::MULTIPLE, &$3, $5, $2)) + if (unlikely(Lex->add_key(Key::MULTIPLE, &$3, $5, $2))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | fulltext opt_key_or_index opt_if_not_exists opt_ident { Lex->option_list= NULL; - if (Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)) + if (unlikely(Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3))) MYSQL_YYABORT; } '(' key_list ')' fulltext_key_options { } | spatial opt_key_or_index opt_if_not_exists opt_ident { Lex->option_list= NULL; - if (Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)) + if (unlikely(Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3))) MYSQL_YYABORT; } '(' key_list ')' spatial_key_options { } @@ -6247,7 +6436,7 @@ key_def: opt_USING_key_algorithm { Lex->option_list= NULL; - if (Lex->add_key($2, $4.str ? &$4 : &$1, $5, $3)) + if (unlikely(Lex->add_key($2, $4.str ? &$4 : &$1, $5, $3))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } @@ -6255,16 +6444,17 @@ key_def: TYPE_SYM btree_or_rtree { Lex->option_list= NULL; - if (Lex->add_key($2, $4.str ? &$4 : &$1, $6, $3)) + if (unlikely(Lex->add_key($2, $4.str ? &$4 : &$1, $6, $3))) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | opt_constraint FOREIGN KEY_SYM opt_if_not_exists opt_ident { - if (Lex->check_add_key($4) || - !(Lex->last_key= (new (thd->mem_root) - Key(Key::MULTIPLE, $1.str ? &$1 : &$5, - HA_KEY_ALG_UNDEF, true, $4)))) + if (unlikely(Lex->check_add_key($4)) || + unlikely(!(Lex->last_key= (new (thd->mem_root) + Key(Key::MULTIPLE, + $1.str ? &$1 : &$5, + HA_KEY_ALG_UNDEF, true, $4))))) MYSQL_YYABORT; Lex->option_list= NULL; } @@ -6281,7 +6471,7 @@ key_def: lex->fk_update_opt, lex->fk_match_option, $4)); - if (key == NULL) + if (unlikely(key == NULL)) MYSQL_YYABORT; /* handle_if_exists_options() expectes the two keys in this order: @@ -6303,6 +6493,15 @@ constraint_def: } ; +period_for_system_time: + // If FOR_SYM is followed by SYSTEM_TIME_SYM then they are merged to: FOR_SYSTEM_TIME_SYM . + PERIOD_SYM FOR_SYSTEM_TIME_SYM '(' ident ',' ident ')' + { + Vers_parse_info &info= Lex->vers_get_info(); + info.set_system_time($4, $6); + } + ; + opt_check_constraint: /* empty */ { $$= (Virtual_column_info*) 0; } | check_constraint { $$= $1;} @@ -6311,12 +6510,9 @@ opt_check_constraint: check_constraint: CHECK_SYM '(' expr ')' { - Virtual_column_info *v= - add_virtual_expression(thd, $3); - if (!v) - { + Virtual_column_info *v= add_virtual_expression(thd, $3); + if (unlikely(!v)) MYSQL_YYABORT; - } $$= v; } ; @@ -6336,11 +6532,11 @@ field_spec: LEX *lex=Lex; Create_field *f= new (thd->mem_root) Create_field(); - if (check_string_char_length(&$1, 0, NAME_CHAR_LEN, - system_charset_info, 1)) + if (unlikely(check_string_char_length(&$1, 0, NAME_CHAR_LEN, + system_charset_info, 1))) my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str)); - if (!f) + if (unlikely(!f)) MYSQL_YYABORT; lex->init_last_field(f, &$1, NULL); @@ -6353,7 +6549,7 @@ field_spec: $$->check_constraint= $4; - if ($$->check(thd)) + if (unlikely($$->check(thd))) MYSQL_YYABORT; lex->alter_info.create_list.push_back($$, thd->mem_root); @@ -6388,6 +6584,15 @@ opt_serial_attribute_list: | serial_attribute ; +opt_asrow_attribute: + /* empty */ {} + | opt_asrow_attribute_list {} + ; + +opt_asrow_attribute_list: + opt_asrow_attribute_list asrow_attribute {} + | asrow_attribute + ; field_def: opt_attribute @@ -6397,6 +6602,16 @@ field_def: Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps } vcol_opt_specifier vcol_opt_attribute + | opt_generated_always AS ROW_SYM START_SYM opt_asrow_attribute + { + if (Lex->last_field_generated_always_as_row_start()) + MYSQL_YYABORT; + } + | opt_generated_always AS ROW_SYM END opt_asrow_attribute + { + if (Lex->last_field_generated_always_as_row_end()) + MYSQL_YYABORT; + } ; opt_generated_always: @@ -6466,7 +6681,7 @@ parse_vcol_expr: expr { Virtual_column_info *v= add_virtual_expression(thd, $3); - if (!v) + if (unlikely(!v)) MYSQL_YYABORT; Lex->last_field->vcol_info= v; } @@ -6476,7 +6691,7 @@ parenthesized_expr: subselect { $$= new (thd->mem_root) Item_singlerow_subselect(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | expr @@ -6484,7 +6699,7 @@ parenthesized_expr: { $3->push_front($1, thd->mem_root); $$= new (thd->mem_root) Item_row(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -6494,10 +6709,8 @@ virtual_column_func: { Virtual_column_info *v= add_virtual_expression(thd, $2); - if (!v) - { + if (unlikely(!v)) MYSQL_YYABORT; - } $$= v; } ; @@ -6508,7 +6721,7 @@ column_default_expr: virtual_column_func | expr_or_literal { - if (!($$= add_virtual_expression(thd, $1))) + if (unlikely(!($$= add_virtual_expression(thd, $1)))) MYSQL_YYABORT; } ; @@ -6541,7 +6754,7 @@ field_type_numeric: { int err; ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err); - if (err || tmp_length > PRECISION_FOR_DOUBLE) + if (unlikely(err || tmp_length > PRECISION_FOR_DOUBLE)) my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0), Lex->last_field->field_name.str)); if (tmp_length > PRECISION_FOR_FLOAT) @@ -6925,29 +7138,42 @@ attribute: | ON UPDATE_SYM NOW_SYM opt_default_time_precision { Item *item= new (thd->mem_root) Item_func_now_local(thd, $4); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; Lex->last_field->on_update= item; } | AUTO_INC { Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; } | SERIAL_SYM DEFAULT VALUE_SYM - { + { LEX *lex=Lex; lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG; lex->alter_info.flags|= ALTER_ADD_INDEX; } | COLLATE_SYM collation_name { - if (Lex->charset && !my_charset_same(Lex->charset,$2)) + if (unlikely(Lex->charset && !my_charset_same(Lex->charset,$2))) my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0), $2->name,Lex->charset->csname)); Lex->last_field->charset= $2; } + | COMPRESSED_SYM opt_compression_method + { + if (unlikely(Lex->last_field->set_compressed($2))) + MYSQL_YYABORT; + } | serial_attribute ; -serial_attribute: - not NULL_SYM { Lex->last_field->flags|= NOT_NULL_FLAG; } +opt_compression_method: + /* empty */ { $$= NULL; } + | equal ident { $$= $2.str; } + ; + +asrow_attribute: + not NULL_SYM + { + Lex->last_field->flags|= NOT_NULL_FLAG; + } | opt_primary KEY_SYM { LEX *lex=Lex; @@ -6955,32 +7181,59 @@ serial_attribute: lex->alter_info.flags|= ALTER_ADD_INDEX; } | vcol_attribute + ; + +serial_attribute: + asrow_attribute | IDENT_sys equal TEXT_STRING_sys { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, true, &Lex->last_field->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, true, + &Lex->last_field->option_list, + &Lex->option_list_last); } | IDENT_sys equal ident { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, false, &Lex->last_field->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, false, + &Lex->last_field->option_list, + &Lex->option_list_last); } | IDENT_sys equal real_ulonglong_num { - new (thd->mem_root) - engine_option_value($1, $3, &Lex->last_field->option_list, - &Lex->option_list_last, thd->mem_root); + (void) new (thd->mem_root) + engine_option_value($1, $3, &Lex->last_field->option_list, + &Lex->option_list_last, thd->mem_root); } | IDENT_sys equal DEFAULT { - new (thd->mem_root) - engine_option_value($1, &Lex->last_field->option_list, &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, &Lex->last_field->option_list, + &Lex->option_list_last); + } + | with_or_without_system VERSIONING_SYM + { + Lex->last_field->versioning= $1; + Lex->create_info.options|= HA_VERSIONED_TABLE; + } + ; + +with_or_without_system: + WITH_SYSTEM_SYM + { + Lex->alter_info.flags|= ALTER_COLUMN_UNVERSIONED; + Lex->create_info.vers_info.versioned_fields= true; + $$= Column_definition::WITH_VERSIONING; + } + | WITHOUT SYSTEM + { + Lex->alter_info.flags|= ALTER_COLUMN_UNVERSIONED; + Lex->create_info.vers_info.unversioned_fields= true; + $$= Column_definition::WITHOUT_VERSIONING; } ; @@ -6992,7 +7245,7 @@ type_with_opt_collate: if ($2) { - if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))) + if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))) MYSQL_YYABORT; } Lex->last_field->set_attributes($1, Lex->charset); @@ -7005,7 +7258,7 @@ sp_param_type_with_opt_collate: $$= $1; if ($2) { - if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))) + if (unlikely(!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))) MYSQL_YYABORT; } Lex->last_field->set_attributes($1, Lex->charset); @@ -7020,7 +7273,7 @@ charset: charset_name: ident_or_text { - if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) + if (unlikely(!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str)); } | BINARY { $$= &my_charset_bin; } @@ -7039,8 +7292,9 @@ opt_load_data_charset: old_or_new_charset_name: ident_or_text { - if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && - !($$=get_old_charset_by_name($1.str))) + if (unlikely(!($$=get_charset_by_csname($1.str, + MY_CS_PRIMARY,MYF(0))) && + !($$=get_old_charset_by_name($1.str)))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str)); } | BINARY { $$= &my_charset_bin; } @@ -7054,7 +7308,7 @@ old_or_new_charset_name_or_default: collation_name: ident_or_text { - if (!($$= mysqld_collation_get_by_name($1.str))) + if (unlikely(!($$= mysqld_collation_get_by_name($1.str)))) MYSQL_YYABORT; } ; @@ -7079,7 +7333,7 @@ charset_or_alias: | ASCII_SYM { $$= &my_charset_latin1; } | UNICODE_SYM { - if (!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0)))) + if (unlikely(!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0))))) my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2")); } ; @@ -7100,7 +7354,7 @@ opt_bin_mod: ws_nweights: '(' real_ulong_num { - if ($2 == 0) + if (unlikely($2 == 0)) { thd->parse_error(); MYSQL_YYABORT; @@ -7191,14 +7445,14 @@ ref_list: ref_list ',' ident { Key_part_spec *key= new (thd->mem_root) Key_part_spec(&$3, 0); - if (key == NULL) + if (unlikely(key == NULL)) MYSQL_YYABORT; Lex->ref_list.push_back(key, thd->mem_root); } | ident { Key_part_spec *key= new (thd->mem_root) Key_part_spec(&$1, 0); - if (key == NULL) + if (unlikely(key == NULL)) MYSQL_YYABORT; LEX *lex= Lex; lex->ref_list.empty(); @@ -7352,37 +7606,38 @@ key_using_alg: all_key_opt: KEY_BLOCK_SIZE opt_equal ulong_num { - Lex->create_info.used_fields|= HA_USES_BLOCK_SIZE; - Lex->create_info.key_block_size= $3; - } + Lex->last_key->key_create_info.block_size= $3; + Lex->last_key->key_create_info.flags|= HA_USES_BLOCK_SIZE; + } | COMMENT_SYM TEXT_STRING_sys { Lex->last_key->key_create_info.comment= $2; } | IDENT_sys equal TEXT_STRING_sys { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, true, &Lex->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, true, &Lex->option_list, + &Lex->option_list_last); } | IDENT_sys equal ident { - if ($3.length > ENGINE_OPTION_MAX_LENGTH) + if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH)) my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str)); - new (thd->mem_root) - engine_option_value($1, $3, false, &Lex->option_list, - &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, $3, false, &Lex->option_list, + &Lex->option_list_last); } | IDENT_sys equal real_ulonglong_num { - new (thd->mem_root) - engine_option_value($1, $3, &Lex->option_list, - &Lex->option_list_last, thd->mem_root); + (void) new (thd->mem_root) + engine_option_value($1, $3, &Lex->option_list, + &Lex->option_list_last, thd->mem_root); } | IDENT_sys equal DEFAULT { - new (thd->mem_root) - engine_option_value($1, &Lex->option_list, &Lex->option_list_last); + (void) new (thd->mem_root) + engine_option_value($1, &Lex->option_list, + &Lex->option_list_last); } ; @@ -7399,7 +7654,7 @@ fulltext_key_opt: all_key_opt | WITH PARSER_SYM IDENT_sys { - if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN)) + if (likely(plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))) Lex->last_key->key_create_info.parser_name= $3; else my_yyabort_error((ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str)); @@ -7427,16 +7682,16 @@ key_part: ident { $$= new (thd->mem_root) Key_part_spec(&$1, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ident '(' NUM ')' { int key_part_len= atoi($3.str); - if (!key_part_len) + if (unlikely(!key_part_len)) my_yyabort_error((ER_KEY_PART_0, MYF(0), $1.str)); $$= new (thd->mem_root) Key_part_spec(&$1, (uint) key_part_len); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -7446,11 +7701,6 @@ opt_ident: | field_ident { $$= $1; } ; -opt_component: - /* empty */ { $$= null_clex_str; } - | '.' ident { $$= $2; } - ; - string_list: text_string { Lex->last_field->interval_list.push_back($1, thd->mem_root); } @@ -7478,21 +7728,21 @@ alter: } alter_options TABLE_SYM table_ident opt_lock_wait_timeout { - if (!Lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_UPGRADABLE)) + if (unlikely(!Lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_UPGRADABLE))) MYSQL_YYABORT; Lex->select_lex.db= (Lex->select_lex.table_list.first)->db; Lex->create_last_non_select_table= Lex->last_table(); } alter_commands { - if (!Lex->m_sql_cmd) + if (likely(!Lex->m_sql_cmd)) { /* Create a generic ALTER TABLE statment. */ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table(); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } } @@ -7506,13 +7756,14 @@ alter: LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; lex->name= $3; - if (lex->name.str == NULL && lex->copy_db_to(&lex->name)) + if (lex->name.str == NULL && + unlikely(lex->copy_db_to(&lex->name))) MYSQL_YYABORT; } | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "DATABASE")); lex->sql_command= SQLCOM_ALTER_DB_UPGRADE; lex->name= $3; @@ -7521,7 +7772,7 @@ alter: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE")); lex->sp_chistics.init(); } @@ -7536,7 +7787,7 @@ alter: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); lex->sp_chistics.init(); } @@ -7549,7 +7800,7 @@ alter: } | ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident { - if (Lex->add_alter_view(thd, $2, $4, $6)) + if (unlikely(Lex->add_alter_view(thd, $2, $4, $6))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -7561,7 +7812,7 @@ alter: with the ALTER EVENT below. */ { - if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5)) + if (unlikely(Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5))) MYSQL_YYABORT; } view_list_opt AS view_select @@ -7576,7 +7827,7 @@ alter: Event_parse_data. */ - if (!(Lex->event_parse_data= Event_parse_data::new_instance(thd))) + if (unlikely(!(Lex->event_parse_data= Event_parse_data::new_instance(thd)))) MYSQL_YYABORT; Lex->event_parse_data->identifier= $5; @@ -7589,7 +7840,7 @@ alter: opt_ev_comment opt_ev_sql_stmt { - if (!($7 || $8 || $9 || $10 || $11)) + if (unlikely(!($7 || $8 || $9 || $10 || $11))) { thd->parse_error(); MYSQL_YYABORT; @@ -7647,18 +7898,19 @@ alter: table_ident { LEX *lex= Lex; - if (!(lex->create_info.seq_create_info= new (thd->mem_root) - sequence_definition()) || - !lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_SEQUENCE, - TL_WRITE, MDL_EXCLUSIVE)) + if (unlikely(!(lex->create_info.seq_create_info= + new (thd->mem_root) sequence_definition())) || + unlikely(!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_SEQUENCE, + TL_WRITE, + MDL_EXCLUSIVE))) MYSQL_YYABORT; } sequence_defs { /* Create a generic ALTER SEQUENCE statment. */ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -7689,8 +7941,8 @@ opt_ev_sql_stmt: ; ident_or_empty: - /* empty */ { $$= null_clex_str; } - | ident { $$= $1; } + /* empty */ { $$= Lex_ident_sys(); } + | ident ; alter_commands: @@ -7700,7 +7952,7 @@ alter_commands: Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_discard_import_tablespace( Sql_cmd_discard_import_tablespace::DISCARD_TABLESPACE); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | IMPORT TABLESPACE @@ -7708,7 +7960,7 @@ alter_commands: Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_discard_import_tablespace( Sql_cmd_discard_import_tablespace::IMPORT_TABLESPACE); - if (Lex->m_sql_cmd == NULL) + if (unlikely(Lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | alter_list @@ -7747,7 +7999,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_optimize_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_no_write_to_binlog @@ -7760,7 +8012,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_analyze_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list @@ -7770,7 +8022,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_check_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_mi_check_type @@ -7783,7 +8035,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_repair_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_mi_repair_type @@ -7801,7 +8053,7 @@ alter_commands: DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_truncate_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } | reorg_partition_rule @@ -7811,21 +8063,19 @@ alter_commands: LEX *lex= thd->lex; lex->select_lex.db= $6->db; if (lex->select_lex.db.str == NULL && - lex->copy_db_to(&lex->select_lex.db)) - { + unlikely(lex->copy_db_to(&lex->select_lex.db))) MYSQL_YYABORT; - } lex->name= $6->table; lex->alter_info.partition_flags|= ALTER_PARTITION_EXCHANGE; - if (!lex->select_lex.add_table_to_list(thd, $6, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $6, NULL, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE))) MYSQL_YYABORT; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table_exchange_partition(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -7851,11 +8101,9 @@ add_partition_rule: { LEX *lex= Lex; lex->part_info= new (thd->mem_root) partition_info(); - if (!lex->part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!lex->part_info)) MYSQL_YYABORT; - } + lex->alter_info.partition_flags|= ALTER_PARTITION_ADD; DBUG_ASSERT(!Lex->create_info.if_not_exists()); lex->create_info.set($3); @@ -7883,11 +8131,9 @@ reorg_partition_rule: { LEX *lex= Lex; lex->part_info= new (thd->mem_root) partition_info(); - if (!lex->part_info) - { - mem_alloc_error(sizeof(partition_info)); + if (unlikely(!lex->part_info)) MYSQL_YYABORT; - } + lex->no_write_to_binlog= $3; } reorg_parts_rule @@ -7917,12 +8163,9 @@ alt_part_name_list: alt_part_name_item: ident { - if (Lex->alter_info.partition_names.push_back($1.str, - thd->mem_root)) - { - mem_alloc_error(1); + if (unlikely(Lex->alter_info.partition_names.push_back($1.str, + thd->mem_root))) MYSQL_YYABORT; - } } ; @@ -7952,6 +8195,10 @@ alter_list_item: Lex->create_last_non_select_table= Lex->last_table(); Lex->alter_info.flags|= ALTER_ADD_INDEX; } + | ADD period_for_system_time + { + Lex->alter_info.flags|= ALTER_ADD_PERIOD; + } | add_column '(' create_field_list ')' { LEX *lex=Lex; @@ -7989,7 +8236,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::COLUMN, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_PARSER_DROP_COLUMN; @@ -8000,7 +8247,7 @@ alter_list_item: Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::CHECK_CONSTRAINT, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_CHECK_CONSTRAINT; @@ -8010,7 +8257,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::FOREIGN_KEY, $5.str, $4)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_FOREIGN_KEY; @@ -8021,7 +8268,7 @@ alter_list_item: Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::KEY, primary_key_name, FALSE)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_INDEX; @@ -8031,7 +8278,7 @@ alter_list_item: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::KEY, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad, thd->mem_root); lex->alter_info.flags|= ALTER_DROP_INDEX; @@ -8050,12 +8297,13 @@ alter_list_item: } | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr { - if (Lex->add_alter_list($4.str, $7, $3)) + if (unlikely(Lex->add_alter_list($4.str, $7, $3))) MYSQL_YYABORT; } | ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT { - if (Lex->add_alter_list($4.str, (Virtual_column_info*) 0, $3)) + if (unlikely(Lex->add_alter_list($4.str, (Virtual_column_info*) 0, + $3))) MYSQL_YYABORT; } | RENAME opt_to table_ident @@ -8063,12 +8311,11 @@ alter_list_item: LEX *lex=Lex; lex->select_lex.db= $3->db; if (lex->select_lex.db.str == NULL && - lex->copy_db_to(&lex->select_lex.db)) - { + unlikely(lex->copy_db_to(&lex->select_lex.db))) MYSQL_YYABORT; - } - if (check_table_name($3->table.str,$3->table.length, FALSE) || - ($3->db.str && check_db_name((LEX_STRING*) &$3->db))) + if (unlikely(check_table_name($3->table.str,$3->table.length, + FALSE)) || + ($3->db.str && unlikely(check_db_name((LEX_STRING*) &$3->db)))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3->table.str)); lex->name= $3->table; lex->alter_info.flags|= ALTER_RENAME; @@ -8080,10 +8327,10 @@ alter_list_item: $4= thd->variables.collation_database; } $5= $5 ? $5 : $4; - if (!my_charset_same($4,$5)) + if (unlikely(!my_charset_same($4,$5))) my_yyabort_error((ER_COLLATION_CHARSET_MISMATCH, MYF(0), $5->name, $4->csname)); - if (Lex->create_info.add_alter_list_item_convert_to_charset($5)) + if (unlikely(Lex->create_info.add_alter_list_item_convert_to_charset($5))) MYSQL_YYABORT; Lex->alter_info.flags|= ALTER_OPTIONS; } @@ -8108,6 +8355,19 @@ alter_list_item: } | alter_algorithm_option | alter_lock_option + | ADD SYSTEM VERSIONING_SYM + { + Lex->alter_info.flags|= ALTER_ADD_SYSTEM_VERSIONING; + Lex->create_info.options|= HA_VERSIONED_TABLE; + } + | DROP SYSTEM VERSIONING_SYM + { + Lex->alter_info.flags|= ALTER_DROP_SYSTEM_VERSIONING; + } + | DROP PERIOD_SYM FOR_SYSTEM_TIME_SYM + { + Lex->alter_info.flags|= ALTER_DROP_PERIOD; + } ; opt_index_lock_algorithm: @@ -8125,7 +8385,7 @@ alter_algorithm_option: } | ALGORITHM_SYM opt_equal ident { - if (Lex->alter_info.set_requested_algorithm(&$3)) + if (unlikely(Lex->alter_info.set_requested_algorithm(&$3))) my_yyabort_error((ER_UNKNOWN_ALTER_ALGORITHM, MYF(0), $3.str)); } ; @@ -8138,13 +8398,13 @@ alter_lock_option: } | LOCK_SYM opt_equal ident { - if (Lex->alter_info.set_requested_lock(&$3)) + if (unlikely(Lex->alter_info.set_requested_lock(&$3))) my_yyabort_error((ER_UNKNOWN_ALTER_LOCK, MYF(0), $3.str)); } ; opt_column: - /* empty */ {} + /* empty */ {} %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE | COLUMN_SYM {} ; @@ -8244,8 +8504,8 @@ start: LEX *lex= Lex; lex->sql_command= SQLCOM_BEGIN; /* READ ONLY and READ WRITE are mutually exclusive. */ - if (($3 & MYSQL_START_TRANS_OPT_READ_WRITE) && - ($3 & MYSQL_START_TRANS_OPT_READ_ONLY)) + if (unlikely(($3 & MYSQL_START_TRANS_OPT_READ_WRITE) && + ($3 & MYSQL_START_TRANS_OPT_READ_ONLY))) { thd->parse_error(); MYSQL_YYABORT; @@ -8313,10 +8573,10 @@ slave_until: | UNTIL_SYM slave_until_opts { LEX *lex=Lex; - if (((lex->mi.log_file_name || lex->mi.pos) && - (lex->mi.relay_log_name || lex->mi.relay_log_pos)) || - !((lex->mi.log_file_name && lex->mi.pos) || - (lex->mi.relay_log_name && lex->mi.relay_log_pos))) + if (unlikely(((lex->mi.log_file_name || lex->mi.pos) && + (lex->mi.relay_log_name || lex->mi.relay_log_pos)) || + !((lex->mi.log_file_name && lex->mi.pos) || + (lex->mi.relay_log_name && lex->mi.relay_log_pos)))) my_yyabort_error((ER_BAD_SLAVE_UNTIL_COND, MYF(0))); } | UNTIL_SYM MASTER_GTID_POS_SYM '=' TEXT_STRING_sys @@ -8371,7 +8631,7 @@ repair: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8413,7 +8673,7 @@ analyze: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8448,7 +8708,7 @@ persistent_column_stat_spec: { LEX* lex= thd->lex; lex->column_list= new (thd->mem_root) List<LEX_STRING>; - if (lex->column_list == NULL) + if (unlikely(lex->column_list == NULL)) MYSQL_YYABORT; } table_column_list @@ -8461,7 +8721,7 @@ persistent_index_stat_spec: { LEX* lex= thd->lex; lex->index_list= new (thd->mem_root) List<LEX_STRING>; - if (lex->index_list == NULL) + if (unlikely(lex->index_list == NULL)) MYSQL_YYABORT; } table_index_list @@ -8535,11 +8795,11 @@ check: CHECK_SYM check_view_or_table { LEX* lex= thd->lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "CHECK")); DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8584,7 +8844,7 @@ optimize: LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } ; @@ -8611,14 +8871,14 @@ rename: rename_list: user TO_SYM user { - if (Lex->users_list.push_back($1, thd->mem_root) || - Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root) || + Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } | rename_list ',' user TO_SYM user { - if (Lex->users_list.push_back($3, thd->mem_root) || - Lex->users_list.push_back($5, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root) || + Lex->users_list.push_back($5, thd->mem_root))) MYSQL_YYABORT; } ; @@ -8633,10 +8893,12 @@ table_to_table: { LEX *lex=Lex; SELECT_LEX *sl= lex->current_select; - if (!sl->add_table_to_list(thd, $1,NULL,TL_OPTION_UPDATING, - TL_IGNORE, MDL_EXCLUSIVE) || - !sl->add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING, - TL_IGNORE, MDL_EXCLUSIVE)) + if (unlikely(!sl->add_table_to_list(thd, $1,NULL, + TL_OPTION_UPDATING, + TL_IGNORE, MDL_EXCLUSIVE)) || + unlikely(!sl->add_table_to_list(thd, $4, NULL, + TL_OPTION_UPDATING, + TL_IGNORE, MDL_EXCLUSIVE))) MYSQL_YYABORT; } ; @@ -8667,9 +8929,10 @@ keycache_list: assign_to_keycache: table_ident cache_keys_spec { - if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8677,9 +8940,10 @@ assign_to_keycache: assign_to_keycache_parts: table_ident adm_partition cache_keys_spec { - if (!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8713,9 +8977,10 @@ preload_list: preload_keys: table_ident cache_keys_spec opt_ignore_leaves { - if (!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8723,9 +8988,10 @@ preload_keys: preload_keys_parts: table_ident adm_partition cache_keys_spec opt_ignore_leaves { - if (!Select->add_table_to_list(thd, $1, NULL, $4, TL_READ, - MDL_SHARED_READ, - Select->pop_index_hints())) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, $4, TL_READ, + MDL_SHARED_READ, + Select-> + pop_index_hints()))) MYSQL_YYABORT; } ; @@ -8774,6 +9040,9 @@ select: select_init: SELECT_SYM select_options_and_item_list select_init3 + | table_value_constructor + | table_value_constructor union_list + | table_value_constructor union_order_or_limit | '(' select_paren ')' | '(' select_paren ')' union_list | '(' select_paren ')' union_order_or_limit @@ -8781,6 +9050,9 @@ select_init: union_list_part2: SELECT_SYM select_options_and_item_list select_init3_union_query_term + | table_value_constructor + | table_value_constructor union_list + | table_value_constructor union_order_or_limit | '(' select_paren_union_query_term ')' | '(' select_paren_union_query_term ')' union_list | '(' select_paren_union_query_term ')' union_order_or_limit @@ -8788,6 +9060,14 @@ union_list_part2: select_paren: { + Lex->current_select->set_braces(true); + } + table_value_constructor + { + DBUG_ASSERT(Lex->current_select->braces); + } + | + { /* In order to correctly parse UNION's global ORDER BY we need to set braces before parsing the clause. @@ -8839,6 +9119,15 @@ select_paren_derived: { Lex->current_select->set_braces(true); } + table_value_constructor + { + DBUG_ASSERT(Lex->current_select->braces); + $$= Lex->current_select->master_unit()->first_select(); + } + | + { + Lex->current_select->set_braces(true); + } SELECT_SYM select_part2_derived opt_table_expression opt_order_clause @@ -8992,11 +9281,76 @@ select_options: /* empty*/ | select_option_list { - if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL) + if (unlikely((Select->options & SELECT_DISTINCT) && + (Select->options & SELECT_ALL))) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT")); } ; +opt_history_unit: + /* empty*/ %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE + { + $$= VERS_UNDEFINED; + } + | TRANSACTION_SYM + { + $$= VERS_TRX_ID; + } + | TIMESTAMP + { + $$= VERS_TIMESTAMP; + } + ; + +history_point: + TIMESTAMP TEXT_STRING + { + Item *item; + if (!(item= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, + MYSQL_TYPE_DATETIME, true))) + MYSQL_YYABORT; + $$= Vers_history_point(VERS_TIMESTAMP, item); + } + | function_call_keyword_timestamp + { + $$= Vers_history_point(VERS_TIMESTAMP, $1); + } + | opt_history_unit bit_expr + { + $$= Vers_history_point($1, $2); + } + ; + +opt_for_system_time_clause: + /* empty */ + { + $$= false; + } + | FOR_SYSTEM_TIME_SYM system_time_expr + { + $$= true; + } + ; + +system_time_expr: + AS OF_SYM history_point + { + Lex->vers_conditions.init(SYSTEM_TIME_AS_OF, $3); + } + | ALL + { + Lex->vers_conditions.init(SYSTEM_TIME_ALL); + } + | FROM history_point TO_SYM history_point + { + Lex->vers_conditions.init(SYSTEM_TIME_FROM_TO, $2, $4); + } + | BETWEEN_SYM history_point AND_SYM history_point + { + Lex->vers_conditions.init(SYSTEM_TIME_BETWEEN, $2, $4); + } + ; + select_option_list: select_option_list select_option | select_option @@ -9010,11 +9364,11 @@ select_option: Allow this flag only on the first top-level SELECT statement, if SQL_CACHE wasn't specified, and only once per query. */ - if (Lex->current_select != &Lex->select_lex) + if (unlikely(Lex->current_select != &Lex->select_lex)) my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE")); Lex->safe_to_cache_query=0; @@ -9027,11 +9381,11 @@ select_option: Allow this flag only on the first top-level SELECT statement, if SQL_NO_CACHE wasn't specified, and only once per query. */ - if (Lex->current_select != &Lex->select_lex) + if (unlikely(Lex->current_select != &Lex->select_lex)) my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE")); - if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE) + if (unlikely(Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE")); Lex->safe_to_cache_query=1; @@ -9067,30 +9421,30 @@ select_item_list: Item *item= new (thd->mem_root) Item_field(thd, &thd->lex->current_select->context, NULL, NULL, &star_clex_str); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; - if (add_item_to_list(thd, item)) + if (unlikely(add_item_to_list(thd, item))) MYSQL_YYABORT; (thd->lex->current_select->with_wild)++; } ; select_item: - remember_name table_wild remember_end + remember_name select_sublist_qualified_asterisk remember_end { - if (add_item_to_list(thd, $2)) + if (unlikely(add_item_to_list(thd, $2))) MYSQL_YYABORT; } | remember_name expr remember_end select_alias { DBUG_ASSERT($1 < $3); - if (add_item_to_list(thd, $2)) + if (unlikely(add_item_to_list(thd, $2))) MYSQL_YYABORT; if ($4.str) { - if (Lex->sql_command == SQLCOM_CREATE_VIEW && - check_column_name($4.str)) + if (unlikely(Lex->sql_command == SQLCOM_CREATE_VIEW && + check_column_name($4.str))) my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), $4.str)); $2->is_autogenerated_name= FALSE; $2->set_name(thd, $4.str, $4.length, system_charset_info); @@ -9210,7 +9564,7 @@ expr: { /* X OR Y */ $$= new (thd->mem_root) Item_cond_or(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } } @@ -9218,7 +9572,7 @@ expr: { /* XOR is a proprietary extension */ $$= new (thd->mem_root) Item_func_xor(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | expr and expr %prec AND_SYM @@ -9260,84 +9614,84 @@ expr: { /* X AND Y */ $$= new (thd->mem_root) Item_cond_and(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } } | NOT_SYM expr %prec NOT_SYM { $$= negate_expression(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_istrue(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnottrue(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isfalse(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotfalse(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bool_pri + | bool_pri %prec PREC_BELOW_NOT ; bool_pri: bool_pri IS NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri IS not NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM { $$= new (thd->mem_root) Item_func_equal(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bool_pri comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | predicate @@ -9347,22 +9701,22 @@ predicate: bit_expr IN_SYM '(' subselect ')' { $$= new (thd->mem_root) Item_in_subselect(thd, $1, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' subselect ')' { Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $5); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= negate_expression(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr IN_SYM '(' expr ')' { $$= handle_sql2003_note184_exception(thd, $1, true, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr IN_SYM '(' expr ',' expr_list ')' @@ -9370,13 +9724,13 @@ predicate: $6->push_front($4, thd->mem_root); $6->push_front($1, thd->mem_root); $$= new (thd->mem_root) Item_func_in(thd, *$6); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' expr ')' { $$= handle_sql2003_note184_exception(thd, $1, false, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' expr ',' expr_list ')' @@ -9384,21 +9738,21 @@ predicate: $7->push_front($5, thd->mem_root); $7->push_front($1, thd->mem_root); Item_func_in *item= new (thd->mem_root) Item_func_in(thd, *$7); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= item->neg_transformer(thd); } | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate { $$= new (thd->mem_root) Item_func_between(thd, $1, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate { Item_func_between *item; item= new (thd->mem_root) Item_func_between(thd, $1, $4, $6); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= item->neg_transformer(thd); } @@ -9406,125 +9760,151 @@ predicate: { Item *item1= new (thd->mem_root) Item_func_soundex(thd, $1); Item *item4= new (thd->mem_root) Item_func_soundex(thd, $4); - if ((item1 == NULL) || (item4 == NULL)) + if (unlikely(item1 == NULL) || unlikely(item4 == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_eq(thd, item1, item4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bit_expr LIKE simple_expr opt_escape + | bit_expr LIKE mysql_concatenation_expr opt_escape { $$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4, Lex->escape_used); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bit_expr not LIKE simple_expr opt_escape + | bit_expr not LIKE mysql_concatenation_expr opt_escape { Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5, Lex->escape_used); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= item->neg_transformer(thd); } | bit_expr REGEXP bit_expr { $$= new (thd->mem_root) Item_func_regex(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr not REGEXP bit_expr { Item *item= new (thd->mem_root) Item_func_regex(thd, $1, $4); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= negate_expression(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | bit_expr + | bit_expr %prec PREC_BELOW_NOT ; bit_expr: bit_expr '|' bit_expr %prec '|' { $$= new (thd->mem_root) Item_func_bit_or(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '&' bit_expr %prec '&' { $$= new (thd->mem_root) Item_func_bit_and(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT { $$= new (thd->mem_root) Item_func_shift_left(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT { $$= new (thd->mem_root) Item_func_shift_right(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | bit_expr ORACLE_CONCAT_SYM bit_expr + { + $$= new (thd->mem_root) Item_func_concat_operator_oracle(thd, + $1, $3); + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '+' bit_expr %prec '+' { $$= new (thd->mem_root) Item_func_plus(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '-' bit_expr %prec '-' { $$= new (thd->mem_root) Item_func_minus(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '+' INTERVAL_SYM expr interval %prec '+' { $$= new (thd->mem_root) Item_date_add_interval(thd, $1, $4, $5, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '-' INTERVAL_SYM expr interval %prec '-' { $$= new (thd->mem_root) Item_date_add_interval(thd, $1, $4, $5, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | INTERVAL_SYM expr interval '+' expr + /* we cannot put interval before - */ + { + $$= new (thd->mem_root) Item_date_add_interval(thd, $5, $2, $3, 0); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | '+' INTERVAL_SYM expr interval '+' expr %prec NEG + { + $$= new (thd->mem_root) Item_date_add_interval(thd, $6, $3, $4, 0); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | '-' INTERVAL_SYM expr interval '+' expr %prec NEG + { + $$= new (thd->mem_root) Item_date_add_interval(thd, $6, $3, $4, 1); + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '*' bit_expr %prec '*' { $$= new (thd->mem_root) Item_func_mul(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '/' bit_expr %prec '/' { $$= new (thd->mem_root) Item_func_div(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr DIV_SYM bit_expr %prec DIV_SYM { $$= new (thd->mem_root) Item_func_int_div(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr MOD_SYM bit_expr %prec MOD_SYM { $$= new (thd->mem_root) Item_func_mod(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | bit_expr '^' bit_expr { $$= new (thd->mem_root) Item_func_bit_xor(thd, $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | simple_expr + | mysql_concatenation_expr %prec '^' ; or: @@ -9611,7 +9991,7 @@ dyncall_create_element: LEX *lex= Lex; $$= (DYNCALL_CREATE_DEF *) alloc_root(thd->mem_root, sizeof(DYNCALL_CREATE_DEF)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->key= $1; $$->value= $3; @@ -9631,7 +10011,7 @@ dyncall_create_list: dyncall_create_element { $$= new (thd->mem_root) List<DYNCALL_CREATE_DEF>; - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->push_back($1, thd->mem_root); } @@ -9647,8 +10027,8 @@ sp_cursor_name_and_offset: { LEX *lex= Lex; $$.name= $1; - if (!lex->spcont || - !lex->spcont->find_cursor(&$1, &$$.offset, false)) + if (unlikely(!lex->spcont || + !lex->spcont->find_cursor(&$1, &$$.offset, false))) my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $1.str)); } ; @@ -9656,26 +10036,26 @@ sp_cursor_name_and_offset: explicit_cursor_attr: sp_cursor_name_and_offset '%' ISOPEN_SYM { - if (!($$= new (thd->mem_root) - Item_func_cursor_isopen(thd, &$1.name, $1.offset))) + if (unlikely(!($$= new (thd->mem_root) + Item_func_cursor_isopen(thd, &$1.name, $1.offset)))) MYSQL_YYABORT; } | sp_cursor_name_and_offset '%' FOUND_SYM { - if (!($$= new (thd->mem_root) - Item_func_cursor_found(thd, &$1.name, $1.offset))) + if (unlikely(!($$= new (thd->mem_root) + Item_func_cursor_found(thd, &$1.name, $1.offset)))) MYSQL_YYABORT; } | sp_cursor_name_and_offset '%' NOTFOUND_SYM { - if (!($$= new (thd->mem_root) - Item_func_cursor_notfound(thd, &$1.name, $1.offset))) + if (unlikely(!($$= new (thd->mem_root) + Item_func_cursor_notfound(thd, &$1.name, $1.offset)))) MYSQL_YYABORT; } | sp_cursor_name_and_offset '%' ROWCOUNT_SYM { - if (!($$= new (thd->mem_root) - Item_func_cursor_rowcount(thd, &$1.name, $1.offset))) + if (unlikely(!($$= new (thd->mem_root) + Item_func_cursor_rowcount(thd, &$1.name, $1.offset)))) MYSQL_YYABORT; } ; @@ -9735,18 +10115,18 @@ column_default_non_parenthesized_expr: { $5->push_front($3, thd->mem_root); $$= new (thd->mem_root) Item_row(thd, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | EXISTS '(' subselect ')' { $$= new (thd->mem_root) Item_exists_subselect(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | '{' ident expr '}' { - if (!($$= $3->make_odbc_literal(thd, &$2))) + if (unlikely(!($$= $3->make_odbc_literal(thd, &$2)))) MYSQL_YYABORT; } | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' @@ -9754,64 +10134,64 @@ column_default_non_parenthesized_expr: $2->push_front($5, thd->mem_root); Item_func_match *i1= new (thd->mem_root) Item_func_match(thd, *$2, $6); - if (i1 == NULL) + if (unlikely(i1 == NULL)) MYSQL_YYABORT; Select->add_ftfunc_to_list(thd, i1); $$= i1; } | CAST_SYM '(' expr AS cast_type ')' { - if (!($$= $5.create_typecast_item(thd, $3, Lex->charset))) + if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) MYSQL_YYABORT; } | CASE_SYM when_list_opt_else END { - if (!($$= new(thd->mem_root) Item_func_case_searched(thd, *$2))) + if (unlikely(!($$= new(thd->mem_root) Item_func_case_searched(thd, *$2)))) MYSQL_YYABORT; } | CASE_SYM expr when_list_opt_else END { $3->push_front($2, thd->mem_root); - if (!($$= new (thd->mem_root) Item_func_case_simple(thd, *$3))) + if (unlikely(!($$= new (thd->mem_root) Item_func_case_simple(thd, *$3)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr ',' cast_type ')' { - if (!($$= $5.create_typecast_item(thd, $3, Lex->charset))) + if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' { $$= new (thd->mem_root) Item_func_conv_charset(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATE_FORMAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DECODE_SYM '(' expr ',' decode_when_list ')' { $5->push_front($3, thd->mem_root); - if (!($$= new (thd->mem_root) Item_func_decode_oracle(thd, *$5))) + if (unlikely(!($$= new (thd->mem_root) Item_func_decode_oracle(thd, *$5)))) MYSQL_YYABORT; } | DEFAULT '(' simple_ident ')' { Item_splocal *il= $3->get_item_splocal(); - if (il) + if (unlikely(il)) my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str)); $$= new (thd->mem_root) Item_default_value(thd, Lex->current_context(), $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->default_used= TRUE; } @@ -9819,66 +10199,67 @@ column_default_non_parenthesized_expr: { $$= new (thd->mem_root) Item_insert_value(thd, Lex->current_context(), $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NEXT_SYM VALUE_SYM FOR_SYM table_ident { - if (!($$= Lex->create_item_func_nextval(thd, $4))) + if (unlikely(!($$= Lex->create_item_func_nextval(thd, $4)))) MYSQL_YYABORT; } | NEXTVAL_SYM '(' table_ident ')' { - if (!($$= Lex->create_item_func_nextval(thd, $3))) + if (unlikely(!($$= Lex->create_item_func_nextval(thd, $3)))) MYSQL_YYABORT; } | PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident { - if (!($$= Lex->create_item_func_lastval(thd, $4))) + if (unlikely(!($$= Lex->create_item_func_lastval(thd, $4)))) MYSQL_YYABORT; } | LASTVAL_SYM '(' table_ident ')' { - if (!($$= Lex->create_item_func_lastval(thd, $3))) + if (unlikely(!($$= Lex->create_item_func_lastval(thd, $3)))) MYSQL_YYABORT; } | SETVAL_SYM '(' table_ident ',' longlong_num ')' { - if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1))) + if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1)))) MYSQL_YYABORT; } | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ')' { - if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7))) + if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7)))) MYSQL_YYABORT; } | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ',' ulonglong_num ')' { - if (!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7))) + if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7)))) MYSQL_YYABORT; } ; -simple_expr: +primary_expr: column_default_non_parenthesized_expr | explicit_cursor_attr - | simple_expr COLLATE_SYM collation_name %prec NEG - { - if (!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3))) - MYSQL_YYABORT; - } | '(' parenthesized_expr ')' { $$= $2; } - | BINARY simple_expr %prec NEG + ; + +string_factor_expr: + primary_expr + | string_factor_expr COLLATE_SYM collation_name { - Type_cast_attributes at(&my_charset_bin); - if (!($$= type_handler_long_blob.create_typecast_item(thd, $2, at))) + if (unlikely(!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3)))) MYSQL_YYABORT; } - | simple_expr OR_OR_SYM simple_expr + ; + +simple_expr: + string_factor_expr %prec NEG + | BINARY simple_expr { - $$= new (thd->mem_root) Item_func_concat_operator_oracle(thd, - $1, $3); - if ($$ == NULL) + Type_cast_attributes at(&my_charset_bin); + if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at)))) MYSQL_YYABORT; } | '+' simple_expr %prec NEG @@ -9888,30 +10269,48 @@ simple_expr: | '-' simple_expr %prec NEG { $$= $2->neg(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | '~' simple_expr %prec NEG { $$= new (thd->mem_root) Item_func_bit_neg(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | not2 simple_expr %prec NEG { $$= negate_expression(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM - /* we cannot put interval before - */ + ; + +mysql_concatenation_expr: + simple_expr + | mysql_concatenation_expr MYSQL_CONCAT_SYM simple_expr { - $$= new (thd->mem_root) Item_date_add_interval(thd, $5, $2, $3, 0); - if ($$ == NULL) + $$= new (thd->mem_root) Item_func_concat(thd, $1, $3); + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; +function_call_keyword_timestamp: + TIMESTAMP '(' expr ')' + { + $$= new (thd->mem_root) Item_datetime_typecast(thd, $3, + AUTO_SEC_PART_DIGITS); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | TIMESTAMP '(' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_add_time(thd, $3, $5, 1, 0); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + ; /* Function call syntax using official SQL 2003 keywords. Because the function name is an official token, @@ -9922,20 +10321,20 @@ function_call_keyword: CHAR_SYM '(' expr_list ')' { $$= new (thd->mem_root) Item_func_char(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CHAR_SYM '(' expr_list USING charset_name ')' { $$= new (thd->mem_root) Item_func_char(thd, *$3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CURRENT_USER optional_braces { $$= new (thd->mem_root) Item_func_current_user(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -9944,7 +10343,7 @@ function_call_keyword: { $$= new (thd->mem_root) Item_func_current_role(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -9952,86 +10351,87 @@ function_call_keyword: | DATE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_date_typecast(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DAY_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_dayofmonth(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | HOUR_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_hour(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | INSERT '(' expr ',' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_insert(thd, $3, $5, $7, $9); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | INTERVAL_SYM '(' expr ',' expr ')' %prec INTERVAL_SYM + | INTERVAL_SYM '(' expr ',' expr ')' { List<Item> *list= new (thd->mem_root) List<Item>; - if (list == NULL) + if (unlikely(list == NULL)) + MYSQL_YYABORT; + if (unlikely(list->push_front($5, thd->mem_root)) || + unlikely(list->push_front($3, thd->mem_root))) MYSQL_YYABORT; - list->push_front($5, thd->mem_root); - list->push_front($3, thd->mem_root); Item_row *item= new (thd->mem_root) Item_row(thd, *list); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_interval(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' %prec INTERVAL_SYM + | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' { $7->push_front($5, thd->mem_root); $7->push_front($3, thd->mem_root); Item_row *item= new (thd->mem_root) Item_row(thd, *$7); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_interval(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LEFT '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_left(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MINUTE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_minute(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MONTH_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_month(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | RIGHT '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_right(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SECOND_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_second(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SQL_SYM '%' ROWCOUNT_SYM { $$= new (thd->mem_root) Item_func_oracle_sql_rowcount(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -10040,31 +10440,22 @@ function_call_keyword: { $$= new (thd->mem_root) Item_time_typecast(thd, $3, AUTO_SEC_PART_DIGITS); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | TIMESTAMP '(' expr ')' + | function_call_keyword_timestamp { - $$= new (thd->mem_root) Item_datetime_typecast(thd, $3, - AUTO_SEC_PART_DIGITS); - if ($$ == NULL) - MYSQL_YYABORT; - } - | TIMESTAMP '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_add_time(thd, $3, $5, 1, 0); - if ($$ == NULL) - MYSQL_YYABORT; + $$= $1; } | TRIM '(' trim_operands ')' { - if (!($$= $3.make_item_func_trim(thd))) + if (unlikely(!($$= $3.make_item_func_trim(thd)))) MYSQL_YYABORT; } | USER_SYM '(' ')' { $$= new (thd->mem_root) Item_func_user(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query=0; @@ -10072,7 +10463,7 @@ function_call_keyword: | YEAR_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_year(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -10094,99 +10485,97 @@ function_call_nonkeyword: { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $5, INTERVAL_DAY, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CURDATE optional_braces { $$= new (thd->mem_root) Item_func_curdate_local(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | CURTIME opt_time_precision { $$= new (thd->mem_root) Item_func_curtime_local(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')' - %prec INTERVAL_SYM { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')' - %prec INTERVAL_SYM { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | GET_FORMAT '(' date_time_type ',' expr ')' { $$= new (thd->mem_root) Item_func_get_format(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NOW_SYM opt_time_precision { $$= new (thd->mem_root) Item_func_now_local(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | POSITION_SYM '(' bit_expr IN_SYM expr ')' { $$= new (thd->mem_root) Item_func_locate(thd, $5, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUBDATE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $5, INTERVAL_DAY, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $3, $6, $7, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUBSTRING '(' expr ',' expr ',' expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5, $7))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7)))) MYSQL_YYABORT; } | SUBSTRING '(' expr ',' expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5)))) MYSQL_YYABORT; } | SUBSTRING '(' expr FROM expr FOR_SYM expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5, $7))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5, $7)))) MYSQL_YYABORT; } | SUBSTRING '(' expr FROM expr ')' { - if (!($$= Lex->make_item_func_substr(thd, $3, $5))) + if (unlikely(!($$= Lex->make_item_func_substr(thd, $3, $5)))) MYSQL_YYABORT; } | SYSDATE opt_time_precision @@ -10203,45 +10592,45 @@ function_call_nonkeyword: $$= new (thd->mem_root) Item_func_sysdate_local(thd, $2); else $$= new (thd->mem_root) Item_func_now_local(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_date_add_interval(thd, $7, $5, $3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_timestamp_diff(thd, $5, $7, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TRIM_ORACLE '(' trim_operands ')' { - if (!($$= $3.make_item_func_trim_oracle(thd))) + if (unlikely(!($$= $3.make_item_func_trim_oracle(thd)))) MYSQL_YYABORT; } | UTC_DATE_SYM optional_braces { $$= new (thd->mem_root) Item_func_curdate_utc(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | UTC_TIME_SYM opt_time_precision { $$= new (thd->mem_root) Item_func_curtime_utc(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | UTC_TIMESTAMP_SYM opt_time_precision { $$= new (thd->mem_root) Item_func_now_utc(thd, $2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } @@ -10249,28 +10638,28 @@ function_call_nonkeyword: COLUMN_ADD_SYM '(' expr ',' dyncall_create_list ')' { $$= create_func_dyncol_add(thd, $3, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLUMN_DELETE_SYM '(' expr ',' expr_list ')' { $$= create_func_dyncol_delete(thd, $3, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLUMN_CHECK_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_dyncol_check(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLUMN_CREATE_SYM '(' dyncall_create_list ')' { $$= create_func_dyncol_create(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | @@ -10280,7 +10669,7 @@ function_call_nonkeyword: $$= create_func_dyncol_get(thd, $3, $5, $7.type_handler(), $7.length(), $7.dec(), lex->charset); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -10294,50 +10683,50 @@ function_call_conflict: ASCII_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_ascii(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CHARSET '(' expr ')' { $$= new (thd->mem_root) Item_func_charset(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COALESCE '(' expr_list ')' { $$= new (thd->mem_root) Item_func_coalesce(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COLLATION_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_collation(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DATABASE '(' ')' { $$= new (thd->mem_root) Item_func_database(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->safe_to_cache_query=0; } | IF_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_if(thd, $3, $5, $7); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | FORMAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_format(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | FORMAT_SYM '(' expr ',' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_format(thd, $3, $5, $7); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } /* LAST_VALUE here conflicts with the definition for window functions. @@ -10346,75 +10735,75 @@ function_call_conflict: | LAST_VALUE '(' expr ')' { List<Item> *list= new (thd->mem_root) List<Item>; - if (list == NULL) + if (unlikely(list == NULL)) MYSQL_YYABORT; list->push_back($3, thd->mem_root); $$= new (thd->mem_root) Item_func_last_value(thd, *list); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LAST_VALUE '(' expr_list ',' expr ')' { $3->push_back($5, thd->mem_root); $$= new (thd->mem_root) Item_func_last_value(thd, *$3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MICROSECOND_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_microsecond(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MOD_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_mod(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | OLD_PASSWORD_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_password(thd, $3, Item_func_password::OLD); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | PASSWORD_SYM '(' expr ')' { Item* i1; i1= new (thd->mem_root) Item_func_password(thd, $3); - if (i1 == NULL) + if (unlikely(i1 == NULL)) MYSQL_YYABORT; $$= i1; } | QUARTER_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_quarter(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | REPEAT_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_repeat(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | REPLACE '(' expr ',' expr ',' expr ')' { - if (!($$= Lex->make_item_func_replace(thd, $3, $5, $7))) + if (unlikely(!($$= Lex->make_item_func_replace(thd, $3, $5, $7)))) MYSQL_YYABORT; } | REVERSE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_reverse(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ROW_COUNT_SYM '(' ')' { $$= new (thd->mem_root) Item_func_row_count(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); Lex->safe_to_cache_query= 0; @@ -10422,25 +10811,25 @@ function_call_conflict: | TRUNCATE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_round(thd, $3, $5, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEEK_SYM '(' expr ')' { $$= new (thd->mem_root) Item_func_week(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEEK_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_week(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr opt_ws_levels ')' { $$= new (thd->mem_root) Item_func_weight_string(thd, $3, 0, 0, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr AS CHAR_SYM ws_nweights opt_ws_levels ')' @@ -10448,26 +10837,26 @@ function_call_conflict: $$= new (thd->mem_root) Item_func_weight_string(thd, $3, 0, $6, $7 | MY_STRXFRM_PAD_WITH_SPACE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr AS BINARY ws_nweights ')' { Item *item= new (thd->mem_root) Item_char_typecast(thd, $3, $6, &my_charset_bin); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_func_weight_string(thd, item, 0, $6, MY_STRXFRM_PAD_WITH_SPACE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | WEIGHT_STRING_SYM '(' expr ',' ulong_num ',' ulong_num ',' ulong_num ')' { $$= new (thd->mem_root) Item_func_weight_string(thd, $3, $5, $7, $9); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | geometry_function @@ -10475,7 +10864,7 @@ function_call_conflict: #ifdef HAVE_SPATIAL $$= $1; /* $1 may be NULL, GEOM_NEW not tested for out of memory */ - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; #else my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, @@ -10537,6 +10926,11 @@ geometry_function: Geometry::wkb_polygon, Geometry::wkb_linestring)); } + | WITHIN '(' expr ',' expr ')' + { + $$= GEOM_NEW(thd, Item_func_spatial_precise_rel(thd, $3, $5, + Item_func::SP_WITHIN_FUNC)); + } ; /* @@ -10558,7 +10952,7 @@ function_call_generic: (udf= find_udf($1.str, $1.length)) && udf->type == UDFTYPE_AGGREGATE) { - if (lex->current_select->inc_in_sum_expr()) + if (unlikely(lex->current_select->inc_in_sum_expr())) { thd->parse_error(); MYSQL_YYABORT; @@ -10573,10 +10967,8 @@ function_call_generic: Create_func *builder; Item *item= NULL; - if (check_routine_name(&$1)) - { + if (unlikely(check_routine_name(&$1))) MYSQL_YYABORT; - } /* Implementation note: @@ -10616,45 +11008,13 @@ function_call_generic: } } - if (! ($$= item)) - { + if (unlikely(! ($$= item))) MYSQL_YYABORT; - } } - | ident '.' ident '(' opt_expr_list ')' + | ident_cli '.' ident_cli '(' opt_expr_list ')' { - Create_qfunc *builder; - Item *item= NULL; - - /* - The following in practice calls: - <code>Create_sp_func::create()</code> - and builds a stored function. - - However, it's important to maintain the interface between the - parser and the implementation in item_create.cc clean, - since this will change with WL#2128 (SQL PATH): - - INFORMATION_SCHEMA.version() is the SQL 99 syntax for the native - function version(), - - MySQL.version() is the SQL 2003 syntax for the native function - version() (a vendor can specify any schema). - */ - - if (!$1.str || check_db_name((LEX_STRING*) &$1)) - my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); - if (check_routine_name(&$3)) - { + if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5)))) MYSQL_YYABORT; - } - - builder= find_qualified_function_builder(thd); - DBUG_ASSERT(builder); - item= builder->create_with_db(thd, &$1, &$3, true, $5); - - if (! ($$= item)) - { - MYSQL_YYABORT; - } } ; @@ -10684,7 +11044,7 @@ udf_expr_list: udf_expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; $$->push_back($1, thd->mem_root); } @@ -10726,46 +11086,46 @@ sum_expr: AVG_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_avg(thd, $3, FALSE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | AVG_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_avg(thd, $4, TRUE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIT_AND '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_and(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIT_OR '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_or(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIT_XOR '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_xor(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COUNT_SYM '(' opt_all '*' ')' { Item *item= new (thd->mem_root) Item_int(thd, (int32) 0L, 1); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_count(thd, item); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COUNT_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_count(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | COUNT_SYM '(' DISTINCT @@ -10775,13 +11135,13 @@ sum_expr: ')' { $$= new (thd->mem_root) Item_sum_count(thd, *$5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MIN_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_min(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } /* @@ -10792,55 +11152,55 @@ sum_expr: | MIN_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_min(thd, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MAX_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_max(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | MAX_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_max(thd, $4); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | STD_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_std(thd, $3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | VARIANCE_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_variance(thd, $3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | STDDEV_SAMP_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_std(thd, $3, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | VAR_SAMP_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_variance(thd, $3, 1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUM_SYM '(' in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_sum(thd, $3, FALSE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SUM_SYM '(' DISTINCT in_sum_expr ')' { $$= new (thd->mem_root) Item_sum_sum(thd, $4, TRUE); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | GROUP_CONCAT_SYM '(' opt_distinct @@ -10857,7 +11217,7 @@ sum_expr: sel->gorder_list, $7, $8, sel->select_limit, sel->offset_limit); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; sel->select_limit= NULL; sel->offset_limit= NULL; @@ -10871,25 +11231,25 @@ window_func_expr: window_func OVER_SYM window_name { $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; - if (Select->add_window_func((Item_window_func *) $$)) + if (unlikely(Select->add_window_func((Item_window_func *) $$))) MYSQL_YYABORT; } | window_func OVER_SYM window_spec { LEX *lex= Lex; - if (Select->add_window_spec(thd, lex->win_ref, - Select->group_list, - Select->order_list, - lex->win_frame)) + if (unlikely(Select->add_window_spec(thd, lex->win_ref, + Select->group_list, + Select->order_list, + lex->win_frame))) MYSQL_YYABORT; $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, thd->lex->win_spec); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; - if (Select->add_window_func((Item_window_func *) $$)) + if (unlikely(Select->add_window_func((Item_window_func *) $$))) MYSQL_YYABORT; } ; @@ -10907,63 +11267,63 @@ simple_window_func: ROW_NUMBER_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_row_number(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | RANK_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_rank(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DENSE_RANK_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_dense_rank(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | PERCENT_RANK_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_percent_rank(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CUME_DIST_SYM '(' ')' { $$= new (thd->mem_root) Item_sum_cume_dist(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NTILE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_ntile(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | FIRST_VALUE_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_first_value(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LAST_VALUE '(' expr ')' { $$= new (thd->mem_root) Item_sum_last_value(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NTH_VALUE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_sum_nth_value(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | @@ -10971,17 +11331,17 @@ simple_window_func: { /* No second argument defaults to 1. */ Item* item_offset= new (thd->mem_root) Item_uint(thd, 1); - if (item_offset == NULL) + if (unlikely(item_offset == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_lead(thd, $3, item_offset); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LEAD_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_sum_lead(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | @@ -10989,35 +11349,38 @@ simple_window_func: { /* No second argument defaults to 1. */ Item* item_offset= new (thd->mem_root) Item_uint(thd, 1); - if (item_offset == NULL) + if (unlikely(item_offset == NULL)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_lag(thd, $3, item_offset); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LAG_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_sum_lag(thd, $3, $5); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; + + + inverse_distribution_function: percentile_function OVER_SYM '(' opt_window_partition_clause ')' { LEX *lex= Lex; - if (Select->add_window_spec(thd, lex->win_ref, - Select->group_list, - Select->order_list, - NULL)) + if (unlikely(Select->add_window_spec(thd, lex->win_ref, + Select->group_list, + Select->order_list, + NULL))) MYSQL_YYABORT; $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, thd->lex->win_spec); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; - if (Select->add_window_func((Item_window_func *) $$)) + if (unlikely(Select->add_window_func((Item_window_func *) $$))) MYSQL_YYABORT; } ; @@ -11033,14 +11396,14 @@ percentile_function: { Item *args= new (thd->mem_root) Item_decimal(thd, "0.5", 3, thd->charset()); - if (($$ == NULL) || (thd->is_error())) - { + if (unlikely(args == NULL) || unlikely(thd->is_error())) + MYSQL_YYABORT; + Select->prepare_add_window_spec(thd); + if (unlikely(add_order_to_list(thd, $3,FALSE))) MYSQL_YYABORT; - } - if (add_order_to_list(thd, $3,FALSE)) MYSQL_YYABORT; $$= new (thd->mem_root) Item_sum_percentile_cont(thd, args); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -11049,27 +11412,31 @@ inverse_distribution_function_def: PERCENTILE_CONT_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_percentile_cont(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | PERCENTILE_DISC_SYM '(' expr ')' { $$= new (thd->mem_root) Item_sum_percentile_disc(thd, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; order_by_single_element_list: ORDER_SYM BY order_ident order_dir - { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_order_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } ; + window_name: ident { $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -11077,7 +11444,7 @@ window_name: variable: '@' { - if (! Lex->parsing_options.allows_variable) + if (unlikely(! Lex->parsing_options.allows_variable)) my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0))); } variable_aux @@ -11091,7 +11458,7 @@ variable_aux: { Item_func_set_user_var *item; $$= item= new (thd->mem_root) Item_func_set_user_var(thd, &$1, $3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); @@ -11100,23 +11467,20 @@ variable_aux: | ident_or_text { $$= new (thd->mem_root) Item_func_get_user_var(thd, &$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); } - | '@' opt_var_ident_type ident_or_text opt_component + | '@' opt_var_ident_type ident_sysvar_name { - /* disallow "SELECT @@global.global.variable" */ - if ($3.str && $4.str && check_reserved_words(&$3)) - { - thd->parse_error(); + if (unlikely(!($$= Lex->make_item_sysvar(thd, $2, &$3)))) MYSQL_YYABORT; - } - if (!($$= get_system_var(thd, $2, &$3, &$4))) + } + | '@' opt_var_ident_type ident_sysvar_name '.' ident + { + if (unlikely(!($$= Lex->make_item_sysvar(thd, $2, &$3, &$5)))) MYSQL_YYABORT; - if (!((Item_func_get_system_var*) $$)->is_written_to_binlog()) - Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE); } ; @@ -11129,7 +11493,7 @@ opt_gconcat_separator: /* empty */ { $$= new (thd->mem_root) String(",", 1, &my_charset_latin1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | SEPARATOR_SYM text_string { $$ = $2; } @@ -11142,9 +11506,15 @@ opt_gorder_clause: gorder_list: gorder_list ',' order_ident order_dir - { if (add_gorder_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_gorder_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_gorder_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + if (unlikely(add_gorder_to_list(thd, $1,(bool) $2))) + MYSQL_YYABORT; + } ; opt_glimit_clause: @@ -11187,11 +11557,13 @@ glimit_options: } ; + + in_sum_expr: opt_all { LEX *lex= Lex; - if (lex->current_select->inc_in_sum_expr()) + if (unlikely(lex->current_select->inc_in_sum_expr())) { thd->parse_error(); MYSQL_YYABORT; @@ -11253,9 +11625,9 @@ expr_list: expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); } | expr_list ',' expr { @@ -11273,9 +11645,9 @@ ident_list: simple_ident { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); } | ident_list ',' simple_ident { @@ -11288,25 +11660,27 @@ when_list: WHEN_SYM expr THEN_SYM expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + if (unlikely($$->push_back($2, thd->mem_root) || + $$->push_back($4, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($2, thd->mem_root); - $$->push_back($4, thd->mem_root); } | when_list WHEN_SYM expr THEN_SYM expr { - $1->push_back($3, thd->mem_root); - $1->push_back($5, thd->mem_root); + if (unlikely($1->push_back($3, thd->mem_root) || + $1->push_back($5, thd->mem_root))) + MYSQL_YYABORT; $$= $1; } ; - when_list_opt_else: when_list | when_list ELSE expr { - $1->push_back($3, thd->mem_root); + if (unlikely($1->push_back($3, thd->mem_root))) + MYSQL_YYABORT; $$= $1; } ; @@ -11315,15 +11689,17 @@ decode_when_list: expr ',' expr { $$= new (thd->mem_root) List<Item>; - if ($$ == NULL) + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root)) || + unlikely($$->push_back($3, thd->mem_root))) MYSQL_YYABORT; - $$->push_back($1, thd->mem_root); - $$->push_back($3, thd->mem_root); + } | decode_when_list ',' expr { $$= $1; - $$->push_back($3, thd->mem_root); + if (unlikely($$->push_back($3, thd->mem_root))) + MYSQL_YYABORT; } ; @@ -11335,7 +11711,7 @@ table_ref: | join_table { LEX *lex= Lex; - if (!($$= lex->current_select->nest_last_join(thd))) + if (unlikely(!($$= lex->current_select->nest_last_join(thd)))) { thd->parse_error(); MYSQL_YYABORT; @@ -11390,7 +11766,7 @@ join_table: { MYSQL_YYABORT_UNLESS($1 && $3); /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(thd, $1, $3)) + if (unlikely(push_new_name_resolution_context(thd, $1, $3))) MYSQL_YYABORT; Select->parsing_place= IN_ON; } @@ -11407,7 +11783,7 @@ join_table: MYSQL_YYABORT_UNLESS($1 && $3); } '(' using_list ')' - { + { $3->straight=$2; add_join_natural($1,$3,$7,Select); $$=$3; @@ -11425,7 +11801,7 @@ join_table: { MYSQL_YYABORT_UNLESS($1 && $5); /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(thd, $1, $5)) + if (unlikely(push_new_name_resolution_context(thd, $1, $5))) MYSQL_YYABORT; Select->parsing_place= IN_ON; } @@ -11461,14 +11837,14 @@ join_table: { MYSQL_YYABORT_UNLESS($1 && $5); /* Change the current name resolution context to a local context. */ - if (push_new_name_resolution_context(thd, $1, $5)) + if (unlikely(push_new_name_resolution_context(thd, $1, $5))) MYSQL_YYABORT; Select->parsing_place= IN_ON; } expr { LEX *lex= Lex; - if (!($$= lex->current_select->convert_right_join())) + if (unlikely(!($$= lex->current_select->convert_right_join()))) MYSQL_YYABORT; add_join_on(thd, $$, $8); Lex->pop_context(); @@ -11481,7 +11857,7 @@ join_table: USING '(' using_list ')' { LEX *lex= Lex; - if (!($$= lex->current_select->convert_right_join())) + if (unlikely(!($$= lex->current_select->convert_right_join()))) MYSQL_YYABORT; add_join_natural($$,$5,$9,Select); } @@ -11490,7 +11866,7 @@ join_table: MYSQL_YYABORT_UNLESS($1 && $6); add_join_natural($6,$1,NULL,Select); LEX *lex= Lex; - if (!($$= lex->current_select->convert_right_join())) + if (unlikely(!($$= lex->current_select->convert_right_join()))) MYSQL_YYABORT; } ; @@ -11538,19 +11914,23 @@ table_factor: table_primary_ident: { + DBUG_ASSERT(Select); SELECT_LEX *sel= Select; sel->table_join_options= 0; } - table_ident opt_use_partition opt_table_alias opt_key_definition + table_ident opt_use_partition opt_for_system_time_clause opt_table_alias opt_key_definition { - if (!($$= Select->add_table_to_list(thd, $2, $4, - Select->get_table_join_options(), - YYPS->m_lock_type, - YYPS->m_mdl_type, - Select->pop_index_hints(), - $3))) + if (unlikely(!($$= Select->add_table_to_list(thd, $2, $5, + Select->get_table_join_options(), + YYPS->m_lock_type, + YYPS->m_mdl_type, + Select-> + pop_index_hints(), + $3)))) MYSQL_YYABORT; Select->add_joined_table($$); + if ($4) + $$->vers_conditions= Lex->vers_conditions; } ; @@ -11573,11 +11953,11 @@ table_primary_ident: */ table_primary_derived: - '(' get_select_lex select_derived_union ')' opt_table_alias + '(' get_select_lex select_derived_union ')' opt_for_system_time_clause opt_table_alias { /* Use $2 instead of Lex->current_select as derived table will alter value of Lex->current_select. */ - if (!($3 || $5) && $2->embedding && + if (!($3 || $6) && $2->embedding && !$2->embedding->nested_join->join_list.elements) { /* we have a derived table ($3 == NULL) but no alias, @@ -11597,18 +11977,18 @@ table_primary_derived: SELECT_LEX_UNIT *unit= sel->master_unit(); lex->current_select= sel= unit->outer_select(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; - if (!($$= sel->add_table_to_list(thd, - ti, $5, 0, - TL_READ, MDL_SHARED_READ))) - + if (unlikely(!($$= sel->add_table_to_list(thd, + ti, $6, 0, + TL_READ, + MDL_SHARED_READ)))) MYSQL_YYABORT; sel->add_joined_table($$); lex->pop_context(); lex->nest_level--; } - else if ($5 != NULL) + else if (unlikely($6 != NULL)) { /* Tables with or without joins within parentheses cannot @@ -11632,25 +12012,33 @@ table_primary_derived: if ($$ && $$->derived && !$$->derived->first_select()->next_select()) $$->select_lex->add_where_field($$->derived->first_select()); + if ($5) + { + MYSQL_YYABORT_UNLESS(!$3); + $$->vers_conditions= Lex->vers_conditions; + } } /* Represents derived table with WITH clause */ | '(' get_select_lex subselect_start with_clause query_expression_body - subselect_end ')' opt_table_alias + subselect_end ')' opt_for_system_time_clause opt_table_alias { LEX *lex=Lex; SELECT_LEX *sel= $2; SELECT_LEX_UNIT *unit= $5->master_unit(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; $5->set_with_clause($4); lex->current_select= sel; - if (!($$= sel->add_table_to_list(lex->thd, - ti, $8, 0, - TL_READ, MDL_SHARED_READ))) + if (unlikely(!($$= sel->add_table_to_list(lex->thd, + ti, $9, 0, + TL_READ, + MDL_SHARED_READ)))) MYSQL_YYABORT; sel->add_joined_table($$); + if ($8) + $$->vers_conditions= Lex->vers_conditions; } ; @@ -11677,7 +12065,7 @@ select_derived_union: select_derived | select_derived union_order_or_limit { - if ($1) + if (unlikely($1)) { thd->parse_error(); MYSQL_YYABORT; @@ -11685,16 +12073,16 @@ select_derived_union: } | select_derived union_head_non_top { - if ($1) + if (unlikely($1)) { thd->parse_error(); MYSQL_YYABORT; } } union_list_derived_part2 - | derived_query_specification opt_select_lock_type - | derived_query_specification order_or_limit opt_select_lock_type - | derived_query_specification opt_select_lock_type union_list_derived + | derived_simple_table opt_select_lock_type + | derived_simple_table order_or_limit opt_select_lock_type + | derived_simple_table opt_select_lock_type union_list_derived ; union_list_derived_part2: @@ -11739,9 +12127,9 @@ select_derived: /* for normal joins, $2 != NULL and end_nested_join() != NULL, for derived tables, both must equal NULL */ - if (!($$= $1->end_nested_join(lex->thd)) && $2) + if (unlikely(!($$= $1->end_nested_join(lex->thd)) && $2)) MYSQL_YYABORT; - if (!$2 && $$) + if (unlikely(!$2 && $$)) { thd->parse_error(); MYSQL_YYABORT; @@ -11749,6 +12137,10 @@ select_derived: } ; +derived_simple_table: + derived_query_specification { $$= $1; } + | derived_table_value_constructor { $$= $1; } + ; /* Similar to query_specification, but for derived tables. Example: the inner parenthesized SELECT in this query: @@ -11763,18 +12155,32 @@ derived_query_specification: } ; +derived_table_value_constructor: + VALUES + { + Lex->tvc_start(); + } + values_list + { + if (Lex->tvc_finalize_derived()) + MYSQL_YYABORT; + $$= NULL; + } + ; + + select_derived2: { LEX *lex= Lex; lex->derived_tables|= DERIVED_SUBQUERY; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) + if (unlikely(!lex->expr_allows_subselect || + lex->sql_command == (int)SQLCOM_PURGE)) { thd->parse_error(); MYSQL_YYABORT; } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || - mysql_new_select(lex, 1, NULL)) + unlikely(mysql_new_select(lex, 1, NULL))) MYSQL_YYABORT; mysql_init_select(lex); lex->current_select->linkage= DERIVED_TABLE_TYPE; @@ -11795,7 +12201,7 @@ get_select_lex_derived: get_select_lex { LEX *lex= Lex; - if ($1->init_nested_join(lex->thd)) + if (unlikely($1->init_nested_join(lex->thd))) MYSQL_YYABORT; } ; @@ -11879,12 +12285,12 @@ key_usage_list: using_list: ident { - if (!($$= new (thd->mem_root) List<String>)) + if (unlikely(!($$= new (thd->mem_root) List<String>))) MYSQL_YYABORT; String *s= new (thd->mem_root) String((const char *) $1.str, $1.length, system_charset_info); - if (s == NULL) + if (unlikely(unlikely(s == NULL))) MYSQL_YYABORT; $$->push_back(s, thd->mem_root); } @@ -11893,9 +12299,10 @@ using_list: String *s= new (thd->mem_root) String((const char *) $3.str, $3.length, system_charset_info); - if (s == NULL) + if (unlikely(unlikely(s == NULL))) + MYSQL_YYABORT; + if (unlikely($1->push_back(s, thd->mem_root))) MYSQL_YYABORT; - $1->push_back(s, thd->mem_root); $$= $1; } ; @@ -11942,10 +12349,10 @@ table_alias: opt_table_alias: /* empty */ { $$=0; } - | table_alias ident + | table_alias ident_table_alias { $$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -11999,7 +12406,7 @@ opt_escape: $$= ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ? new (thd->mem_root) Item_string_ascii(thd, "", 0) : new (thd->mem_root) Item_string_ascii(thd, "\\", 1)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12015,9 +12422,15 @@ opt_group_clause: group_list: group_list ',' order_ident order_dir - { if (add_group_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_group_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_group_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + if (unlikely(add_group_to_list(thd, $1,(bool) $2))) + MYSQL_YYABORT; + } ; olap_opt: @@ -12032,7 +12445,7 @@ olap_opt: SQL-2003: GROUP BY ... CUBE(col1, col2, col3) */ LEX *lex=Lex; - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + if (unlikely(lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "WITH CUBE", "global union parameters")); lex->current_select->olap= CUBE_TYPE; @@ -12049,7 +12462,7 @@ olap_opt: SQL-2003: GROUP BY ... ROLLUP(col1, col2, col3) */ LEX *lex= Lex; - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + if (unlikely(lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "WITH ROLLUP", "global union parameters")); lex->current_select->olap= ROLLUP_TYPE; @@ -12077,10 +12490,10 @@ window_def: window_name AS window_spec { LEX *lex= Lex; - if (Select->add_window_def(thd, $1, lex->win_ref, - Select->group_list, - Select->order_list, - lex->win_frame)) + if (unlikely(Select->add_window_def(thd, $1, lex->win_ref, + Select->group_list, + Select->order_list, + lex->win_frame))) MYSQL_YYABORT; } ; @@ -12098,7 +12511,7 @@ opt_window_ref: | ident { thd->lex->win_ref= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - if (thd->lex->win_ref == NULL) + if (unlikely(thd->lex->win_ref == NULL)) MYSQL_YYABORT; } @@ -12122,7 +12535,7 @@ opt_window_frame_clause: lex->frame_top_bound, lex->frame_bottom_bound, $3); - if (lex->win_frame == NULL) + if (unlikely(lex->win_frame == NULL)) MYSQL_YYABORT; } ; @@ -12140,7 +12553,7 @@ window_frame_extent: lex->frame_bottom_bound= new (thd->mem_root) Window_frame_bound(Window_frame_bound::CURRENT, NULL); - if (lex->frame_bottom_bound == NULL) + if (unlikely(lex->frame_bottom_bound == NULL)) MYSQL_YYABORT; } | BETWEEN_SYM window_frame_bound AND_SYM window_frame_bound @@ -12156,21 +12569,21 @@ window_frame_start: { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::PRECEDING, NULL); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | CURRENT_SYM ROW_SYM { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::CURRENT, NULL); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | literal PRECEDING_SYM { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::PRECEDING, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12181,14 +12594,14 @@ window_frame_bound: { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::FOLLOWING, NULL); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | literal FOLLOWING_SYM { $$= new (thd->mem_root) Window_frame_bound(Window_frame_bound::FOLLOWING, $1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12222,7 +12635,7 @@ alter_order_item: simple_ident_nospvar order_dir { bool ascending= ($2 == 1) ? true : false; - if (add_order_to_list(thd, $1, ascending)) + if (unlikely(add_order_to_list(thd, $1, ascending))) MYSQL_YYABORT; } ; @@ -12242,9 +12655,9 @@ order_clause: LEX *lex=Lex; SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel-> master_unit(); - if (sel->linkage != GLOBAL_OPTIONS_TYPE && - sel->olap != UNSPECIFIED_OLAP_TYPE && - (sel->linkage != UNION_TYPE || sel->braces)) + if (unlikely(sel->linkage != GLOBAL_OPTIONS_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE && + (sel->linkage != UNION_TYPE || sel->braces))) { my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY"); @@ -12258,14 +12671,14 @@ order_clause: executed in the same way as the query SELECT ... ORDER BY order_list unless the SELECT construct contains ORDER BY or LIMIT clauses. - Otherwise we create a fake SELECT_LEX if it has not been created - yet. + Otherwise we create a fake SELECT_LEX if it has not been + created yet. */ SELECT_LEX *first_sl= unit->first_select(); - if (!unit->is_unit_op() && - (first_sl->order_list.elements || - first_sl->select_limit) && - unit->add_fake_select_lex(thd)) + if (unlikely(!unit->is_unit_op() && + (first_sl->order_list.elements || + first_sl->select_limit) && + unit->add_fake_select_lex(thd))) MYSQL_YYABORT; } if (sel->master_unit()->is_unit_op() && !sel->braces) @@ -12288,9 +12701,15 @@ order_clause: order_list: order_list ',' order_ident order_dir - { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; } + { + if (unlikely(add_order_to_list(thd, $3,(bool) $4))) + MYSQL_YYABORT; + } | order_ident order_dir - { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; } + { + if (unlikely(add_order_to_list(thd, $1,(bool) $2))) + MYSQL_YYABORT; + } ; order_dir: @@ -12361,42 +12780,36 @@ limit_options: ; limit_option: - ident_with_tok_start - { - LEX *lex= thd->lex; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; - if (!($$= lex->create_item_limit(thd, &$1, - $1.m_pos, lip->get_tok_end()))) - MYSQL_YYABORT; - } - | ident_with_tok_start '.' ident - { - LEX *lex= thd->lex; - Lex_input_stream *lip= & thd->m_parser_state->m_lip; - if (!($$= lex->create_item_limit(thd, &$1, &$3, - $1.m_pos, lip->get_ptr()))) - MYSQL_YYABORT; - } + ident_cli + { + if (unlikely(!($$= Lex->create_item_limit(thd, &$1)))) + MYSQL_YYABORT; + } + | ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->create_item_limit(thd, &$1, &$3)))) + MYSQL_YYABORT; + } | param_marker - { - $1->limit_clause_param= TRUE; - } + { + $1->limit_clause_param= TRUE; + } | ULONGLONG_NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LONG_NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -12508,9 +12921,9 @@ procedure_clause: Item_field *item= new (thd->mem_root) Item_field(thd, &lex->current_select->context, NULL, NULL, &$2); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; - if (add_proc_to_list(thd, item)) + if (unlikely(add_proc_to_list(thd, item))) MYSQL_YYABORT; Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); @@ -12542,7 +12955,7 @@ procedure_list2: procedure_item: remember_name expr remember_end { - if (add_proc_to_list(thd, $2)) + if (unlikely(add_proc_to_list(thd, $2))) MYSQL_YYABORT; if (!$2->name.str || $2->name.str == item_empty_name) $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); @@ -12553,7 +12966,8 @@ select_var_list_init: { LEX *lex=Lex; if (!lex->describe && - (!(lex->result= new (thd->mem_root) select_dumpvar(thd)))) + unlikely((!(lex->result= new (thd->mem_root) + select_dumpvar(thd))))) MYSQL_YYABORT; } select_var_list @@ -12569,7 +12983,7 @@ select_var_ident: select_outvar { if (Lex->result) { - if ($1 == NULL) + if (unlikely($1 == NULL)) MYSQL_YYABORT; ((select_dumpvar *)Lex->result)->var_list.push_back($1, thd->mem_root); } @@ -12591,12 +13005,12 @@ select_outvar: } | ident_or_text { - if (!($$= Lex->create_outvar(thd, &$1)) && Lex->result) + if (unlikely(!($$= Lex->create_outvar(thd, &$1)) && Lex->result)) MYSQL_YYABORT; } | ident '.' ident { - if (!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result) + if (unlikely(!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result)) MYSQL_YYABORT; } ; @@ -12610,10 +13024,11 @@ into_destination: { LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - if (!(lex->exchange= - new (thd->mem_root) sql_exchange($2.str, 0)) || - !(lex->result= - new (thd->mem_root) select_export(thd, lex->exchange))) + if (unlikely(!(lex->exchange= + new (thd->mem_root) sql_exchange($2.str, 0))) || + unlikely(!(lex->result= + new (thd->mem_root) + select_export(thd, lex->exchange)))) MYSQL_YYABORT; } opt_load_data_charset @@ -12625,10 +13040,12 @@ into_destination: if (!lex->describe) { lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - if (!(lex->exchange= new (thd->mem_root) sql_exchange($2.str,1))) + if (unlikely(!(lex->exchange= + new (thd->mem_root) sql_exchange($2.str,1)))) MYSQL_YYABORT; - if (!(lex->result= - new (thd->mem_root) select_dump(thd, lex->exchange))) + if (unlikely(!(lex->result= + new (thd->mem_root) + select_dump(thd, lex->exchange)))) MYSQL_YYABORT; } } @@ -12674,16 +13091,16 @@ drop: LEX *lex=Lex; Alter_drop *ad= (new (thd->mem_root) Alter_drop(Alter_drop::KEY, $4.str, $3)); - if (ad == NULL) + if (unlikely(ad == NULL)) MYSQL_YYABORT; lex->sql_command= SQLCOM_DROP_INDEX; lex->alter_info.reset(); lex->alter_info.flags= ALTER_DROP_INDEX; lex->alter_info.drop_list.push_back(ad, thd->mem_root); - if (!lex->current_select->add_table_to_list(thd, $6, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_UPGRADABLE)) + if (unlikely(!lex->current_select-> + add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_UPGRADABLE))) MYSQL_YYABORT; } | DROP DATABASE opt_if_exists ident @@ -12696,7 +13113,7 @@ drop: { LEX *lex= Lex; lex->set_command(SQLCOM_DROP_PACKAGE, $3); - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE")); lex->spname= $4; } @@ -12704,7 +13121,7 @@ drop: { LEX *lex= Lex; lex->set_command(SQLCOM_DROP_PACKAGE_BODY, $4); - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE BODY")); lex->spname= $5; } @@ -12712,13 +13129,13 @@ drop: { LEX *lex= thd->lex; sp_name *spname; - if ($4.str && check_db_name((LEX_STRING*) &$4)) - my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $4.str)); - if (lex->sphead) + if (unlikely($4.str && check_db_name((LEX_STRING*) &$4))) + my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $4.str)); + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); lex->set_command(SQLCOM_DROP_FUNCTION, $3); spname= new (thd->mem_root) sp_name(&$4, &$6, true); - if (spname == NULL) + if (unlikely(spname == NULL)) MYSQL_YYABORT; lex->spname= spname; } @@ -12727,20 +13144,20 @@ drop: LEX *lex= thd->lex; LEX_CSTRING db= {0, 0}; sp_name *spname; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); - if (thd->db.str && lex->copy_db_to(&db)) + if (thd->db.str && unlikely(lex->copy_db_to(&db))) MYSQL_YYABORT; lex->set_command(SQLCOM_DROP_FUNCTION, $3); spname= new (thd->mem_root) sp_name(&db, &$4, false); - if (spname == NULL) + if (unlikely(spname == NULL)) MYSQL_YYABORT; lex->spname= spname; } | DROP PROCEDURE_SYM opt_if_exists sp_name { LEX *lex=Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE")); lex->set_command(SQLCOM_DROP_PROCEDURE, $3); lex->spname= $4; @@ -12809,10 +13226,10 @@ table_list: table_name: table_ident { - if (!Select->add_table_to_list(thd, $1, NULL, - TL_OPTION_UPDATING, - YYPS->m_lock_type, - YYPS->m_mdl_type)) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, + TL_OPTION_UPDATING, + YYPS->m_lock_type, + YYPS->m_mdl_type))) MYSQL_YYABORT; } ; @@ -12820,12 +13237,12 @@ table_name: table_name_with_opt_use_partition: table_ident opt_use_partition { - if (!Select->add_table_to_list(thd, $1, NULL, - TL_OPTION_UPDATING, - YYPS->m_lock_type, - YYPS->m_mdl_type, - NULL, - $2)) + if (unlikely(!Select->add_table_to_list(thd, $1, NULL, + TL_OPTION_UPDATING, + YYPS->m_lock_type, + YYPS->m_mdl_type, + NULL, + $2))) MYSQL_YYABORT; } ; @@ -12838,10 +13255,12 @@ table_alias_ref_list: table_alias_ref: table_ident_opt_wild { - if (!Select->add_table_to_list(thd, $1, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, + if (unlikely(!Select-> + add_table_to_list(thd, $1, NULL, + (TL_OPTION_UPDATING | + TL_OPTION_ALIAS), YYPS->m_lock_type, - YYPS->m_mdl_type)) + YYPS->m_mdl_type))) MYSQL_YYABORT; } ; @@ -12926,10 +13345,9 @@ insert_lock_option: | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; } | DELAYED_SYM { - Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() - - thd->query()); - Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset + - YYLIP->yyLength() + 1; + // QQ: why was +1? + Lex->keyword_delayed_begin_offset= (uint)($1.pos() - thd->query()); + Lex->keyword_delayed_end_offset= (uint)($1.end() - thd->query()); $$= TL_WRITE_DELAYED; } | HIGH_PRIORITY { $$= TL_WRITE; } @@ -12939,10 +13357,8 @@ replace_lock_option: opt_low_priority { $$= $1; } | DELAYED_SYM { - Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() - - thd->query()); - Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset + - YYLIP->yyLength() + 1; + Lex->keyword_delayed_begin_offset= (uint)($1.pos() - thd->query()); + Lex->keyword_delayed_end_offset= (uint)($1.end() - thd->query()); $$= TL_WRITE_DELAYED; } ; @@ -12968,8 +13384,9 @@ insert_field_spec: | SET { LEX *lex=Lex; - if (!(lex->insert_list= new (thd->mem_root) List_item) || - lex->many_values.push_back(lex->insert_list, thd->mem_root)) + if (unlikely(!(lex->insert_list= new (thd->mem_root) List_item)) || + unlikely(lex->many_values.push_back(lex->insert_list, + thd->mem_root))) MYSQL_YYABORT; } ident_eq_list @@ -13001,8 +13418,8 @@ ident_eq_value: simple_ident_nospvar equal expr_or_default { LEX *lex=Lex; - if (lex->field_list.push_back($1, thd->mem_root) || - lex->insert_list->push_back($3, thd->mem_root)) + if (unlikely(lex->field_list.push_back($1, thd->mem_root)) || + unlikely(lex->insert_list->push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -13030,13 +13447,14 @@ opt_by: no_braces: '(' { - if (!(Lex->insert_list= new (thd->mem_root) List_item)) - MYSQL_YYABORT; + if (unlikely(!(Lex->insert_list= new (thd->mem_root) List_item))) + MYSQL_YYABORT; } opt_values ')' { LEX *lex=Lex; - if (lex->many_values.push_back(lex->insert_list, thd->mem_root)) + if (unlikely(lex->many_values.push_back(lex->insert_list, + thd->mem_root))) MYSQL_YYABORT; } ; @@ -13049,12 +13467,12 @@ opt_values: values: values ',' expr_or_default { - if (Lex->insert_list->push_back($3, thd->mem_root)) + if (unlikely(Lex->insert_list->push_back($3, thd->mem_root))) MYSQL_YYABORT; } | expr_or_default { - if (Lex->insert_list->push_back($1, thd->mem_root)) + if (unlikely(Lex->insert_list->push_back($1, thd->mem_root))) MYSQL_YYABORT; } ; @@ -13064,13 +13482,13 @@ expr_or_default: | DEFAULT { $$= new (thd->mem_root) Item_default_value(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | IGNORE_SYM { $$= new (thd->mem_root) Item_ignore_value(thd, Lex->current_context()); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -13104,7 +13522,7 @@ update: LEX *lex= Lex; if (lex->select_lex.table_list.elements > 1) lex->sql_command= SQLCOM_UPDATE_MULTI; - else if (lex->select_lex.get_table_list()->derived) + else if (unlikely(lex->select_lex.get_table_list()->derived)) { /* it is single table update and it is update of derived table */ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), @@ -13129,7 +13547,8 @@ update_list: update_elem: simple_ident_nospvar equal expr_or_default { - if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3)) + if (unlikely(add_item_to_list(thd, $1)) || + unlikely(add_value_to_list(thd, $3))) MYSQL_YYABORT; } ; @@ -13143,8 +13562,8 @@ insert_update_elem: simple_ident_nospvar equal expr_or_default { LEX *lex= Lex; - if (lex->update_list.push_back($1, thd->mem_root) || - lex->value_list.push_back($3, thd->mem_root)) + if (unlikely(lex->update_list.push_back($1, thd->mem_root)) || + unlikely(lex->value_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -13168,23 +13587,48 @@ delete: lex->ignore= 0; lex->select_lex.init_order(); } - opt_delete_options single_multi + delete_part2 + ; + +opt_delete_system_time: + /* empty */ + { + Lex->vers_conditions.init(SYSTEM_TIME_ALL); + } + | BEFORE_SYM SYSTEM_TIME_SYM history_point + { + Lex->vers_conditions.init(SYSTEM_TIME_BEFORE, $3); + } + ; + +delete_part2: + opt_delete_options single_multi {} + | HISTORY_SYM delete_single_table opt_delete_system_time + { + Lex->last_table()->vers_conditions= Lex->vers_conditions; + } ; -single_multi: +delete_single_table: FROM table_ident opt_use_partition { - if (!Select->add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING, + if (unlikely(!Select-> + add_table_to_list(thd, $2, NULL, TL_OPTION_UPDATING, YYPS->m_lock_type, YYPS->m_mdl_type, NULL, - $3)) + $3))) MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_DEFAULT; YYPS->m_mdl_type= MDL_SHARED_READ; } - opt_where_clause opt_order_clause - delete_limit_clause {} + ; + +single_multi: + delete_single_table + opt_where_clause + opt_order_clause + delete_limit_clause opt_select_expressions {} | table_wild_list { @@ -13194,7 +13638,7 @@ single_multi: } FROM join_table_list opt_where_clause { - if (multi_delete_set_locks_and_link_aux_tables(Lex)) + if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex))) MYSQL_YYABORT; } | FROM table_alias_ref_list @@ -13205,7 +13649,7 @@ single_multi: } USING join_table_list opt_where_clause { - if (multi_delete_set_locks_and_link_aux_tables(Lex)) + if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex))) MYSQL_YYABORT; } ; @@ -13224,27 +13668,31 @@ table_wild_one: ident opt_wild { Table_ident *ti= new (thd->mem_root) Table_ident(&$1); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; - if (!Select->add_table_to_list(thd, + if (unlikely(!Select-> + add_table_to_list(thd, ti, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, + (TL_OPTION_UPDATING | + TL_OPTION_ALIAS), YYPS->m_lock_type, - YYPS->m_mdl_type)) + YYPS->m_mdl_type))) MYSQL_YYABORT; } | ident '.' ident opt_wild { Table_ident *ti= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); - if (ti == NULL) + if (unlikely(ti == NULL)) MYSQL_YYABORT; - if (!Select->add_table_to_list(thd, + if (unlikely(!Select-> + add_table_to_list(thd, ti, NULL, - TL_OPTION_UPDATING | TL_OPTION_ALIAS, + (TL_OPTION_UPDATING | + TL_OPTION_ALIAS), YYPS->m_lock_type, - YYPS->m_mdl_type)) + YYPS->m_mdl_type))) MYSQL_YYABORT; } ; @@ -13266,7 +13714,7 @@ opt_delete_option: ; truncate: - TRUNCATE_SYM opt_table_sym + TRUNCATE_SYM { LEX* lex= Lex; lex->sql_command= SQLCOM_TRUNCATE; @@ -13277,12 +13725,12 @@ truncate: YYPS->m_lock_type= TL_WRITE; YYPS->m_mdl_type= MDL_EXCLUSIVE; } - table_name opt_lock_wait_timeout + opt_table_sym table_name opt_lock_wait_timeout { LEX* lex= thd->lex; DBUG_ASSERT(!lex->m_sql_cmd); lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table(); - if (lex->m_sql_cmd == NULL) + if (unlikely(lex->m_sql_cmd == NULL)) MYSQL_YYABORT; } opt_truncate_table_storage_clause { } @@ -13380,7 +13828,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_DATABASES; - if (prepare_schema_table(thd, lex, 0, SCH_SCHEMATA)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SCHEMATA))) MYSQL_YYABORT; } | opt_full TABLES opt_db wild_and_where @@ -13388,7 +13836,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))) MYSQL_YYABORT; } | opt_full TRIGGERS_SYM opt_db wild_and_where @@ -13396,7 +13844,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TRIGGERS; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))) MYSQL_YYABORT; } | EVENTS_SYM opt_db wild_and_where @@ -13404,7 +13852,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_EVENTS; lex->select_lex.db= $2; - if (prepare_schema_table(thd, lex, 0, SCH_EVENTS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_EVENTS))) MYSQL_YYABORT; } | TABLE_SYM STATUS_SYM opt_db wild_and_where @@ -13412,7 +13860,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLE_STATUS; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_TABLES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_TABLES))) MYSQL_YYABORT; } | OPEN_SYM TABLES opt_db wild_and_where @@ -13420,27 +13868,27 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; lex->select_lex.db= $3; - if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))) MYSQL_YYABORT; } | PLUGINS_SYM { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_PLUGINS; - if (prepare_schema_table(thd, lex, 0, SCH_PLUGINS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PLUGINS))) MYSQL_YYABORT; } | PLUGINS_SYM SONAME_SYM TEXT_STRING_sys { Lex->ident= $3; Lex->sql_command= SQLCOM_SHOW_PLUGINS; - if (prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS)) + if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS))) MYSQL_YYABORT; } | PLUGINS_SYM SONAME_SYM wild_and_where { Lex->sql_command= SQLCOM_SHOW_PLUGINS; - if (prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS)) + if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS))) MYSQL_YYABORT; } | ENGINE_SYM known_storage_engines show_engine_param @@ -13453,7 +13901,7 @@ show_param: lex->sql_command= SQLCOM_SHOW_FIELDS; if ($5.str) $4->change_db(&$5); - if (prepare_schema_table(thd, lex, $4, SCH_COLUMNS)) + if (unlikely(prepare_schema_table(thd, lex, $4, SCH_COLUMNS))) MYSQL_YYABORT; } | master_or_binary LOGS_SYM @@ -13481,14 +13929,14 @@ show_param: lex->sql_command= SQLCOM_SHOW_KEYS; if ($4.str) $3->change_db(&$4); - if (prepare_schema_table(thd, lex, $3, SCH_STATISTICS)) + if (unlikely(prepare_schema_table(thd, lex, $3, SCH_STATISTICS))) MYSQL_YYABORT; } | opt_storage ENGINES_SYM { LEX *lex=Lex; lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES; - if (prepare_schema_table(thd, lex, 0, SCH_ENGINES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_ENGINES))) MYSQL_YYABORT; } | AUTHORS_SYM @@ -13526,7 +13974,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_PROFILE; - if (prepare_schema_table(thd, lex, NULL, SCH_PROFILES) != 0) + if (unlikely(prepare_schema_table(thd, lex, NULL, SCH_PROFILES))) MYSQL_YYABORT; } | opt_var_type STATUS_SYM wild_and_where @@ -13534,7 +13982,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS; lex->option_type= $1; - if (prepare_schema_table(thd, lex, 0, SCH_SESSION_STATUS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SESSION_STATUS))) MYSQL_YYABORT; } | opt_full PROCESSLIST_SYM @@ -13544,27 +13992,28 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_VARIABLES; lex->option_type= $1; - if (prepare_schema_table(thd, lex, 0, SCH_SESSION_VARIABLES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SESSION_VARIABLES))) MYSQL_YYABORT; } | charset wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_CHARSETS; - if (prepare_schema_table(thd, lex, 0, SCH_CHARSETS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_CHARSETS))) MYSQL_YYABORT; } | COLLATION_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_COLLATIONS; - if (prepare_schema_table(thd, lex, 0, SCH_COLLATIONS)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_COLLATIONS))) MYSQL_YYABORT; } | GRANTS { Lex->sql_command= SQLCOM_SHOW_GRANTS; - if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!(Lex->grant_user= + (LEX_USER*)thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; Lex->grant_user->user= current_user_and_current_role; } @@ -13583,7 +14032,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $3, NULL,0))) MYSQL_YYABORT; lex->create_info.storage_media= HA_SM_DEFAULT; } @@ -13591,7 +14040,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_VIEW; } @@ -13599,7 +14048,7 @@ show_param: { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE; - if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + if (unlikely(!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))) MYSQL_YYABORT; lex->table_type= TABLE_TYPE_SEQUENCE; } @@ -13659,7 +14108,8 @@ show_param: | CREATE USER_SYM { Lex->sql_command= SQLCOM_SHOW_CREATE_USER; - if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!(Lex->grant_user= + (LEX_USER*)thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; Lex->grant_user->user= current_user; } @@ -13672,28 +14122,28 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PROC; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | FUNCTION_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_FUNC; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | PACKAGE_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | PACKAGE_SYM BODY_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE_BODY; - if (prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)) + if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } | PROCEDURE_SYM CODE_SYM sp_name @@ -13719,7 +14169,7 @@ show_param: | describe_command FOR_SYM expr { Lex->sql_command= SQLCOM_SHOW_EXPLAIN; - if (prepare_schema_table(thd, Lex, 0, SCH_EXPLAIN)) + if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_EXPLAIN))) MYSQL_YYABORT; add_value_to_list(thd, $3); } @@ -13729,17 +14179,17 @@ show_param: bool in_plugin; lex->sql_command= SQLCOM_SHOW_GENERIC; ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1, &in_plugin); - if (!table || !table->old_format || !in_plugin) + if (unlikely(!table || !table->old_format || !in_plugin)) { thd->parse_error(ER_SYNTAX_ERROR, $2); MYSQL_YYABORT; } - if (lex->wild && table->idx_field1 < 0) + if (unlikely(lex->wild && table->idx_field1 < 0)) { thd->parse_error(ER_SYNTAX_ERROR, $3); MYSQL_YYABORT; } - if (make_schema_select(thd, Lex->current_select, table)) + if (unlikely(make_schema_select(thd, Lex->current_select, table))) MYSQL_YYABORT; } ; @@ -13794,7 +14244,7 @@ wild_and_where: { Lex->wild= new (thd->mem_root) String($3.str, $3.length, system_charset_info); - if (Lex->wild == NULL) + if (unlikely(Lex->wild == NULL)) MYSQL_YYABORT; $$= $2; } @@ -13817,7 +14267,7 @@ describe: lex->sql_command= SQLCOM_SHOW_FIELDS; lex->select_lex.db= null_clex_str; lex->verbose= 0; - if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS)) + if (unlikely(prepare_schema_table(thd, lex, $2, SCH_COLUMNS))) MYSQL_YYABORT; } opt_describe_column @@ -13863,9 +14313,9 @@ opt_format_json: /* empty */ {} | FORMAT_SYM '=' ident_or_text { - if (!my_strcasecmp(system_charset_info, $3.str, "JSON")) + if (lex_string_eq(&$3, STRING_WITH_LEN("JSON"))) Lex->explain_json= true; - else if (!my_strcasecmp(system_charset_info, $3.str, "TRADITIONAL")) + else if (lex_string_eq(&$3, STRING_WITH_LEN("TRADITIONAL"))) DBUG_ASSERT(Lex->explain_json==false); else my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "EXPLAIN", @@ -13881,7 +14331,7 @@ opt_describe_column: Lex->wild= new (thd->mem_root) String((const char*) $1.str, $1.length, system_charset_info); - if (Lex->wild == NULL) + if (unlikely(Lex->wild == NULL)) MYSQL_YYABORT; } ; @@ -13938,8 +14388,9 @@ flush_lock: { Lex->type|= REFRESH_READ_LOCK | $4; } | FOR_SYM { - if (Lex->query_tables == NULL) // Table list can't be empty + if (unlikely(Lex->query_tables == NULL)) { + // Table list can't be empty thd->parse_error(ER_NO_TABLES_USED); MYSQL_YYABORT; } @@ -13962,12 +14413,12 @@ flush_option: { Lex->type|= REFRESH_GENERAL_LOG; } | SLOW LOGS_SYM { Lex->type|= REFRESH_SLOW_LOG; } - | BINARY LOGS_SYM + | BINARY LOGS_SYM opt_delete_gtid_domain { Lex->type|= REFRESH_BINARY_LOG; } | RELAY LOGS_SYM optional_connection_name { LEX *lex= Lex; - if (lex->type & REFRESH_RELAY_LOG) + if (unlikely(lex->type & REFRESH_RELAY_LOG)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "FLUSH", "RELAY LOGS")); lex->type|= REFRESH_RELAY_LOG; lex->relay_log_connection_name= lex->mi.connection_name; @@ -13988,7 +14439,7 @@ flush_option: | SLAVE optional_connection_name { LEX *lex= Lex; - if (lex->type & REFRESH_SLAVE) + if (unlikely(lex->type & REFRESH_SLAVE)) my_yyabort_error((ER_WRONG_USAGE, MYF(0), "FLUSH","SLAVE")); lex->type|= REFRESH_SLAVE; lex->reset_slave_info.all= false; @@ -14003,14 +14454,15 @@ flush_option: { Lex->type|= REFRESH_GENERIC; ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1); - if (!table || !table->reset_table) + if (unlikely(!table || !table->reset_table)) { thd->parse_error(ER_SYNTAX_ERROR, $2); MYSQL_YYABORT; } - Lex->view_list.push_back((LEX_CSTRING*) - thd->memdup(&$1, sizeof(LEX_CSTRING)), - thd->mem_root); + if (unlikely(Lex->view_list.push_back((LEX_CSTRING*) + thd->memdup(&$1, sizeof(LEX_CSTRING)), + thd->mem_root))) + MYSQL_YYABORT; } ; @@ -14019,6 +14471,24 @@ opt_table_list: | table_list {} ; +opt_delete_gtid_domain: + /* empty */ {} + | DELETE_DOMAIN_ID_SYM '=' '(' delete_domain_id_list ')' + {} + ; +delete_domain_id_list: + /* Empty */ + | delete_domain_id + | delete_domain_id_list ',' delete_domain_id + ; + +delete_domain_id: + ulong_num + { + insert_dynamic(&Lex->delete_gtid_domain, (uchar*) &($1)); + } + ; + optional_flush_tables_arguments: /* empty */ {$$= 0;} | AND_SYM DISABLE_SYM CHECKPOINT_SYM {$$= REFRESH_CHECKPOINT; } @@ -14161,7 +14631,7 @@ load: { LEX *lex= thd->lex; - if (lex->sphead) + if (unlikely(lex->sphead)) { my_error(ER_SP_BADSTATEMENT, MYF(0), $2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML"); @@ -14175,14 +14645,17 @@ load: lex->local_file= $5; lex->duplicates= DUP_ERROR; lex->ignore= 0; - if (!(lex->exchange= new (thd->mem_root) sql_exchange($7.str, 0, $2))) + if (unlikely(!(lex->exchange= new (thd->mem_root) + sql_exchange($7.str, 0, $2)))) MYSQL_YYABORT; } opt_duplicate INTO TABLE_SYM table_ident opt_use_partition { LEX *lex=Lex; - if (!Select->add_table_to_list(thd, $12, NULL, TL_OPTION_UPDATING, - $4, MDL_SHARED_WRITE, NULL, $13)) + if (unlikely(!Select->add_table_to_list(thd, $12, NULL, + TL_OPTION_UPDATING, + $4, MDL_SHARED_WRITE, + NULL, $13))) MYSQL_YYABORT; lex->field_list.empty(); lex->update_list.empty(); @@ -14320,7 +14793,7 @@ field_or_var: | '@' ident_or_text { $$= new (thd->mem_root) Item_user_var_as_out_param(thd, &$2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -14339,8 +14812,8 @@ load_data_set_elem: simple_ident_nospvar equal remember_name expr_or_default remember_end { LEX *lex= Lex; - if (lex->update_list.push_back($1, thd->mem_root) || - lex->value_list.push_back($4, thd->mem_root)) + if (unlikely(lex->update_list.push_back($1, thd->mem_root)) || + unlikely(lex->value_list.push_back($4, thd->mem_root))) MYSQL_YYABORT; $4->set_name_no_truncate(thd, $3, (uint) ($5 - $3), thd->charset()); } @@ -14351,22 +14824,22 @@ load_data_set_elem: text_literal: TEXT_STRING { - if (!($$= thd->make_string_literal($1))) + if (unlikely(!($$= thd->make_string_literal($1)))) MYSQL_YYABORT; } | NCHAR_STRING { - if (!($$= thd->make_string_literal_nchar($1))) + if (unlikely(!($$= thd->make_string_literal_nchar($1)))) MYSQL_YYABORT; } | UNDERSCORE_CHARSET TEXT_STRING { - if (!($$= thd->make_string_literal_charset($2, $1))) + if (unlikely(!($$= thd->make_string_literal_charset($2, $1)))) MYSQL_YYABORT; } | text_literal TEXT_STRING_literal { - if (!($$= $1->make_string_literal_concat(thd, &$2))) + if (unlikely(!($$= $1->make_string_literal_concat(thd, &$2)))) MYSQL_YYABORT; } ; @@ -14377,7 +14850,7 @@ text_string: $$= new (thd->mem_root) String($1.str, $1.length, thd->variables.collation_connection); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | hex_or_bin_String { $$= $1; } @@ -14389,7 +14862,7 @@ hex_or_bin_String: { Item *tmp= new (thd->mem_root) Item_hex_hybrid(thd, $1.str, $1.length); - if (tmp == NULL) + if (unlikely(tmp == NULL)) MYSQL_YYABORT; /* it is OK only emulate fix_fields, because we need only @@ -14402,7 +14875,7 @@ hex_or_bin_String: { Item *tmp= new (thd->mem_root) Item_hex_string(thd, $1.str, $1.length); - if (tmp == NULL) + if (unlikely(tmp == NULL)) MYSQL_YYABORT; tmp->quick_fix_field(); $$= tmp->val_str((String*) 0); @@ -14411,7 +14884,7 @@ hex_or_bin_String: { Item *tmp= new (thd->mem_root) Item_bin_string(thd, $1.str, $1.length); - if (tmp == NULL) + if (unlikely(tmp == NULL)) MYSQL_YYABORT; /* it is OK only emulate fix_fields, because we need only @@ -14425,21 +14898,21 @@ hex_or_bin_String: param_marker: PARAM_MARKER { - if (!($$= Lex->add_placeholder(thd, ¶m_clex_str, - YYLIP->get_tok_start(), - YYLIP->get_tok_start() + 1))) + if (unlikely(!($$= Lex->add_placeholder(thd, ¶m_clex_str, + YYLIP->get_tok_start(), + YYLIP->get_tok_start() + 1)))) MYSQL_YYABORT; } - | colon_with_pos ident + | colon_with_pos ident_cli { - if (!($$= Lex->add_placeholder(thd, &null_clex_str, - $1, YYLIP->get_tok_end()))) + if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str, + $1, $2.end())))) MYSQL_YYABORT; } | colon_with_pos NUM { - if (!($$= Lex->add_placeholder(thd, &null_clex_str, - $1, YYLIP->get_ptr()))) + if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str, + $1, YYLIP->get_ptr())))) MYSQL_YYABORT; } ; @@ -14467,38 +14940,38 @@ literal: */ YYLIP->reduce_digest_token(TOK_GENERIC_VALUE, NULL_SYM); $$= new (thd->mem_root) Item_null(thd); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT; } | FALSE_SYM { $$= new (thd->mem_root) Item_bool(thd, (char*) "FALSE",0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | TRUE_SYM { $$= new (thd->mem_root) Item_bool(thd, (char*) "TRUE",1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | HEX_NUM { $$= new (thd->mem_root) Item_hex_hybrid(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | HEX_STRING { $$= new (thd->mem_root) Item_hex_string(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BIN_NUM { $$= new (thd->mem_root) Item_bin_string(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | UNDERSCORE_CHARSET hex_or_bin_String @@ -14511,7 +14984,8 @@ literal: item_str= new (thd->mem_root) Item_string_with_introducer(thd, NULL, $2->ptr(), $2->length(), $1); - if (!item_str || !item_str->check_well_formed_result(true)) + if (unlikely(!item_str || + !item_str->check_well_formed_result(true))) MYSQL_YYABORT; $$= item_str; @@ -14526,7 +15000,7 @@ NUM_literal: Item_int(thd, $1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | LONG_NUM @@ -14536,31 +15010,27 @@ NUM_literal: Item_int(thd, $1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ULONGLONG_NUM { $$= new (thd->mem_root) Item_uint(thd, $1.str, $1.length); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | DECIMAL_NUM { $$= new (thd->mem_root) Item_decimal(thd, $1.str, $1.length, thd->charset()); - if (($$ == NULL) || (thd->is_error())) - { + if (unlikely($$ == NULL) || unlikely(thd->is_error())) MYSQL_YYABORT; - } } | FLOAT_NUM { $$= new (thd->mem_root) Item_float(thd, $1.str, $1.length); - if (($$ == NULL) || (thd->is_error())) - { + if (unlikely($$ == NULL) || unlikely(thd->is_error())) MYSQL_YYABORT; - } } ; @@ -14568,20 +15038,26 @@ NUM_literal: temporal_literal: DATE_SYM TEXT_STRING { - if (!($$= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, - MYSQL_TYPE_DATE, true))) + if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length, + YYCSCL, + MYSQL_TYPE_DATE, + true)))) MYSQL_YYABORT; } | TIME_SYM TEXT_STRING { - if (!($$= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, - MYSQL_TYPE_TIME, true))) + if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length, + YYCSCL, + MYSQL_TYPE_TIME, + true)))) MYSQL_YYABORT; } | TIMESTAMP TEXT_STRING { - if (!($$= create_temporal_literal(thd, $2.str, $2.length, YYCSCL, - MYSQL_TYPE_DATETIME, true))) + if (unlikely(!($$= create_temporal_literal(thd, $2.str, $2.length, + YYCSCL, + MYSQL_TYPE_DATETIME, + true)))) MYSQL_YYABORT; } ; @@ -14601,7 +15077,7 @@ with_clause: { With_clause *with_clause= new With_clause($2, Lex->curr_with_clause); - if (with_clause == NULL) + if (unlikely(with_clause == NULL)) MYSQL_YYABORT; Lex->derived_tables|= DERIVED_WITH; Lex->curr_with_clause= with_clause; @@ -14632,16 +15108,17 @@ with_list_element: opt_with_column_list { $2= new List<LEX_CSTRING> (Lex->with_column_list); - if ($2 == NULL) + if (unlikely($2 == NULL)) MYSQL_YYABORT; Lex->with_column_list.empty(); } AS '(' remember_name subselect remember_end ')' { With_element *elem= new With_element($1, *$2, $7->master_unit()); - if (elem == NULL || Lex->curr_with_clause->add_with_element(elem)) + if (unlikely(elem == NULL) || + unlikely(Lex->curr_with_clause->add_with_element(elem))) MYSQL_YYABORT; - if (elem->set_unparsed_spec(thd, $6+1, $8)) + if (unlikely(elem->set_unparsed_spec(thd, $6+1, $8))) MYSQL_YYABORT; } ; @@ -14673,7 +15150,7 @@ query_name: ident { $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -14692,24 +15169,26 @@ insert_ident: table_wild: ident '.' '*' { - SELECT_LEX *sel= Select; - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, $1.str, &star_clex_str); - if ($$ == NULL) + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1)))) MYSQL_YYABORT; - sel->with_wild++; } | ident '.' ident '.' '*' { - SELECT_LEX *sel= Select; - const char* schema= thd->client_capabilities & CLIENT_NO_SCHEMA ? - NullS : $1.str; - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - schema, - $3.str, &star_clex_str); - if ($$ == NULL) + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1, &$3)))) + MYSQL_YYABORT; + } + ; + +select_sublist_qualified_asterisk: + ident_cli '.' '*' + { + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1)))) + MYSQL_YYABORT; + } + | ident_cli '.' ident_cli '.' '*' + { + if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1, &$3)))) MYSQL_YYABORT; - sel->with_wild++; } ; @@ -14717,21 +15196,32 @@ order_ident: expr { $$=$1; } ; + simple_ident: - ident + ident_cli { - Lex_input_stream *lip= YYLIP; - if (!($$= Lex->create_item_ident(thd, &$1, - lip->get_tok_start_prev(), - lip->get_tok_end()))) + if (unlikely(!($$= Lex->create_item_ident(thd, &$1)))) MYSQL_YYABORT; } - | simple_ident_q2 - | ident '.' ident + | ident_cli '.' ident_cli { - LEX *lex= thd->lex; - if (!($$= lex->create_item_ident(thd, &$1, &$3, - $1.m_pos, YYLIP->get_tok_end()))) + if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3)))) + MYSQL_YYABORT; + } + | '.' ident_cli '.' ident_cli + { + Lex_ident_cli empty($2.pos(), 0); + if (unlikely(!($$= Lex->create_item_ident(thd, &empty, &$2, &$4)))) + MYSQL_YYABORT; + } + | ident_cli '.' ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) + MYSQL_YYABORT; + } + | colon_with_pos ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4)))) MYSQL_YYABORT; } ; @@ -14739,47 +15229,28 @@ simple_ident: simple_ident_nospvar: ident { - if (!($$= Lex->create_item_ident_nosp(thd, &$1))) + if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1)))) MYSQL_YYABORT; } - | simple_ident_q { $$= $1; } - ; - -simple_ident_q: - ident '.' ident + | ident '.' ident { - if (!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3))) + if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3)))) MYSQL_YYABORT; } - | simple_ident_q2 - ; - -simple_ident_q2: - colon_with_pos ident '.' ident + | colon_with_pos ident_cli '.' ident_cli { - LEX *lex= Lex; - if (lex->is_trigger_new_or_old_reference(&$2)) - { - bool new_row= ($2.str[0]=='N' || $2.str[0]=='n'); - if (!($$= lex->create_and_link_Item_trigger_field(thd, - &$4, - new_row))) - MYSQL_YYABORT; - } - else - { - thd->parse_error(); + if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4)))) MYSQL_YYABORT; - } } | '.' ident '.' ident { - if (!($$= Lex->create_item_ident(thd, &null_clex_str, &$2, &$4))) + Lex_ident_sys none; + if (unlikely(!($$= Lex->create_item_ident(thd, &none, &$2, &$4)))) MYSQL_YYABORT; } | ident '.' ident '.' ident { - if (!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))) + if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } ; @@ -14789,17 +15260,19 @@ field_ident: | ident '.' ident '.' ident { TABLE_LIST *table= Select->table_list.first; - if (my_strcasecmp(table_alias_charset, $1.str, table->db.str)) + if (unlikely(my_strcasecmp(table_alias_charset, $1.str, + table->db.str))) my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); - if (my_strcasecmp(table_alias_charset, $3.str, - table->table_name.str)) + if (unlikely(my_strcasecmp(table_alias_charset, $3.str, + table->table_name.str))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3.str)); $$=$5; } | ident '.' ident { TABLE_LIST *table= Select->table_list.first; - if (my_strcasecmp(table_alias_charset, $1.str, table->alias.str)) + if (unlikely(my_strcasecmp(table_alias_charset, $1.str, + table->alias.str))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $1.str)); $$=$3; } @@ -14810,20 +15283,20 @@ table_ident: ident { $$= new (thd->mem_root) Table_ident(&$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ident '.' ident { $$= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | '.' ident { /* For Delphi */ $$= new (thd->mem_root) Table_ident(&$2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -14832,13 +15305,13 @@ table_ident_opt_wild: ident opt_wild { $$= new (thd->mem_root) Table_ident(&$1); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ident '.' ident opt_wild { $$= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -14848,150 +15321,104 @@ table_ident_nodb: { LEX_CSTRING db={(char*) any_db,3}; $$= new (thd->mem_root) Table_ident(thd, &db, &$1, 0); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; -IDENT_sys: - IDENT { $$= $1; } +IDENT_cli: + IDENT | IDENT_QUOTED + ; + +ident_cli: + IDENT + | IDENT_QUOTED + | keyword_ident { $$= $1; } + ; + +IDENT_sys: + IDENT_cli { - if (thd->charset_is_system_charset) - { - CHARSET_INFO *cs= system_charset_info; - size_t wlen= Well_formed_prefix(cs, $1.str, $1.length).length(); - if (wlen < $1.length) - { - ErrConvString err($1.str, $1.length, &my_charset_bin); - my_error(ER_INVALID_CHARACTER_STRING, MYF(0), - cs->csname, err.ptr()); - MYSQL_YYABORT; - } - $$= $1; - } - else - { - LEX_STRING to; - if (thd->convert_with_error(system_charset_info, &to, - thd->charset(), $1.str, $1.length)) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (unlikely(thd->to_ident_sys_alloc(&$$, &$1))) + MYSQL_YYABORT; } ; TEXT_STRING_sys: TEXT_STRING { - if (thd->charset_is_system_charset) - $$= $1; - else - { - LEX_STRING to; - if (thd->convert_string(&to, system_charset_info, - $1.str, $1.length, thd->charset())) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (thd->make_text_string_sys(&$$, &$1)) + MYSQL_YYABORT; } ; TEXT_STRING_literal: TEXT_STRING { - if (thd->charset_is_collation_connection) - $$= $1; - else - { - LEX_STRING to; - if (thd->convert_string(&to, thd->variables.collation_connection, - $1.str, $1.length, thd->charset())) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (thd->make_text_string_connection(&$$, &$1)) + MYSQL_YYABORT; } ; TEXT_STRING_filesystem: TEXT_STRING { - if (thd->charset_is_character_set_filesystem) - $$= $1; - else - { - LEX_STRING to; - if (thd->convert_string(&to, - thd->variables.character_set_filesystem, - $1.str, $1.length, thd->charset())) - MYSQL_YYABORT; - $$.str= to.str; - $$.length= to.length; - } + if (thd->make_text_string_filesystem(&$$, &$1)) + MYSQL_YYABORT; } ; -ident: +ident_table_alias: IDENT_sys + | keyword_table_alias { - (LEX_CSTRING &)$$= $1; - $$.m_pos= (char *) YYLIP->get_tok_start_prev(); - } - | keyword - { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; - $$.m_pos= (char *) YYLIP->get_tok_start_prev(); } ; -ident_with_tok_start: + +ident_sysvar_name: IDENT_sys + | keyword_sysvar_name { - (LEX_CSTRING &)$$= $1; - $$.m_pos= (char *) YYLIP->get_tok_start(); + if (unlikely($$.copy_keyword(thd, &$1))) + MYSQL_YYABORT; } - | keyword + | TEXT_STRING_sys { - if (!($$.str= thd->strmake($1.str, $1.length))) + if (unlikely($$.copy_sys(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; - $$.m_pos= (char *) YYLIP->get_tok_start(); } ; -ident_directly_assignable: - IDENT_sys { $$=$1; } - | keyword_directly_assignable + +ident: + IDENT_sys + | keyword_ident { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; } - | keyword_sp + ; + +ident_directly_assignable: + IDENT_sys + | keyword_directly_assignable { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; } ; label_ident: - IDENT_sys { $$=$1; } - | keyword_sp + IDENT_sys + | keyword_label { - $$.str= thd->strmake($1.str, $1.length); - if ($$.str == NULL) + if (unlikely($$.copy_keyword(thd, &$1))) MYSQL_YYABORT; - $$.length= $1.length; } ; @@ -15003,7 +15430,7 @@ labels_declaration_oracle: label_declaration_oracle: SHIFT_LEFT label_ident SHIFT_RIGHT { - if (Lex->sp_push_goto_label(thd, &$2)) + if (unlikely(Lex->sp_push_goto_label(thd, &$2))) MYSQL_YYABORT; $$= $2; } @@ -15018,28 +15445,28 @@ ident_or_text: user_maybe_role: ident_or_text { - if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user = $1; $$->host= null_clex_str; // User or Role, see get_current_user() $$->reset_auth(); - if (check_string_char_length(&$$->user, ER_USERNAME, - username_char_length, - system_charset_info, 0)) + if (unlikely(check_string_char_length(&$$->user, ER_USERNAME, + username_char_length, + system_charset_info, 0))) MYSQL_YYABORT; } | ident_or_text '@' ident_or_text { - if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user = $1; $$->host=$3; $$->reset_auth(); - if (check_string_char_length(&$$->user, ER_USERNAME, - username_char_length, - system_charset_info, 0) || - check_host_name(&$$->host)) + if (unlikely(check_string_char_length(&$$->user, ER_USERNAME, + username_char_length, + system_charset_info, 0)) || + unlikely(check_host_name(&$$->host))) MYSQL_YYABORT; if ($$->host.str[0]) { @@ -15061,7 +15488,7 @@ user_maybe_role: } | CURRENT_USER optional_braces { - if (!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user= current_user; $$->plugin= empty_clex_str; @@ -15079,74 +15506,143 @@ user: user_maybe_role } ; +/* Keywords which we allow as table aliases. */ +keyword_table_alias: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause + | FUNCTION_SYM + ; + /* Keyword that we allow for identifiers (except SP labels) */ -keyword: - keyword_sp {} - | keyword_directly_assignable {} - | keyword_directly_not_assignable {} +keyword_ident: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause + | FUNCTION_SYM + | WINDOW_SYM + ; + +/* + Keywords that we allow for labels in SPs. + Should not include keywords that start a statement or SP characteristics. +*/ +keyword_label: + keyword_data_type + | keyword_sp_var_and_label + | keyword_sysvar_type + | FUNCTION_SYM + ; + +keyword_sysvar_name: + keyword_data_type + | keyword_sp_block_section + | keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_verb_clause + | FUNCTION_SYM + | WINDOW_SYM ; +keyword_sp_decl: + keyword_sp_head + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause + | WINDOW_SYM + ; + +keyword_directly_assignable: + keyword_data_type + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | FUNCTION_SYM + | WINDOW_SYM + ; /* Keywords that we allow in Oracle-style direct assignments: xxx := 10; + but do not allow in labels in the default sql_mode: + label: + stmt1; + stmt2; + TODO: check if some of them can migrate to keyword_sp_var_and_label. */ -keyword_directly_assignable: - ASCII_SYM {} - | BACKUP_SYM {} - | BINLOG_SYM {} - | BYTE_SYM {} - | CACHE_SYM {} - | CHECKSUM_SYM {} - | CHECKPOINT_SYM {} - | COLUMN_ADD_SYM {} - | COLUMN_CHECK_SYM {} - | COLUMN_CREATE_SYM {} - | COLUMN_DELETE_SYM {} - | COLUMN_GET_SYM {} - | DEALLOCATE_SYM {} - | EXAMINED_SYM {} - | EXCLUDE_SYM {} - | EXECUTE_SYM {} - | FLUSH_SYM {} - | FOLLOWING_SYM {} - | FORMAT_SYM {} - | GET_SYM {} - | HELP_SYM {} - | HOST_SYM {} - | INSTALL_SYM {} - | OPTION {} - | OPTIONS_SYM {} - | OWNER_SYM {} - | PARSER_SYM {} - | PORT_SYM {} - | PRECEDING_SYM {} - | PREPARE_SYM {} - | REMOVE_SYM {} - | RESET_SYM {} - | RESTORE_SYM {} - | SECURITY_SYM {} - | SERVER_SYM {} - | SIGNED_SYM {} - | SOCKET_SYM {} - | SLAVE {} - | SLAVES {} - | SONAME_SYM {} - | START_SYM {} - | STOP_SYM {} - | STORED_SYM {} - | TIES_SYM {} - | UNICODE_SYM {} - | UNINSTALL_SYM {} - | UNBOUNDED_SYM {} - | WITHIN {} - | WRAPPER_SYM {} - | XA_SYM {} - | UPGRADE_SYM {} +keyword_sp_var_not_label: + ASCII_SYM + | BACKUP_SYM + | BINLOG_SYM + | BYTE_SYM + | CACHE_SYM + | CHECKSUM_SYM + | CHECKPOINT_SYM + | COLUMN_ADD_SYM + | COLUMN_CHECK_SYM + | COLUMN_CREATE_SYM + | COLUMN_DELETE_SYM + | COLUMN_GET_SYM + | DEALLOCATE_SYM + | EXAMINED_SYM + | EXCLUDE_SYM + | EXECUTE_SYM + | FLUSH_SYM + | FOLLOWING_SYM + | FORMAT_SYM + | GET_SYM + | HELP_SYM + | HISTORY_SYM + | HOST_SYM + | INSTALL_SYM + | OPTION + | OPTIONS_SYM + | OWNER_SYM + | PARSER_SYM + | PERIOD_SYM + | PORT_SYM + | PRECEDING_SYM + | PREPARE_SYM + | REMOVE_SYM + | RESET_SYM + | RESTORE_SYM + | SECURITY_SYM + | SERVER_SYM + | SIGNED_SYM + | SOCKET_SYM + | SLAVE + | SLAVES + | SONAME_SYM + | START_SYM + | STOP_SYM + | STORED_SYM + | SYSTEM + | SYSTEM_TIME_SYM + | TIES_SYM + | UNICODE_SYM + | UNINSTALL_SYM + | UNBOUNDED_SYM + | VERSIONING_SYM + | WITHIN + | WITHOUT + | WRAPPER_SYM + | XA_SYM + | UPGRADE_SYM ; /* - Keywords that are allowed as identifiers (e.g. table, column names), + Keywords that can start optional clauses in SP or trigger declarations + Allowed as identifiers (e.g. table, column names), but: - not allowed as SP label names - not allowed as variable names in Oracle-style assignments: @@ -15181,401 +15677,402 @@ keyword_directly_assignable: CREATE TRIGGER .. FOR EACH ROW follows:= 10; CREATE TRIGGER .. FOR EACH ROW FOLLOWS tr1 a:= 10; */ -keyword_directly_not_assignable: - CONTAINS_SYM { /* SP characteristic */ } - | LANGUAGE_SYM { /* SP characteristic */ } - | NO_SYM { /* SP characteristic */ } - | CHARSET { /* SET CHARSET utf8; */ } - | FOLLOWS_SYM { /* Conflicts with assignment in FOR EACH */} - | PRECEDES_SYM { /* Conflicts with assignment in FOR EACH */} - | keyword_sp_verb_clause { } - ; - -/* - * Keywords that we allow for labels in SPs. - * Anything that's the beginning of a statement or characteristics - * must be in keyword above, otherwise we get (harmful) shift/reduce - * conflicts. - */ -keyword_sp: - keyword_sp_data_type - | keyword_sp_not_data_type - | FUNCTION_SYM { /* Oracle-PLSQL-R */} +keyword_sp_head: + CONTAINS_SYM /* SP characteristic */ + | LANGUAGE_SYM /* SP characteristic */ + | NO_SYM /* SP characteristic */ + | CHARSET /* SET CHARSET utf8; */ + | FOLLOWS_SYM /* Conflicts with assignment in FOR EACH */ + | PRECEDES_SYM /* Conflicts with assignment in FOR EACH */ ; - /* - Keywords that start a statement or an SP block section. + Keywords that start a statement. Generally allowed as identifiers (e.g. table, column names) - not allowed as SP label names - not allowed as variable names in Oracle-style assignments: xxx:=10 */ -keyword_sp_verb_clause: - BEGIN_SYM { /* Compound. Reserved in Oracle */ } - | CLOSE_SYM { /* Verb clause. Reserved in Oracle */ } - | COMMIT_SYM { /* Verb clause. Reserved in Oracle */ } - | EXCEPTION_SYM { /* EXCEPTION section in SP blocks */ } - | DO_SYM { /* Verb clause */ } - | END { /* Compound. Reserved in Oracle */ } - | HANDLER_SYM { /* Verb clause */ } - | OPEN_SYM { /* Verb clause. Reserved in Oracle */ } - | REPAIR { /* Verb clause */ } - | ROLLBACK_SYM { /* Verb clause. Reserved in Oracle */ } - | SAVEPOINT_SYM { /* Verb clause. Reserved in Oracle */ } - | SHUTDOWN { /* Verb clause */ } - | TRUNCATE_SYM { /* Verb clause. Reserved in Oracle */ } - ; +keyword_verb_clause: + CLOSE_SYM /* Verb clause. Reserved in Oracle */ + | COMMIT_SYM /* Verb clause. Reserved in Oracle */ + | DO_SYM /* Verb clause */ + | HANDLER_SYM /* Verb clause */ + | OPEN_SYM /* Verb clause. Reserved in Oracle */ + | REPAIR /* Verb clause */ + | ROLLBACK_SYM /* Verb clause. Reserved in Oracle */ + | SAVEPOINT_SYM /* Verb clause. Reserved in Oracle */ + | SHUTDOWN /* Verb clause */ + | TRUNCATE_SYM /* Verb clause. Reserved in Oracle */ + ; + +/* + Keywords that start an SP block section. +*/ +keyword_sp_block_section: + BEGIN_SYM + | EXCEPTION_SYM + | END + ; + +keyword_sysvar_type: + GLOBAL_SYM + | LOCAL_SYM + | SESSION_SYM + ; /* These keywords are generally allowed as identifiers, but not allowed as non-delimited SP variable names in sql_mode=ORACLE. */ -keyword_sp_data_type: - BIT_SYM {} - | BOOLEAN_SYM {} /* PLSQL-R */ - | BOOL_SYM {} - | CLOB {} - | DATE_SYM {} /* Oracle-R, PLSQL-R */ - | DATETIME {} - | ENUM {} - | FIXED_SYM {} - | GEOMETRYCOLLECTION {} - | GEOMETRY_SYM {} - | JSON_SYM {} - | LINESTRING {} - | MEDIUM_SYM {} - | MULTILINESTRING {} - | MULTIPOINT {} - | MULTIPOLYGON {} - | NATIONAL_SYM {} - | NCHAR_SYM {} - | NUMBER_SYM {} /* Oracle-R, PLSQL-R */ - | NVARCHAR_SYM {} - | POINT_SYM {} - | POLYGON {} - | RAW {} /* Oracle-R */ - | ROW_SYM {} - | SERIAL_SYM {} - | TEXT_SYM {} - | TIMESTAMP {} - | TIME_SYM {} /* Oracle-R */ - | VARCHAR2 {} /* Oracle-R, PLSQL-R */ - | YEAR_SYM {} - ; - - -keyword_sp_not_data_type: - ACTION {} - | ADDDATE_SYM {} - | ADMIN_SYM {} - | AFTER_SYM {} - | AGAINST {} - | AGGREGATE_SYM {} - | ALGORITHM_SYM {} - | ALWAYS_SYM {} - | ANY_SYM {} - | AT_SYM {} - | ATOMIC_SYM {} - | AUTHORS_SYM {} - | AUTO_INC {} - | AUTOEXTEND_SIZE_SYM {} - | AUTO_SYM {} - | AVG_ROW_LENGTH {} - | AVG_SYM {} - | BLOCK_SYM {} - | BTREE_SYM {} - | CASCADED {} - | CATALOG_NAME_SYM {} - | CHAIN_SYM {} - | CHANGED {} - | CIPHER_SYM {} - | CLIENT_SYM {} - | CLASS_ORIGIN_SYM {} - | COALESCE {} - | CODE_SYM {} - | COLLATION_SYM {} - | COLUMN_NAME_SYM {} - | COLUMNS {} - | COMMITTED_SYM {} - | COMPACT_SYM {} - | COMPLETION_SYM {} - | COMPRESSED_SYM {} - | CONCURRENT {} - | CONNECTION_SYM {} - | CONSISTENT_SYM {} - | CONSTRAINT_CATALOG_SYM {} - | CONSTRAINT_SCHEMA_SYM {} - | CONSTRAINT_NAME_SYM {} - | CONTEXT_SYM {} - | CONTRIBUTORS_SYM {} - | CURRENT_POS_SYM {} - | CPU_SYM {} - | CUBE_SYM {} +keyword_data_type: + BIT_SYM + | BOOLEAN_SYM + | BOOL_SYM + | CLOB + | DATE_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | DATETIME + | ENUM + | FIXED_SYM + | GEOMETRYCOLLECTION + | GEOMETRY_SYM + | JSON_SYM + | LINESTRING + | MEDIUM_SYM + | MULTILINESTRING + | MULTIPOINT + | MULTIPOLYGON + | NATIONAL_SYM + | NCHAR_SYM + | NUMBER_SYM + | NVARCHAR_SYM + | POINT_SYM + | POLYGON + | RAW + | ROW_SYM + | SERIAL_SYM + | TEXT_SYM + | TIMESTAMP %prec PREC_BELOW_CONTRACTION_TOKEN2 + | TIME_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | VARCHAR2 + | YEAR_SYM + ; + + +/* + These keywords are fine for both SP variable names and SP labels. +*/ +keyword_sp_var_and_label: + ACTION + | ADDDATE_SYM + | ADMIN_SYM + | AFTER_SYM + | AGAINST + | AGGREGATE_SYM + | ALGORITHM_SYM + | ALWAYS_SYM + | ANY_SYM + | AT_SYM + | ATOMIC_SYM + | AUTHORS_SYM + | AUTO_INC + | AUTOEXTEND_SIZE_SYM + | AUTO_SYM + | AVG_ROW_LENGTH + | AVG_SYM + | BLOCK_SYM + | BTREE_SYM + | CASCADED + | CATALOG_NAME_SYM + | CHAIN_SYM + | CHANGED + | CIPHER_SYM + | CLIENT_SYM + | CLASS_ORIGIN_SYM + | COALESCE + | CODE_SYM + | COLLATION_SYM + | COLUMN_NAME_SYM + | COLUMNS + | COMMITTED_SYM + | COMPACT_SYM + | COMPLETION_SYM + | COMPRESSED_SYM + | CONCURRENT + | CONNECTION_SYM + | CONSISTENT_SYM + | CONSTRAINT_CATALOG_SYM + | CONSTRAINT_SCHEMA_SYM + | CONSTRAINT_NAME_SYM + | CONTEXT_SYM + | CONTRIBUTORS_SYM + | CURRENT_POS_SYM + | CPU_SYM + | CUBE_SYM /* Although a reserved keyword in SQL:2003 (and :2008), not reserved in MySQL per WL#2111 specification. */ - | CURRENT_SYM {} - | CURSOR_NAME_SYM {} - | CYCLE_SYM {} - | DATA_SYM {} - | DATAFILE_SYM {} - | DATE_FORMAT_SYM {} - | DAY_SYM {} - | DECODE_SYM {} - | DEFINER_SYM {} - | DELAY_KEY_WRITE_SYM {} - | DES_KEY_FILE {} - | DIAGNOSTICS_SYM {} - | DIRECTORY_SYM {} - | DISABLE_SYM {} - | DISCARD {} - | DISK_SYM {} - | DUMPFILE {} - | DUPLICATE_SYM {} - | DYNAMIC_SYM {} - | ENDS_SYM {} - | ENGINE_SYM {} - | ENGINES_SYM {} - | ERROR_SYM {} - | ERRORS {} - | ESCAPE_SYM {} - | EVENT_SYM {} - | EVENTS_SYM {} - | EVERY_SYM {} - | EXCHANGE_SYM {} - | EXPANSION_SYM {} - | EXPORT_SYM {} - | EXTENDED_SYM {} - | EXTENT_SIZE_SYM {} - | FAULTS_SYM {} - | FAST_SYM {} - | FOUND_SYM {} - | ENABLE_SYM {} - | FULL {} - | FILE_SYM {} - | FIRST_SYM {} - | GENERAL {} - | GENERATED_SYM {} - | GET_FORMAT {} - | GRANTS {} - | GLOBAL_SYM {} - | HASH_SYM {} - | HARD_SYM {} - | INVISIBLE_SYM {} - | HOSTS_SYM {} - | HOUR_SYM {} - | ID_SYM {} - | IDENTIFIED_SYM {} - | IGNORE_SERVER_IDS_SYM {} - | INCREMENT_SYM {} - | IMMEDIATE_SYM {} /* SQL-2003-R */ - | INVOKER_SYM {} - | IMPORT {} - | INDEXES {} - | INITIAL_SIZE_SYM {} - | IO_SYM {} - | IPC_SYM {} - | ISOLATION {} - | ISOPEN_SYM {} - | ISSUER_SYM {} - | INSERT_METHOD {} - | KEY_BLOCK_SIZE {} - | LAST_VALUE {} - | LAST_SYM {} - | LASTVAL_SYM {} - | LEAVES {} - | LESS_SYM {} - | LEVEL_SYM {} - | LIST_SYM {} - | LOCAL_SYM {} - | LOCKS_SYM {} - | LOGFILE_SYM {} - | LOGS_SYM {} - | MAX_ROWS {} - | MASTER_SYM {} - | MASTER_HEARTBEAT_PERIOD_SYM {} - | MASTER_GTID_POS_SYM {} - | MASTER_HOST_SYM {} - | MASTER_PORT_SYM {} - | MASTER_LOG_FILE_SYM {} - | MASTER_LOG_POS_SYM {} - | MASTER_USER_SYM {} - | MASTER_USE_GTID_SYM {} - | MASTER_PASSWORD_SYM {} - | MASTER_SERVER_ID_SYM {} - | MASTER_CONNECT_RETRY_SYM {} - | MASTER_DELAY_SYM {} - | MASTER_SSL_SYM {} - | MASTER_SSL_CA_SYM {} - | MASTER_SSL_CAPATH_SYM {} - | MASTER_SSL_CERT_SYM {} - | MASTER_SSL_CIPHER_SYM {} - | MASTER_SSL_CRL_SYM {} - | MASTER_SSL_CRLPATH_SYM {} - | MASTER_SSL_KEY_SYM {} - | MAX_CONNECTIONS_PER_HOUR {} - | MAX_QUERIES_PER_HOUR {} - | MAX_SIZE_SYM {} - | MAX_STATEMENT_TIME_SYM {} - | MAX_UPDATES_PER_HOUR {} - | MAX_USER_CONNECTIONS_SYM {} - | MEMORY_SYM {} - | MERGE_SYM {} - | MESSAGE_TEXT_SYM {} - | MICROSECOND_SYM {} - | MIGRATE_SYM {} - | MINUTE_SYM {} - | MINVALUE_SYM {} - | MIN_ROWS {} - | MODIFY_SYM {} - | MODE_SYM {} - | MONTH_SYM {} - | MUTEX_SYM {} - | MYSQL_SYM {} - | MYSQL_ERRNO_SYM {} - | NAME_SYM {} - | NAMES_SYM {} - | NEXT_SYM {} - | NEXTVAL_SYM {} - | NEW_SYM {} - | NOCACHE_SYM {} - | NOCYCLE_SYM {} - | NOMINVALUE_SYM {} - | NOMAXVALUE_SYM {} - | NO_WAIT_SYM {} - | NOWAIT_SYM {} - | NODEGROUP_SYM {} - | NONE_SYM {} - | NOTFOUND_SYM {} - | OF_SYM {} /* SQL-1999-R, Oracle-R */ - | OFFSET_SYM {} - | OLD_PASSWORD_SYM {} - | ONE_SYM {} - | ONLINE_SYM {} - | ONLY_SYM {} - | PACK_KEYS_SYM {} - | PAGE_SYM {} - | PARTIAL {} - | PARTITIONING_SYM {} - | PARTITIONS_SYM {} - | PASSWORD_SYM {} - | PERSISTENT_SYM {} - | PHASE_SYM {} - | PLUGIN_SYM {} - | PLUGINS_SYM {} - | PRESERVE_SYM {} - | PREV_SYM {} - | PREVIOUS_SYM {} - | PRIVILEGES {} - | PROCESS {} - | PROCESSLIST_SYM {} - | PROFILE_SYM {} - | PROFILES_SYM {} - | PROXY_SYM {} - | QUARTER_SYM {} - | QUERY_SYM {} - | QUICK {} - | READ_ONLY_SYM {} - | REBUILD_SYM {} - | RECOVER_SYM {} - | REDO_BUFFER_SIZE_SYM {} - | REDOFILE_SYM {} - | REDUNDANT_SYM {} - | RELAY {} - | RELAYLOG_SYM {} - | RELAY_LOG_FILE_SYM {} - | RELAY_LOG_POS_SYM {} - | RELAY_THREAD {} - | RELOAD {} - | REORGANIZE_SYM {} - | REPEATABLE_SYM {} - | REPLICATION {} - | RESOURCES {} - | RESTART_SYM {} - | RESUME_SYM {} - | RETURNED_SQLSTATE_SYM {} - | RETURNS_SYM {} - | REUSE_SYM {} - | REVERSE_SYM {} - | ROLE_SYM {} - | ROLLUP_SYM {} - | ROUTINE_SYM {} - | ROWCOUNT_SYM {} - | ROW_COUNT_SYM {} - | ROW_FORMAT_SYM {} - | RTREE_SYM {} - | SCHEDULE_SYM {} - | SCHEMA_NAME_SYM {} - | SECOND_SYM {} - | SEQUENCE_SYM {} - | SERIALIZABLE_SYM {} - | SESSION_SYM {} - | SETVAL_SYM {} - | SIMPLE_SYM {} - | SHARE_SYM {} - | SLAVE_POS_SYM {} - | SLOW {} - | SNAPSHOT_SYM {} - | SOFT_SYM {} - | SOUNDS_SYM {} - | SOURCE_SYM {} - | SQL_CACHE_SYM {} - | SQL_BUFFER_RESULT {} - | SQL_NO_CACHE_SYM {} - | SQL_THREAD {} - | STARTS_SYM {} - | STATEMENT_SYM {} - | STATUS_SYM {} - | STORAGE_SYM {} - | STRING_SYM {} - | SUBCLASS_ORIGIN_SYM {} - | SUBDATE_SYM {} - | SUBJECT_SYM {} - | SUBPARTITION_SYM {} - | SUBPARTITIONS_SYM {} - | SUPER_SYM {} - | SUSPEND_SYM {} - | SWAPS_SYM {} - | SWITCHES_SYM {} - | TABLE_NAME_SYM {} - | TABLES {} - | TABLE_CHECKSUM_SYM {} - | TABLESPACE {} - | TEMPORARY {} - | TEMPTABLE_SYM {} - | THAN_SYM {} - | TRANSACTION_SYM {} - | TRANSACTIONAL_SYM {} - | TRIGGERS_SYM {} - | TRIM_ORACLE {} - | TIMESTAMP_ADD {} - | TIMESTAMP_DIFF {} - | TYPES_SYM {} - | TYPE_SYM {} - | UDF_RETURNS_SYM {} - | UNCOMMITTED_SYM {} - | UNDEFINED_SYM {} - | UNDO_BUFFER_SIZE_SYM {} - | UNDOFILE_SYM {} - | UNKNOWN_SYM {} - | UNTIL_SYM {} - | USER_SYM {} - | USE_FRM {} - | VARIABLES {} - | VIEW_SYM {} - | VIRTUAL_SYM {} - | VALUE_SYM {} - | WARNINGS {} - | WAIT_SYM {} - | WEEK_SYM {} - | WEIGHT_STRING_SYM {} - | WORK_SYM {} - | X509_SYM {} - | XML_SYM {} - | VIA_SYM {} + | CURRENT_SYM + | CURSOR_NAME_SYM + | CYCLE_SYM + | DATA_SYM + | DATAFILE_SYM + | DATE_FORMAT_SYM + | DAY_SYM + | DECODE_SYM + | DEFINER_SYM + | DELAY_KEY_WRITE_SYM + | DES_KEY_FILE + | DIAGNOSTICS_SYM + | DIRECTORY_SYM + | DISABLE_SYM + | DISCARD + | DISK_SYM + | DUMPFILE + | DUPLICATE_SYM + | DYNAMIC_SYM + | ENDS_SYM + | ENGINE_SYM + | ENGINES_SYM + | ERROR_SYM + | ERRORS + | ESCAPE_SYM + | EVENT_SYM + | EVENTS_SYM + | EVERY_SYM + + | EXCHANGE_SYM + | EXPANSION_SYM + | EXPORT_SYM + | EXTENDED_SYM + | EXTENT_SIZE_SYM + | FAULTS_SYM + | FAST_SYM + | FOUND_SYM + | ENABLE_SYM + | FULL + | FILE_SYM + | FIRST_SYM + | GENERAL + | GENERATED_SYM + | GET_FORMAT + | GRANTS + | HASH_SYM + | HARD_SYM + | HOSTS_SYM + | HOUR_SYM + | ID_SYM + | IDENTIFIED_SYM + | IGNORE_SERVER_IDS_SYM + | INCREMENT_SYM + | IMMEDIATE_SYM + | INVOKER_SYM + | IMPORT + | INDEXES + | INITIAL_SIZE_SYM + | IO_SYM + | IPC_SYM + | ISOLATION + | ISOPEN_SYM + | ISSUER_SYM + | INSERT_METHOD + | INVISIBLE_SYM + | KEY_BLOCK_SIZE + | LAST_VALUE + | LAST_SYM + | LASTVAL_SYM + | LEAVES + | LESS_SYM + | LEVEL_SYM + | LIST_SYM + | LOCKS_SYM + | LOGFILE_SYM + | LOGS_SYM + | MAX_ROWS + | MASTER_SYM + | MASTER_HEARTBEAT_PERIOD_SYM + | MASTER_GTID_POS_SYM + | MASTER_HOST_SYM + | MASTER_PORT_SYM + | MASTER_LOG_FILE_SYM + | MASTER_LOG_POS_SYM + | MASTER_USER_SYM + | MASTER_USE_GTID_SYM + | MASTER_PASSWORD_SYM + | MASTER_SERVER_ID_SYM + | MASTER_CONNECT_RETRY_SYM + | MASTER_DELAY_SYM + | MASTER_SSL_SYM + | MASTER_SSL_CA_SYM + | MASTER_SSL_CAPATH_SYM + | MASTER_SSL_CERT_SYM + | MASTER_SSL_CIPHER_SYM + | MASTER_SSL_CRL_SYM + | MASTER_SSL_CRLPATH_SYM + | MASTER_SSL_KEY_SYM + | MAX_CONNECTIONS_PER_HOUR + | MAX_QUERIES_PER_HOUR + | MAX_SIZE_SYM + | MAX_STATEMENT_TIME_SYM + | MAX_UPDATES_PER_HOUR + | MAX_USER_CONNECTIONS_SYM + | MEMORY_SYM + | MERGE_SYM + | MESSAGE_TEXT_SYM + | MICROSECOND_SYM + | MIGRATE_SYM + | MINUTE_SYM + | MINVALUE_SYM + | MIN_ROWS + | MODIFY_SYM + | MODE_SYM + | MONTH_SYM + | MUTEX_SYM + | MYSQL_SYM + | MYSQL_ERRNO_SYM + | NAME_SYM + | NAMES_SYM + | NEXT_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | NEXTVAL_SYM + | NEW_SYM + | NOCACHE_SYM + | NOCYCLE_SYM + | NOMINVALUE_SYM + | NOMAXVALUE_SYM + | NO_WAIT_SYM + | NOWAIT_SYM + | NODEGROUP_SYM + | NONE_SYM + | NOTFOUND_SYM + | OF_SYM + | OFFSET_SYM + | OLD_PASSWORD_SYM + | ONE_SYM + | ONLINE_SYM + | ONLY_SYM + + | PACK_KEYS_SYM + | PAGE_SYM + | PARTIAL + | PARTITIONING_SYM + | PARTITIONS_SYM + | PASSWORD_SYM + | PERSISTENT_SYM + | PHASE_SYM + | PLUGIN_SYM + | PLUGINS_SYM + | PRESERVE_SYM + | PREV_SYM + | PREVIOUS_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | PRIVILEGES + | PROCESS + | PROCESSLIST_SYM + | PROFILE_SYM + | PROFILES_SYM + | PROXY_SYM + | QUARTER_SYM + | QUERY_SYM + | QUICK + + | READ_ONLY_SYM + | REBUILD_SYM + | RECOVER_SYM + | REDO_BUFFER_SIZE_SYM + | REDOFILE_SYM + | REDUNDANT_SYM + | RELAY + | RELAYLOG_SYM + | RELAY_LOG_FILE_SYM + | RELAY_LOG_POS_SYM + | RELAY_THREAD + | RELOAD + | REORGANIZE_SYM + | REPEATABLE_SYM + | REPLICATION + | RESOURCES + | RESTART_SYM + | RESUME_SYM + | RETURNED_SQLSTATE_SYM + | RETURNS_SYM + | REUSE_SYM + | REVERSE_SYM + | ROLE_SYM + | ROLLUP_SYM + | ROUTINE_SYM + | ROWCOUNT_SYM + | ROW_COUNT_SYM + | ROW_FORMAT_SYM + | RTREE_SYM + | SCHEDULE_SYM + | SCHEMA_NAME_SYM + | SECOND_SYM + | SEQUENCE_SYM + | SERIALIZABLE_SYM + | SETVAL_SYM + | SIMPLE_SYM + | SHARE_SYM + | SLAVE_POS_SYM + | SLOW + | SNAPSHOT_SYM + | SOFT_SYM + | SOUNDS_SYM + | SOURCE_SYM + | SQL_CACHE_SYM + | SQL_BUFFER_RESULT + | SQL_NO_CACHE_SYM + | SQL_THREAD + | STARTS_SYM + | STATEMENT_SYM + | STATUS_SYM + | STORAGE_SYM + | STRING_SYM + | SUBCLASS_ORIGIN_SYM + | SUBDATE_SYM + | SUBJECT_SYM + | SUBPARTITION_SYM + | SUBPARTITIONS_SYM + | SUPER_SYM + | SUSPEND_SYM + | SWAPS_SYM + | SWITCHES_SYM + | TABLE_NAME_SYM + | TABLES + | TABLE_CHECKSUM_SYM + | TABLESPACE + | TEMPORARY + | TEMPTABLE_SYM + | THAN_SYM + | TRANSACTION_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 + | TRANSACTIONAL_SYM + | TRIGGERS_SYM + | TRIM_ORACLE + | TIMESTAMP_ADD + | TIMESTAMP_DIFF + | TYPES_SYM + | TYPE_SYM + | UDF_RETURNS_SYM + | UNCOMMITTED_SYM + | UNDEFINED_SYM + | UNDO_BUFFER_SIZE_SYM + | UNDOFILE_SYM + | UNKNOWN_SYM + | UNTIL_SYM + | USER_SYM + | USE_FRM + | VARIABLES + | VIEW_SYM + | VIRTUAL_SYM + | VALUE_SYM + | WARNINGS + | WAIT_SYM + | WEEK_SYM + | WEIGHT_STRING_SYM + | WORK_SYM + | X509_SYM + | XML_SYM + | VIA_SYM ; /* @@ -15602,7 +16099,7 @@ set: set_stmt_option_value_following_option_type_list { LEX *lex= Lex; - if (lex->table_or_sp_used()) + if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT")); lex->stmt_var_list= lex->var_list; lex->var_list.empty(); @@ -15621,8 +16118,8 @@ set_assign: } set_expr_or_default { - if (Lex->set_variable(&$1, $4) || - sp_create_assignment_instr(thd, yychar == YYEMPTY)) + if (unlikely(Lex->set_variable(&$1, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | ident_directly_assignable '.' ident SET_VAR @@ -15636,14 +16133,14 @@ set_assign: { LEX *lex= Lex; DBUG_ASSERT(lex->var_list.is_empty()); - if (lex->set_variable(&$1, &$3, $6) || - lex->sphead->restore_lex(thd)) + if (unlikely(lex->set_variable(&$1, &$3, $6)) || + unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } | colon_with_pos ident '.' ident SET_VAR { LEX *lex= Lex; - if (!lex->is_trigger_new_or_old_reference(&$2)) + if (unlikely(!lex->is_trigger_new_or_old_reference(&$2))) { thd->parse_error(ER_SYNTAX_ERROR, $1); MYSQL_YYABORT; @@ -15655,8 +16152,8 @@ set_assign: set_expr_or_default { LEX_CSTRING tmp= { $2.str, $2.length }; - if (Lex->set_trigger_field(&tmp, &$4, $7) || - sp_create_assignment_instr(thd, yychar == YYEMPTY)) + if (unlikely(Lex->set_trigger_field(&tmp, &$4, $7)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } ; @@ -15675,7 +16172,7 @@ set_stmt_option_value_following_option_type_list: start_option_value_list: option_value_no_option_type { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } option_value_list_continued @@ -15685,7 +16182,7 @@ start_option_value_list: } transaction_characteristics { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | option_type @@ -15700,14 +16197,14 @@ start_option_value_list: start_option_value_list_following_option_type: option_value_following_option_type { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } option_value_list_continued | TRANSACTION_SYM transaction_characteristics { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; @@ -15724,8 +16221,8 @@ option_value_list: } option_value { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | option_value_list ',' { @@ -15733,8 +16230,8 @@ option_value_list: } option_value { - if (sp_create_assignment_instr(thd, yychar == YYEMPTY)) - MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; @@ -15772,17 +16269,17 @@ opt_var_ident_type: option_value_following_option_type: ident equal set_expr_or_default { - if (Lex->set_system_variable(Lex->option_type, &$1, $3)) + if (unlikely(Lex->set_system_variable(Lex->option_type, &$1, $3))) MYSQL_YYABORT; } | ident '.' ident equal set_expr_or_default { - if (Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5)) + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default { - if (Lex->set_default_system_variable(Lex->option_type, &$3, $5)) + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) MYSQL_YYABORT; } ; @@ -15791,37 +16288,37 @@ option_value_following_option_type: option_value_no_option_type: ident equal set_expr_or_default { - if (Lex->set_variable(&$1, $3)) + if (unlikely(Lex->set_variable(&$1, $3))) MYSQL_YYABORT; } | ident '.' ident equal set_expr_or_default { - if (Lex->set_variable(&$1, &$3, $5)) + if (unlikely(Lex->set_variable(&$1, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default { - if (Lex->set_default_system_variable(Lex->option_type, &$3, $5)) + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) MYSQL_YYABORT; } | '@' ident_or_text equal expr { - if (Lex->set_user_variable(thd, &$2, $4)) + if (unlikely(Lex->set_user_variable(thd, &$2, $4))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident equal set_expr_or_default + | '@' '@' opt_var_ident_type ident_sysvar_name equal set_expr_or_default { - if (Lex->set_system_variable($3, &$4, $6)) + if (unlikely(Lex->set_system_variable($3, &$4, $6))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident '.' ident equal set_expr_or_default + | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal set_expr_or_default { - if (Lex->set_system_variable(thd, $3, &$4, &$6, $8)) + if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $8))) MYSQL_YYABORT; } | '@' '@' opt_var_ident_type DEFAULT '.' ident equal set_expr_or_default { - if (Lex->set_default_system_variable($3, &$6, $8)) + if (unlikely(Lex->set_default_system_variable($3, &$6, $8))) MYSQL_YYABORT; } | charset old_or_new_charset_name_or_default @@ -15834,7 +16331,7 @@ option_value_no_option_type: set_var_collation_client(cs2, thd->variables.collation_database, cs2)); - if (var == NULL) + if (unlikely(var == NULL)) MYSQL_YYABORT; lex->var_list.push_back(var, thd->mem_root); } @@ -15843,7 +16340,7 @@ option_value_no_option_type: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; LEX_CSTRING names= { STRING_WITH_LEN("names") }; - if (spc && spc->find_variable(&names, false)) + if (unlikely(spc && spc->find_variable(&names, false))) my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); else thd->parse_error(); @@ -15856,7 +16353,7 @@ option_value_no_option_type: CHARSET_INFO *cs3; cs2= $2 ? $2 : global_system_variables.character_set_client; cs3= $3 ? $3 : cs2; - if (!my_charset_same(cs2, cs3)) + if (unlikely(!my_charset_same(cs2, cs3))) { my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), cs3->name, cs2->csname); @@ -15864,23 +16361,24 @@ option_value_no_option_type: } set_var_collation_client *var; var= new (thd->mem_root) set_var_collation_client(cs3, cs3, cs3); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } | DEFAULT ROLE_SYM grant_role { LEX *lex = Lex; LEX_USER *user; - if (!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; user->user= current_user; set_var_default_role *var= (new (thd->mem_root) set_var_default_role(user, $3->user)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); + thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; @@ -15890,9 +16388,9 @@ option_value_no_option_type: LEX *lex = Lex; set_var_default_role *var= (new (thd->mem_root) set_var_default_role($5, $3->user)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; @@ -15901,18 +16399,18 @@ option_value_no_option_type: { LEX *lex = Lex; set_var_role *var= new (thd->mem_root) set_var_role($2); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } | PASSWORD_SYM opt_for_user text_or_password { LEX *lex = Lex; set_var_password *var= (new (thd->mem_root) set_var_password(lex->definer)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; @@ -15932,16 +16430,17 @@ transaction_access_mode: { LEX *lex=Lex; Item *item= new (thd->mem_root) Item_int(thd, (int32) $1); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; set_var *var= (new (thd->mem_root) set_var(thd, lex->option_type, find_sys_var(thd, "tx_read_only"), &null_clex_str, item)); - if (var == NULL) + if (unlikely(var == NULL)) + MYSQL_YYABORT; + if (unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } ; @@ -15950,16 +16449,16 @@ isolation_level: { LEX *lex=Lex; Item *item= new (thd->mem_root) Item_int(thd, (int32) $3); - if (item == NULL) + if (unlikely(item == NULL)) MYSQL_YYABORT; set_var *var= (new (thd->mem_root) set_var(thd, lex->option_type, find_sys_var(thd, "tx_isolation"), &null_clex_str, item)); - if (var == NULL) + if (unlikely(var == NULL) || + unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; - lex->var_list.push_back(var, thd->mem_root); } ; @@ -15982,9 +16481,10 @@ opt_for_user: sp_pcontext *spc= lex->spcont; LEX_CSTRING pw= { STRING_WITH_LEN("password") }; - if (spc && spc->find_variable(&pw, false)) + if (unlikely(spc && spc->find_variable(&pw, false))) my_yyabort_error((ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str)); - if (!(lex->definer= (LEX_USER*) thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!(lex->definer= (LEX_USER*) + thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; lex->definer->user= current_user; lex->definer->plugin= empty_clex_str; @@ -16011,19 +16511,19 @@ set_expr_or_default: | ON { $$=new (thd->mem_root) Item_string_sys(thd, "ON", 2); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | ALL { $$=new (thd->mem_root) Item_string_sys(thd, "ALL", 3); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } | BINARY { $$=new (thd->mem_root) Item_string_sys(thd, "binary", 6); - if ($$ == NULL) + if (unlikely($$ == NULL)) MYSQL_YYABORT; } ; @@ -16035,7 +16535,7 @@ lock: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK")); lex->sql_command= SQLCOM_LOCK_TABLES; } @@ -16048,14 +16548,14 @@ opt_lock_wait_timeout: {} | WAIT_SYM ulong_num { - if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2) || - set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2)) + if (unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2)) || + unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))) MYSQL_YYABORT; } | NOWAIT_SYM { - if (set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0) || - set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0)) + if (unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0)) || + unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))) MYSQL_YYABORT; } ; @@ -16075,12 +16575,13 @@ table_lock: { thr_lock_type lock_type= (thr_lock_type) $3; bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE); - if (!Select->add_table_to_list(thd, $1, $2, 0, lock_type, + if (unlikely(!Select-> + add_table_to_list(thd, $1, $2, 0, lock_type, (lock_for_write ? lock_type == TL_WRITE_CONCURRENT_INSERT ? MDL_SHARED_WRITE : MDL_SHARED_NO_READ_WRITE : - MDL_SHARED_READ))) + MDL_SHARED_READ)))) MYSQL_YYABORT; } ; @@ -16102,7 +16603,7 @@ unlock: { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK")); lex->sql_command= SQLCOM_UNLOCK_TABLES; } @@ -16118,43 +16619,46 @@ handler: HANDLER_SYM table_ident OPEN_SYM opt_table_alias { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->sql_command = SQLCOM_HA_OPEN; - if (!lex->current_select->add_table_to_list(thd, $2, $4, 0)) + if (unlikely(!lex->current_select->add_table_to_list(thd, $2, $4, + 0))) MYSQL_YYABORT; } | HANDLER_SYM table_ident_nodb CLOSE_SYM { LEX *lex= Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->sql_command = SQLCOM_HA_CLOSE; - if (!lex->current_select->add_table_to_list(thd, $2, 0, 0)) + if (unlikely(!lex->current_select->add_table_to_list(thd, $2, 0, + 0))) MYSQL_YYABORT; } | HANDLER_SYM table_ident_nodb READ_SYM { LEX *lex=Lex; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER")); lex->expr_allows_subselect= FALSE; lex->sql_command = SQLCOM_HA_READ; lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ Item *one= new (thd->mem_root) Item_int(thd, (int32) 1); - if (one == NULL) + if (unlikely(one == NULL)) MYSQL_YYABORT; lex->current_select->select_limit= one; lex->current_select->offset_limit= 0; lex->limit_rows_examined= 0; - if (!lex->current_select->add_table_to_list(thd, $2, 0, 0)) + if (unlikely(!lex->current_select->add_table_to_list(thd, $2, 0, + 0))) MYSQL_YYABORT; } handler_read_or_scan opt_where_clause opt_limit_clause { Lex->expr_allows_subselect= TRUE; /* Stored functions are not supported for HANDLER READ. */ - if (Lex->uses_stored_routines()) + if (unlikely(Lex->uses_stored_routines())) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "stored functions in HANDLER ... READ"); @@ -16183,7 +16687,7 @@ handler_rkey_function: LEX *lex=Lex; lex->ha_read_mode = RKEY; lex->ha_rkey_mode=$1; - if (!(lex->insert_list= new (thd->mem_root) List_item)) + if (unlikely(!(lex->insert_list= new (thd->mem_root) List_item))) MYSQL_YYABORT; } '(' values ')' @@ -16214,24 +16718,26 @@ revoke_command: } | grant_privileges ON FUNCTION_SYM grant_ident FROM user_and_role_list { - if (Lex->add_grant_command(thd, SQLCOM_REVOKE, TYPE_ENUM_FUNCTION)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_FUNCTION))) MYSQL_YYABORT; } | grant_privileges ON PROCEDURE_SYM grant_ident FROM user_and_role_list { - if (Lex->add_grant_command(thd, SQLCOM_REVOKE, TYPE_ENUM_PROCEDURE)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } | grant_privileges ON PACKAGE_SYM grant_ident FROM user_and_role_list { - if (Lex->add_grant_command(thd, SQLCOM_REVOKE, - TYPE_ENUM_PACKAGE)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_PACKAGE))) MYSQL_YYABORT; } | grant_privileges ON PACKAGE_SYM BODY_SYM grant_ident FROM user_and_role_list { - if (Lex->add_grant_command(thd, SQLCOM_REVOKE, - TYPE_ENUM_PACKAGE_BODY)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_PACKAGE_BODY))) MYSQL_YYABORT; } | ALL opt_privileges ',' GRANT OPTION FROM user_and_role_list @@ -16248,7 +16754,7 @@ revoke_command: | admin_option_for_role FROM user_and_role_list { Lex->sql_command= SQLCOM_REVOKE_ROLE; - if (Lex->users_list.push_front($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_front($1, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16276,27 +16782,29 @@ grant_command: | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (Lex->add_grant_command(thd, SQLCOM_GRANT, TYPE_ENUM_FUNCTION)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_FUNCTION))) MYSQL_YYABORT; } | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (Lex->add_grant_command(thd, SQLCOM_GRANT, TYPE_ENUM_PROCEDURE)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } | grant_privileges ON PACKAGE_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (Lex->add_grant_command(thd, SQLCOM_GRANT, - TYPE_ENUM_PACKAGE)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_PACKAGE))) MYSQL_YYABORT; } | grant_privileges ON PACKAGE_SYM BODY_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { - if (Lex->add_grant_command(thd, SQLCOM_GRANT, - TYPE_ENUM_PACKAGE_BODY)) + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_PACKAGE_BODY))) MYSQL_YYABORT; } | PROXY_SYM ON user TO_SYM grant_list opt_grant_option @@ -16311,7 +16819,7 @@ grant_command: LEX *lex= Lex; lex->sql_command= SQLCOM_GRANT_ROLE; /* The first role is the one that is granted */ - if (Lex->users_list.push_front($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_front($1, thd->mem_root))) MYSQL_YYABORT; } @@ -16328,12 +16836,12 @@ opt_with_admin_option: role_list: grant_role { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | role_list ',' grant_role { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16341,7 +16849,7 @@ role_list: current_role: CURRENT_ROLE optional_braces { - if (!($$=(LEX_USER*) thd->calloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->calloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user= current_role; $$->reset_auth(); @@ -16355,17 +16863,17 @@ grant_role: /* trim end spaces (as they'll be lost in mysql.user anyway) */ $1.length= cs->cset->lengthsp(cs, $1.str, $1.length); ((char*) $1.str)[$1.length] = '\0'; - if ($1.length == 0) + if (unlikely($1.length == 0)) my_yyabort_error((ER_INVALID_ROLE, MYF(0), "")); - if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + if (unlikely(!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))) MYSQL_YYABORT; $$->user= $1; $$->host= empty_clex_str; $$->reset_auth(); - if (check_string_char_length(&$$->user, ER_USERNAME, - username_char_length, - cs, 0)) + if (unlikely(check_string_char_length(&$$->user, ER_USERNAME, + username_char_length, + cs, 0))) MYSQL_YYABORT; } | current_role @@ -16434,6 +16942,7 @@ object_privilege: | EVENT_SYM { Lex->grant |= EVENT_ACL;} | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; } | CREATE TABLESPACE { Lex->grant |= CREATE_TABLESPACE_ACL; } + | DELETE_SYM HISTORY_SYM { Lex->grant |= DELETE_HISTORY_ACL; } ; opt_and: @@ -16450,21 +16959,21 @@ require_list_element: SUBJECT_SYM TEXT_STRING { LEX *lex=Lex; - if (lex->x509_subject) + if (unlikely(lex->x509_subject)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SUBJECT")); lex->x509_subject=$2.str; } | ISSUER_SYM TEXT_STRING { LEX *lex=Lex; - if (lex->x509_issuer) + if (unlikely(lex->x509_issuer)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "ISSUER")); lex->x509_issuer=$2.str; } | CIPHER_SYM TEXT_STRING { LEX *lex=Lex; - if (lex->ssl_cipher) + if (unlikely(lex->ssl_cipher)) my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CIPHER")); lex->ssl_cipher=$2.str; } @@ -16474,11 +16983,11 @@ grant_ident: '*' { LEX *lex= Lex; - if (lex->copy_db_to(&lex->current_select->db)) + if (unlikely(lex->copy_db_to(&lex->current_select->db))) MYSQL_YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = DB_ACLS & ~GRANT_ACL; - else if (lex->columns.elements) + else if (unlikely(lex->columns.elements)) my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | ident '.' '*' @@ -16487,7 +16996,7 @@ grant_ident: lex->current_select->db= $1; if (lex->grant == GLOBAL_ACLS) lex->grant = DB_ACLS & ~GRANT_ACL; - else if (lex->columns.elements) + else if (unlikely(lex->columns.elements)) my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | '*' '.' '*' @@ -16496,14 +17005,15 @@ grant_ident: lex->current_select->db= null_clex_str; if (lex->grant == GLOBAL_ACLS) lex->grant= GLOBAL_ACLS & ~GRANT_ACL; - else if (lex->columns.elements) + else if (unlikely(lex->columns.elements)) my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0))); } | table_ident { LEX *lex=Lex; - if (!lex->current_select->add_table_to_list(thd, $1,NULL, - TL_OPTION_UPDATING)) + if (unlikely(!lex->current_select-> + add_table_to_list(thd, $1,NULL, + TL_OPTION_UPDATING))) MYSQL_YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; @@ -16513,12 +17023,12 @@ grant_ident: user_list: user { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | user_list ',' user { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16526,12 +17036,12 @@ user_list: grant_list: grant_user { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | grant_list ',' grant_user { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16539,12 +17049,12 @@ grant_list: user_and_role_list: user_or_role { - if (Lex->users_list.push_back($1, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($1, thd->mem_root))) MYSQL_YYABORT; } | user_and_role_list ',' user_or_role { - if (Lex->users_list.push_back($3, thd->mem_root)) + if (unlikely(Lex->users_list.push_back($3, thd->mem_root))) MYSQL_YYABORT; } ; @@ -16557,7 +17067,7 @@ grant_user: { $$= $1; $1->pwtext= $4; - if (Lex->sql_command == SQLCOM_REVOKE) + if (unlikely(Lex->sql_command == SQLCOM_REVOKE)) MYSQL_YYABORT; } | user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING @@ -16599,7 +17109,7 @@ column_list_id: ident { String *new_str= new (thd->mem_root) String((const char*) $1.str,$1.length,system_charset_info); - if (new_str == NULL) + if (unlikely(new_str == NULL)) MYSQL_YYABORT; List_iterator <LEX_COLUMN> iter(Lex->columns); class LEX_COLUMN *point; @@ -16617,7 +17127,7 @@ column_list_id: { LEX_COLUMN *col= (new (thd->mem_root) LEX_COLUMN(*new_str,lex->which_columns)); - if (col == NULL) + if (unlikely(col == NULL)) MYSQL_YYABORT; lex->columns.push_back(col, thd->mem_root); } @@ -16816,7 +17326,7 @@ union_clause: union_list: unit_type_decl union_option { - if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) + if (unlikely(Lex->add_select_to_union_list((bool)$2, $1, TRUE))) MYSQL_YYABORT; } union_list_part2 @@ -16832,7 +17342,7 @@ union_list: union_list_view: unit_type_decl union_option { - if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) + if (unlikely(Lex->add_select_to_union_list((bool)$2, $1, TRUE))) MYSQL_YYABORT; } query_expression_body_view @@ -16873,7 +17383,7 @@ order_or_limit: union_head_non_top: unit_type_decl union_option { - if (Lex->add_select_to_union_list((bool)$2, $1, FALSE)) + if (unlikely(Lex->add_select_to_union_list((bool)$2, $1, FALSE))) MYSQL_YYABORT; } ; @@ -16884,6 +17394,24 @@ union_option: | ALL { $$=0; } ; +simple_table: + query_specification { $$= $1; } + | table_value_constructor { $$= $1; } + ; + +table_value_constructor: + VALUES + { + Lex->tvc_start(); + } + values_list + { + $$= Lex->current_select; + if (Lex->tvc_finalize()) + MYSQL_YYABORT; + } + ; + /* Corresponds to the SQL Standard <query specification> ::= @@ -16901,13 +17429,13 @@ query_specification: ; query_term_union_not_ready: - query_specification order_or_limit opt_select_lock_type { $$= $1; } + simple_table order_or_limit opt_select_lock_type { $$= $1; } | '(' select_paren_derived ')' union_order_or_limit { $$= $2; } ; query_term_union_ready: - query_specification opt_select_lock_type { $$= $1; } - | '(' select_paren_derived ')' { $$= $2; } + simple_table opt_select_lock_type { $$= $1; } + | '(' select_paren_derived ')' { $$= $2; } ; query_expression_body: @@ -16928,8 +17456,8 @@ subselect: subselect_start: { LEX *lex=Lex; - if (!lex->expr_allows_subselect || - lex->sql_command == (int)SQLCOM_PURGE) + if (unlikely(!lex->expr_allows_subselect || + lex->sql_command == (int)SQLCOM_PURGE)) { thd->parse_error(); MYSQL_YYABORT; @@ -16941,7 +17469,7 @@ subselect_start: (SELECT .. ) UNION ... becomes SELECT * FROM ((SELECT ...) UNION ...) */ - if (mysql_new_select(Lex, 1, NULL)) + if (unlikely(mysql_new_select(Lex, 1, NULL))) MYSQL_YYABORT; } ; @@ -16986,7 +17514,7 @@ query_expression_option: STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } | HIGH_PRIORITY { - if (check_simple_select()) + if (unlikely(Lex->check_simple_select(&$1))) MYSQL_YYABORT; YYPS->m_lock_type= TL_READ_HIGH_PRIORITY; YYPS->m_mdl_type= MDL_SHARED_READ; @@ -16998,13 +17526,13 @@ query_expression_option: | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; } | SQL_BUFFER_RESULT { - if (check_simple_select()) + if (unlikely(Lex->check_simple_select(&$1))) MYSQL_YYABORT; Select->options|= OPTION_BUFFER_RESULT; } | SQL_CALC_FOUND_ROWS { - if (check_simple_select()) + if (unlikely(Lex->check_simple_select(&$1))) MYSQL_YYABORT; Select->options|= OPTION_FOUND_ROWS; } @@ -17116,6 +17644,9 @@ view_select: */ query_expression_body_view: SELECT_SYM select_options_and_item_list select_init3_view + | table_value_constructor + | table_value_constructor union_order_or_limit + | table_value_constructor union_list_view | '(' select_paren_view ')' | '(' select_paren_view ')' union_order_or_limit | '(' select_paren_view ')' union_list_view @@ -17160,7 +17691,7 @@ trigger_tail: remember_name opt_if_not_exists { - if (Lex->add_create_options_with_check($2)) + if (unlikely(Lex->add_create_options_with_check($2))) MYSQL_YYABORT; } sp_name @@ -17187,7 +17718,7 @@ trigger_tail: LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; - if (lex->sphead) + if (unlikely(lex->sphead)) my_yyabort_error((ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER")); lex->stmt_definition_begin= $1; @@ -17197,7 +17728,7 @@ trigger_tail: (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17); lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr(); - if (!lex->make_sp_head(thd, $4, &sp_handler_trigger)) + if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger))) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); @@ -17206,14 +17737,14 @@ trigger_tail: { /* $20 */ LEX *lex= Lex; sp_head *sp= lex->sphead; - if (sp->check_unresolved_goto()) + if (unlikely(sp->check_unresolved_goto())) MYSQL_YYABORT; lex->sql_command= SQLCOM_CREATE_TRIGGER; sp->set_stmt_end(thd); sp->restore_thd_mem_root(thd); - if (sp->is_not_allowed_in_function("trigger")) + if (unlikely(sp->is_not_allowed_in_function("trigger"))) MYSQL_YYABORT; /* @@ -17221,11 +17752,11 @@ trigger_tail: sp_proc_stmt alternatives are not saving/restoring LEX, so lex->query_tables can be wiped out. */ - if (!lex->select_lex.add_table_to_list(thd, $10, - (LEX_CSTRING*) 0, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_NO_WRITE)) + if (unlikely(!lex->select_lex. + add_table_to_list(thd, $10, (LEX_CSTRING*) 0, + TL_OPTION_UPDATING, + TL_READ_NO_INSERT, + MDL_SHARED_NO_WRITE))) MYSQL_YYABORT; } ; @@ -17241,9 +17772,9 @@ udf_tail: RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys { LEX *lex= thd->lex; - if (lex->add_create_options_with_check($1)) + if (unlikely(lex->add_create_options_with_check($1))) MYSQL_YYABORT; - if (is_native_function(thd, & $2)) + if (unlikely(is_native_function(thd, & $2))) my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $2.str)); lex->sql_command= SQLCOM_CREATE_FUNCTION; lex->udf.name= $2; @@ -17263,7 +17794,8 @@ sf_return_type: } sp_param_type_with_opt_collate { - if (Lex->sphead->fill_field_definition(thd, Lex->last_field)) + if (unlikely(Lex->sphead->fill_field_definition(thd, + Lex->last_field))) MYSQL_YYABORT; } ; @@ -17273,8 +17805,8 @@ sf_tail: sp_name { Lex->sql_command= SQLCOM_CREATE_SPFUNCTION; - if (!Lex->make_sp_head_no_recursive(thd, $1, $2, - &sp_handler_function)) + if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1, $2, + &sp_handler_function))) MYSQL_YYABORT; } opt_sp_parenthesized_fdparam_list @@ -17290,9 +17822,9 @@ sf_tail: sp_tail_is sp_body { - if (Lex->sp_body_finalize_function(thd)) + if (unlikely(Lex->sp_body_finalize_function(thd))) MYSQL_YYABORT; - if (Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR) + if (unlikely(Lex->sphead->m_flags & sp_head::HAS_AGGREGATE_INSTR)) { my_yyabort_error((ER_NOT_AGGREGATE_FUNCTION, MYF(0))); } @@ -17304,8 +17836,8 @@ sp_tail: opt_if_not_exists sp_name { Lex->sql_command= SQLCOM_CREATE_PROCEDURE; - if (!Lex->make_sp_head_no_recursive(thd, $1, $2, - &sp_handler_procedure)) + if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1, $2, + &sp_handler_procedure))) MYSQL_YYABORT; } opt_sp_parenthesized_pdparam_list @@ -17317,7 +17849,7 @@ sp_tail: sp_tail_is sp_body { - if (Lex->sp_body_finalize_procedure(thd)) + if (unlikely(Lex->sp_body_finalize_procedure(thd))) MYSQL_YYABORT; } ; @@ -17325,7 +17857,7 @@ sp_tail: sf_tail_standalone: sf_tail opt_sp_name { - if ($2 && !$2->eq(Lex->sphead)) + if (unlikely($2 && !$2->eq(Lex->sphead))) my_yyabort_error((ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0), ErrConvDQName($2).ptr(), ErrConvDQName(Lex->sphead).ptr())); @@ -17335,7 +17867,7 @@ sf_tail_standalone: sp_tail_standalone: sp_tail opt_sp_name { - if ($2 && !$2->eq(Lex->sphead)) + if (unlikely($2 && !$2->eq(Lex->sphead))) my_yyabort_error((ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0), ErrConvDQName($2).ptr(), ErrConvDQName(Lex->sphead).ptr())); @@ -17386,37 +17918,38 @@ opt_format_xid: /* empty */ { $$= false; } | FORMAT_SYM '=' ident_or_text { - if (!my_strcasecmp(system_charset_info, $3.str, "SQL")) + if (lex_string_eq(&$3, STRING_WITH_LEN("SQL"))) $$= true; - else if (!my_strcasecmp(system_charset_info, $3.str, "RAW")) + else if (lex_string_eq(&$3, STRING_WITH_LEN("RAW"))) $$= false; else { - my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), "XA RECOVER", $3.str)); + my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), + "XA RECOVER", $3.str)); $$= false; } - } - ; + } + ; xid: text_string { MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE); - if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))) + if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0); } | text_string ',' text_string { MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); - if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))) + if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length()); } | text_string ',' text_string ',' ulong_num { MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); - if (!(Lex->xid=(XID *)thd->alloc(sizeof(XID)))) + if (unlikely(!(Lex->xid=(XID *)thd->alloc(sizeof(XID))))) MYSQL_YYABORT; Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length()); } diff --git a/sql/strfunc.cc b/sql/strfunc.cc index f701c4a09ed..f457f6b29be 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -79,8 +79,9 @@ ulonglong find_set(TYPELIB *lib, const char *str, size_t length, CHARSET_INFO *c var_len= (uint) (pos - start); uint find= cs ? find_type2(lib, start, var_len, cs) : find_type(lib, start, var_len, (bool) 0); - if (!find && *err_len == 0) // report the first error with length > 0 + if (unlikely(!find && *err_len == 0)) { + // report the first error with length > 0 *err_pos= (char*) start; *err_len= var_len; *set_warning= 1; diff --git a/sql/structs.h b/sql/structs.h index 01d99517fed..d530dd73b7c 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -754,12 +754,6 @@ public: }; -struct Lex_string_with_pos_st: public LEX_CSTRING -{ - const char *m_pos; -}; - - class Load_data_param { protected: diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 0331343ccef..658bb0e2d1c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -400,7 +400,7 @@ static const char *vers_alter_history_keywords[]= {"ERROR", "KEEP", NullS}; static Sys_var_enum Sys_vers_alter_history( "system_versioning_alter_history", "Versioning ALTER TABLE mode. " "ERROR: Fail ALTER with error; " /* TODO: fail only when history non-empty */ - "KEEP: Keep historical system rows and subject them to ALTER; ", + "KEEP: Keep historical system rows and subject them to ALTER", SESSION_VAR(vers_alter_history), CMD_LINE(REQUIRED_ARG), vers_alter_history_keywords, DEFAULT(VERS_ALTER_HISTORY_ERROR)); @@ -443,13 +443,13 @@ static bool error_if_in_trans_or_substatement(THD *thd, int in_substatement_error, int in_transaction_error) { - if (thd->in_sub_stmt) + if (unlikely(thd->in_sub_stmt)) { my_error(in_substatement_error, MYF(0)); return true; } - if (thd->in_active_multi_stmt_transaction()) + if (unlikely(thd->in_active_multi_stmt_transaction())) { my_error(in_transaction_error, MYF(0)); return true; @@ -470,6 +470,8 @@ static bool check_has_super(sys_var *self, THD *thd, set_var *var) #endif return false; } + + static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) { if (check_has_super(self, thd, var)) @@ -529,9 +531,9 @@ static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) return true; } - if (error_if_in_trans_or_substatement(thd, - ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, - ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT)) + if (unlikely(error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT))) return true; return false; @@ -566,9 +568,9 @@ static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var) if (var->type == OPT_GLOBAL) return false; - if (error_if_in_trans_or_substatement(thd, - ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, - ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT)) + if (unlikely(error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT))) return true; return false; @@ -1606,9 +1608,9 @@ static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var) if (check_has_super(self, thd, var)) return true; - if (error_if_in_trans_or_substatement(thd, - ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO, - ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO)) + if (unlikely(error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO))) return true; domain_id= thd->variables.gtid_domain_id; @@ -2369,9 +2371,19 @@ static Sys_var_mybool Sys_old_mode( "old", "Use compatible behavior from previous MariaDB version. See also --old-mode", SESSION_VAR(old_mode), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); -static Sys_var_mybool Sys_old_alter_table( - "old_alter_table", "Use old, non-optimized alter table", - SESSION_VAR(old_alter_table), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); +static const char *alter_algorithm_modes[]= {"DEFAULT", "COPY", "INPLACE", +"NOCOPY", "INSTANT", NULL}; + +static Sys_var_enum Sys_alter_algorithm( + "alter_algorithm", "Specify the alter table algorithm", + SESSION_VAR(alter_algorithm), CMD_LINE(OPT_ARG), + alter_algorithm_modes, DEFAULT(0)); + +static Sys_var_enum Sys_old_alter_table( + "old_alter_table", "Alias for alter_algorithm. " + "Deprecated. Use --alter-algorithm instead.", + SESSION_VAR(alter_algorithm), CMD_LINE(OPT_ARG), + alter_algorithm_modes, DEFAULT(0)); static bool check_old_passwords(sys_var *self, THD *thd, set_var *var) { @@ -2442,8 +2454,7 @@ static Sys_var_ulong Sys_optimizer_search_depth( "optimization, but may produce very bad query plans. If set to 0, " "the system will automatically pick a reasonable value.", SESSION_VAR(optimizer_search_depth), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, MAX_TABLES+1), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0)); + VALID_RANGE(0, MAX_TABLES+1), DEFAULT(MAX_TABLES+1), BLOCK_SIZE(1)); /* this is used in the sigsegv handler */ export const char *optimizer_switch_names[]= @@ -4036,15 +4047,15 @@ static bool check_sql_log_bin(sys_var *self, THD *thd, set_var *var) if (check_has_super(self, thd, var)) return TRUE; - if (var->type == OPT_GLOBAL) + if (unlikely(var->type == OPT_GLOBAL)) { my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), self->name.str, "SESSION"); return TRUE; } - if (error_if_in_trans_or_substatement(thd, - ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN, - ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN)) + if (unlikely(error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN))) return TRUE; return FALSE; @@ -4177,9 +4188,9 @@ static bool check_skip_replication(sys_var *self, THD *thd, set_var *var) Rows_log_event without Table_map_log_event or transactional updates without the COMMIT). */ - if (error_if_in_trans_or_substatement(thd, - ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION, - ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION)) + if (unlikely(error_if_in_trans_or_substatement(thd, + ER_STORED_FUNCTION_PREVENTS_SWITCH_SKIP_REPLICATION, + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SKIP_REPLICATION))) return 1; return 0; @@ -4202,11 +4213,24 @@ static Sys_var_harows Sys_select_limit( SESSION_VAR(select_limit), NO_CMD_LINE, VALID_RANGE(0, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1)); +static const char *secure_timestamp_levels[]= {"NO", "SUPER", "REPLICATION", "YES", 0}; +static bool check_timestamp(sys_var *self, THD *thd, set_var *var) +{ + if (opt_secure_timestamp == SECTIME_NO) + return false; + if (opt_secure_timestamp == SECTIME_SUPER) + return check_has_super(self, thd, var); + char buf[1024]; + strxnmov(buf, sizeof(buf), "--secure-timestamp=", + secure_timestamp_levels[opt_secure_timestamp], NULL); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf); + return true; +} static Sys_var_timestamp Sys_timestamp( "timestamp", "Set the time for this client", sys_var::ONLY_SESSION, NO_CMD_LINE, VALID_RANGE(0, TIMESTAMP_MAX_VALUE), - NO_MUTEX_GUARD, IN_BINLOG); + NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_timestamp)); static bool update_last_insert_id(THD *thd, set_var *var) { @@ -5402,9 +5426,7 @@ static const char *wsrep_OSU_method_names[]= { "TOI", "RSU", NullS }; static Sys_var_enum Sys_wsrep_OSU_method( "wsrep_OSU_method", "Method for Online Schema Upgrade", SESSION_VAR(wsrep_OSU_method), CMD_LINE(OPT_ARG), - wsrep_OSU_method_names, DEFAULT(WSREP_OSU_TOI), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(0)); + wsrep_OSU_method_names, DEFAULT(WSREP_OSU_TOI)); static PolyLock_mutex PLock_wsrep_desync(&LOCK_wsrep_desync); static Sys_var_mybool Sys_wsrep_desync ( @@ -5872,9 +5894,7 @@ static Sys_var_enum Sys_binlog_row_image( "before image, and only changed columns are logged in the after image. " "(Default: FULL).", SESSION_VAR(binlog_row_image), CMD_LINE(REQUIRED_ARG), - binlog_row_image_names, DEFAULT(BINLOG_ROW_IMAGE_FULL), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), - ON_UPDATE(NULL)); + binlog_row_image_names, DEFAULT(BINLOG_ROW_IMAGE_FULL)); static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var) { @@ -6046,3 +6066,13 @@ static Sys_var_uint Sys_in_subquery_conversion_threshold( SESSION_VAR(in_subquery_conversion_threshold), CMD_LINE(OPT_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(IN_SUBQUERY_CONVERSION_THRESHOLD), BLOCK_SIZE(1)); #endif + +static Sys_var_enum Sys_secure_timestamp( + "secure_timestamp", "Restricts direct setting of a session " + "timestamp. Possible levels are: YES - timestamp cannot deviate from " + "the system clock, REPLICATION - replication thread can adjust " + "timestamp to match the master's, SUPER - a user with this " + "privilege and a replication thread can adjust timestamp, NO - " + "historical behavior, anyone can modify session timestamp", + READ_ONLY GLOBAL_VAR(opt_secure_timestamp), CMD_LINE(REQUIRED_ARG), + secure_timestamp_levels, DEFAULT(SECTIME_NO)); diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index e04e09e9bc6..498204deb92 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -325,7 +325,7 @@ public: Class specific constructor arguments: char* values[] - 0-terminated list of strings of valid values - Backing store: uint + Backing store: ulong @note Do *not* use "enum FOO" variables as a backing store, there is no @@ -1271,7 +1271,7 @@ public: default_value, res->ptr(), res->length(), &error, &error_len); - if (error) + if (unlikely(error)) { ErrConvString err(error, error_len, res->charset()); my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); @@ -1370,7 +1370,7 @@ public: That is even while empty (zero-length) values are considered errors by find_set(), these errors are ignored here */ - if (error_len) + if (unlikely(error_len)) { ErrConvString err(error, error_len, res->charset()); my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); @@ -1465,7 +1465,7 @@ public: plugin= ha_resolve_by_name(thd, &pname, false); else plugin= my_plugin_lock_by_name(thd, &pname, plugin_type); - if (!plugin) + if (unlikely(!plugin)) { // historically different error code if (plugin_type == MYSQL_STORAGE_ENGINE_PLUGIN) @@ -1892,10 +1892,11 @@ public: const char *comment, int flag_args, CMD_LINE getopt, double min_val, double max_val, - PolyLock *lock, enum binlog_status_enum binlog_status_arg) + PolyLock *lock, enum binlog_status_enum binlog_status_arg, + on_check_function on_check_func=0) : Sys_var_double(name_arg, comment, flag_args, 0, sizeof(double), getopt, min_val, - max_val, 0, lock, binlog_status_arg) + max_val, 0, lock, binlog_status_arg, on_check_func) { SYSVAR_ASSERT(scope() == ONLY_SESSION); SYSVAR_ASSERT(getopt.id < 0); // NO_CMD_LINE, because the offset is fake diff --git a/sql/table.cc b/sql/table.cc index 93684cb5221..11e1b9f3b7a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2016, MariaDB +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2008, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -677,7 +677,7 @@ err: mysql_file_close(file, MYF(MY_WME)); err_not_open: - if (share->error && !error_given) + if (unlikely(share->error && !error_given)) { share->open_errno= my_errno; open_table_error(share, share->error, share->open_errno); @@ -1856,6 +1856,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, vers_can_native= plugin_hton(se_plugin)->flags & HTON_NATIVE_SYS_VERSIONING; row_start_field= row_start; row_end_field= row_end; + status_var_increment(thd->status_var.feature_system_versioning); } // if (system_period == NULL) for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++) @@ -2804,11 +2805,14 @@ int TABLE_SHARE::init_from_sql_statement_string(THD *thd, bool write, thd->reset_db(&db); lex_start(thd); - if ((error= parse_sql(thd, & parser_state, NULL) || - sql_unusable_for_discovery(thd, hton, sql_copy))) + if (unlikely((error= parse_sql(thd, & parser_state, NULL) || + sql_unusable_for_discovery(thd, hton, sql_copy)))) goto ret; thd->lex->create_info.db_type= hton; +#ifdef WITH_PARTITION_STORAGE_ENGINE + thd->work_part_info= 0; // For partitioning +#endif if (tabledef_version.str) thd->lex->create_info.tabledef_version= tabledef_version; @@ -2837,7 +2841,7 @@ ret: reenable_binlog(thd); thd->variables.sql_mode= saved_mode; thd->variables.character_set_client= old_cs; - if (thd->is_error() || error) + if (unlikely(thd->is_error() || error)) { thd->clear_error(); my_error(ER_SQL_DISCOVER_ERROR, MYF(0), @@ -2997,14 +3001,14 @@ static bool fix_and_check_vcol_expr(THD *thd, TABLE *table, res.errors= 0; int error= func_expr->walk(&Item::check_vcol_func_processor, 0, &res); - if (error || (res.errors & VCOL_IMPOSSIBLE)) + if (unlikely(error || (res.errors & VCOL_IMPOSSIBLE))) { // this can only happen if the frm was corrupted my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, vcol->get_vcol_type_name(), vcol->name.str); DBUG_RETURN(1); } - else if (res.errors & VCOL_AUTO_INC) + else if (unlikely(res.errors & VCOL_AUTO_INC)) { /* An auto_increment field may not be used in an expression for @@ -3085,7 +3089,7 @@ unpack_vcol_info_from_frm(THD *thd, MEM_ROOT *mem_root, TABLE *table, lex.last_field= &vcol_storage; error= parse_sql(thd, &parser_state, NULL); - if (error) + if (unlikely(error)) goto end; if (lex.current_select->table_list.first[0].next_global) @@ -3354,7 +3358,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, if (share->table_check_constraints || share->field_check_constraints) outparam->check_constraints= check_constraint_ptr; - if (parse_vcol_defs(thd, &outparam->mem_root, outparam, &error_reported)) + if (unlikely(parse_vcol_defs(thd, &outparam->mem_root, outparam, + &error_reported))) { error= OPEN_FRM_CORRUPTED; goto err; @@ -3506,7 +3511,8 @@ partititon_err: /* Set a flag if the table is crashed and it can be auto. repaired */ share->crashed= (outparam->file->auto_repair(ha_err) && !(ha_open_flags & HA_OPEN_FOR_REPAIR)); - outparam->file->print_error(ha_err, MYF(0)); + if (!thd->is_error()) + outparam->file->print_error(ha_err, MYF(0)); error_reported= TRUE; if (ha_err == HA_ERR_TABLE_DEF_CHANGED) @@ -3579,7 +3585,7 @@ partititon_err: table TABLE object to free */ -int closefrm(register TABLE *table) +int closefrm(TABLE *table) { int error=0; DBUG_ENTER("closefrm"); @@ -3616,7 +3622,7 @@ int closefrm(register TABLE *table) /* Deallocate temporary blob storage */ -void free_blobs(register TABLE *table) +void free_blobs(TABLE *table) { uint *ptr, *end; for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ; @@ -3810,17 +3816,6 @@ void append_unescaped(String *res, const char *pos, size_t length) for (; pos != end ; pos++) { -#if defined(USE_MB) && MYSQL_VERSION_ID < 40100 - uint mblen; - if (use_mb(default_charset_info) && - (mblen= my_ismbchar(default_charset_info, pos, end))) - { - res->append(pos, mblen); - pos+= mblen; - continue; - } -#endif - switch (*pos) { case 0: /* Must be escaped for 'mysql' */ res->append('\\'); @@ -4235,7 +4230,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) /* Whether the table definition has already been validated. */ if (table->s->table_field_def_cache == table_def) - DBUG_RETURN(FALSE); + goto end; if (table->s->fields != table_def->count) { @@ -4268,6 +4263,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) is backward compatible. */ } + else + { StringBuffer<1024> sql_type(system_charset_info); sql_type.extra_allocation(256); // Allocate min 256 characters at once for (i=0 ; i < table_def->count; i++, field_def++) @@ -4353,6 +4350,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) error= TRUE; } } + } if (table_def->primary_key_parts) { @@ -4394,9 +4392,19 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) } } - if (! error) + if (likely(! error)) table->s->table_field_def_cache= table_def; +end: + + if (has_keys && !error && !table->key_info) + { + report_error(0, "Incorrect definition of table %s.%s: " + "indexes are missing", + table->s->db.str, table->alias.c_ptr()); + error= TRUE; + } + DBUG_RETURN(error); } @@ -5258,14 +5266,25 @@ int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure) int TABLE::verify_constraints(bool ignore_failure) { + /* + We have to check is_error() first as we are checking it for each + constraint to catch fatal warnings. + */ + if (in_use->is_error()) + return (VIEW_CHECK_ERROR); + /* go trough check option clauses for fields and table */ if (check_constraints && !(in_use->variables.option_bits & OPTION_NO_CHECK_CONSTRAINT_CHECKS)) { for (Virtual_column_info **chk= check_constraints ; *chk ; chk++) { - /* yes! NULL is ok, see 4.23.3.4 Table check constraints, part 2, SQL:2016 */ - if ((*chk)->expr->val_int() == 0 && !(*chk)->expr->null_value) + /* + yes! NULL is ok. + see 4.23.3.4 Table check constraints, part 2, SQL:2016 + */ + if (((*chk)->expr->val_int() == 0 && !(*chk)->expr->null_value) || + in_use->is_error()) { my_error(ER_CONSTRAINT_FAILED, MYF(ignore_failure ? ME_JUST_WARNING : 0), (*chk)->name.str, @@ -5274,7 +5293,11 @@ int TABLE::verify_constraints(bool ignore_failure) } } } - return(VIEW_CHECK_OK); + /* + We have to check in_use() as checking constraints may have generated + warnings that should be treated as errors + */ + return(!in_use->is_error() ? VIEW_CHECK_OK : VIEW_CHECK_ERROR); } /* @@ -6702,6 +6725,12 @@ void TABLE::mark_columns_per_binlog_row_image() DBUG_ASSERT(FALSE); } } + /* + We have to ensure that all virtual columns that are part of read set + are calculated. + */ + if (vcol_set) + bitmap_union(vcol_set, read_set); file->column_bitmaps_signal(); } @@ -6743,7 +6772,8 @@ bool TABLE::mark_virtual_col(Field *field) /* @brief Mark virtual columns for update/insert commands - @param insert_fl <-> virtual columns are marked for insert command + @param insert_fl true if virtual columns are marked for insert command + For the moment this is not used, may be used in future. @details The function marks virtual columns used in a update/insert commands @@ -6768,7 +6798,8 @@ bool TABLE::mark_virtual_col(Field *field) be added to read_set either. */ -bool TABLE::mark_virtual_columns_for_write(bool insert_fl) +bool TABLE::mark_virtual_columns_for_write(bool insert_fl + __attribute__((unused))) { Field **vfield_ptr, *tmp_vfield; bool bitmap_updated= false; @@ -6778,35 +6809,13 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl) { tmp_vfield= *vfield_ptr; if (bitmap_is_set(write_set, tmp_vfield->field_index)) - bitmap_updated= mark_virtual_col(tmp_vfield); + bitmap_updated|= mark_virtual_col(tmp_vfield); else if (tmp_vfield->vcol_info->stored_in_db || - (tmp_vfield->flags & PART_KEY_FLAG)) + (tmp_vfield->flags & (PART_KEY_FLAG | FIELD_IN_PART_FUNC_FLAG))) { - if (insert_fl) - { - bitmap_set_bit(write_set, tmp_vfield->field_index); - mark_virtual_col(tmp_vfield); - bitmap_updated= true; - } - else - { - MY_BITMAP *save_read_set= read_set, *save_vcol_set= vcol_set; - Item *vcol_item= tmp_vfield->vcol_info->expr; - DBUG_ASSERT(vcol_item); - bitmap_clear_all(&tmp_set); - read_set= vcol_set= &tmp_set; - vcol_item->walk(&Item::register_field_in_read_map, 1, 0); - read_set= save_read_set; - vcol_set= save_vcol_set; - if (bitmap_is_overlapping(&tmp_set, write_set)) - { - bitmap_set_bit(write_set, tmp_vfield->field_index); - bitmap_set_bit(vcol_set, tmp_vfield->field_index); - bitmap_union(read_set, &tmp_set); - bitmap_union(vcol_set, &tmp_set); - bitmap_updated= true; - } - } + bitmap_set_bit(write_set, tmp_vfield->field_index); + mark_virtual_col(tmp_vfield); + bitmap_updated= true; } } if (bitmap_updated) @@ -7452,8 +7461,8 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl) } /* - TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) and - create tbl->force_index_join instead. + TODO: get rid of tbl->force_index (on if any FORCE INDEX is specified) + and create tbl->force_index_join instead. Then use the correct force_index_XX instead of the global one. */ if (!index_join[INDEX_HINT_FORCE].is_clear_all() || @@ -7483,21 +7492,27 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl) } -size_t max_row_length(TABLE *table, const uchar *data) +size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data) { TABLE_SHARE *table_s= table->s; size_t length= table_s->reclength + 2 * table_s->fields; uint *const beg= table_s->blob_field; uint *const end= beg + table_s->blob_fields; + my_ptrdiff_t const rec_offset= (my_ptrdiff_t) (data - table->record[0]); + DBUG_ENTER("max_row_length"); for (uint *ptr= beg ; ptr != end ; ++ptr) { - Field_blob* const blob= (Field_blob*) table->field[*ptr]; - length+= blob->get_length((const uchar*) - (data + blob->offset(table->record[0]))) + - HA_KEY_BLOB_LENGTH; + Field * const field= table->field[*ptr]; + if (bitmap_is_set(cols, field->field_index) && + !field->is_null(rec_offset)) + { + Field_blob * const blob= (Field_blob*) field; + length+= blob->get_length(rec_offset) + 8; /* max blob store length */ + } } - return length; + DBUG_PRINT("exit", ("length: %lld", (longlong) length)); + DBUG_RETURN(length); } @@ -7612,7 +7627,7 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) Query_arena backup_arena; Turn_errors_to_warnings_handler Suppress_errors; int error; - bool handler_pushed= 0; + bool handler_pushed= 0, update_all_columns= 1; DBUG_ASSERT(vfield); if (h->keyread_enabled()) @@ -7629,6 +7644,16 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) in_use->push_internal_handler(&Suppress_errors); handler_pushed= 1; } + else if (update_mode == VCOL_UPDATE_FOR_REPLACE && + in_use->is_current_stmt_binlog_format_row() && + in_use->variables.binlog_row_image != BINLOG_ROW_IMAGE_MINIMAL) + { + /* + If we are doing a replace with not minimal binary logging, we have to + calculate all virtual columns. + */ + update_all_columns= 1; + } /* Iterate over virtual fields in the table */ for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) @@ -7641,8 +7666,8 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) bool update= 0, swap_values= 0; switch (update_mode) { case VCOL_UPDATE_FOR_READ: - update= !vcol_info->stored_in_db - && bitmap_is_set(vcol_set, vf->field_index); + update= (!vcol_info->stored_in_db && + bitmap_is_set(vcol_set, vf->field_index)); swap_values= 1; break; case VCOL_UPDATE_FOR_DELETE: @@ -7650,8 +7675,9 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) update= bitmap_is_set(vcol_set, vf->field_index); break; case VCOL_UPDATE_FOR_REPLACE: - update= !vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) - && bitmap_is_set(vcol_set, vf->field_index); + update= ((!vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) && + bitmap_is_set(vcol_set, vf->field_index)) || + update_all_columns); if (update && (vf->flags & BLOB_FLAG)) { /* @@ -7668,8 +7694,8 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode) case VCOL_UPDATE_INDEXED: case VCOL_UPDATE_INDEXED_FOR_UPDATE: /* Read indexed fields that was not updated in VCOL_UPDATE_FOR_READ */ - update= !vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) && - bitmap_is_set(vcol_set, vf->field_index); + update= (!vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) && + !bitmap_is_set(vcol_set, vf->field_index)); swap_values= 1; break; } @@ -7789,8 +7815,8 @@ void TABLE::vers_update_fields() { if (!vers_write) return; - if (vers_start_field()->store_timestamp(in_use->systime(), - in_use->systime_sec_part())) + if (vers_start_field()->store_timestamp(in_use->query_start(), + in_use->query_start_sec_part())) DBUG_ASSERT(0); } else @@ -7805,8 +7831,8 @@ void TABLE::vers_update_fields() void TABLE::vers_update_end() { - if (vers_end_field()->store_timestamp(in_use->systime(), - in_use->systime_sec_part())) + if (vers_end_field()->store_timestamp(in_use->query_start(), + in_use->query_start_sec_part())) DBUG_ASSERT(0); } @@ -7957,7 +7983,7 @@ bool TABLE::insert_all_rows_into_tmp_table(THD *thd, tmp_table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL); file->ha_index_or_rnd_end(); - if (file->ha_rnd_init_with_error(1)) + if (unlikely(file->ha_rnd_init_with_error(1))) DBUG_RETURN(1); if (tmp_table->no_rows) @@ -7969,10 +7995,10 @@ bool TABLE::insert_all_rows_into_tmp_table(THD *thd, tmp_table->file->ha_start_bulk_insert(file->stats.records); } - while (!file->ha_rnd_next(tmp_table->record[0])) + while (likely(!file->ha_rnd_next(tmp_table->record[0]))) { write_err= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]); - if (write_err) + if (unlikely(write_err)) { bool is_duplicate; if (tmp_table->file->is_fatal_error(write_err, HA_CHECK_DUP) && @@ -7983,11 +8009,8 @@ bool TABLE::insert_all_rows_into_tmp_table(THD *thd, DBUG_RETURN(1); } - if (thd->check_killed()) - { - thd->send_kill_message(); + if (unlikely(thd->check_killed())) goto err_killed; - } } if (!tmp_table->no_rows && tmp_table->file->ha_end_bulk_insert()) goto err; @@ -8154,7 +8177,21 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) (first_table && first_table->is_multitable())) set_multitable(); - unit->derived= this; + if (!unit->derived) + unit->derived= this; + else if (!is_with_table_recursive_reference() && unit->derived != this) + { + if (unit->derived->is_with_table_recursive_reference()) + unit->derived= this; + else if (vers_conditions.eq(unit->derived->vers_conditions)) + vers_conditions.empty(); + else + { + my_error(ER_CONFLICTING_FOR_SYSTEM_TIME, MYF(0)); + return TRUE; + } + } + if (init_view && !view) { /* This is all what we can do for a derived table for now. */ @@ -8281,7 +8318,10 @@ bool TABLE_LIST::change_refs_to_fields() if (!used_items.elements) return FALSE; - materialized_items= (Item**)thd->calloc(sizeof(void*) * table->s->fields); + Item **materialized_items= + (Item **)thd->calloc(sizeof(void *) * table->s->fields); + if (!materialized_items) + return TRUE; while ((ref= (Item_direct_ref*)li++)) { @@ -8440,17 +8480,15 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id) if (!table && open()) return true; - timeval start_time= {thd->systime(), long(thd->systime_sec_part())}; - thd->set_start_time(); - timeval end_time= {thd->systime(), long(thd->systime_sec_part())}; + store(FLD_BEGIN_TS, thd->transaction_time()); + timeval end_time= {thd->query_start(), long(thd->query_start_sec_part())}; store(FLD_TRX_ID, start_id); store(FLD_COMMIT_ID, end_id); - store(FLD_BEGIN_TS, start_time); store(FLD_COMMIT_TS, end_time); store_iso_level(thd->tx_isolation); int error= table->file->ha_write_row(table->record[0]); - if (error) + if (unlikely(error)) table->file->print_error(error, MYF(0)); return error; } @@ -8469,10 +8507,10 @@ bool TR_table::query(ulonglong trx_id) Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_TRX_ID]); Item *value= newx Item_int(thd, trx_id); COND *conds= newx Item_func_eq(thd, field, value); - if ((error= setup_conds(thd, this, dummy, &conds))) + if (unlikely((error= setup_conds(thd, this, dummy, &conds)))) return false; select= make_select(table, 0, 0, conds, NULL, 0, &error); - if (error || !select) + if (unlikely(error || !select)) return false; // FIXME: (performance) force index 'transaction_id' error= init_read_record(&info, thd, table, select, NULL, @@ -8503,11 +8541,11 @@ bool TR_table::query(MYSQL_TIME &commit_time, bool backwards) conds= newx Item_func_ge(thd, field, value); else conds= newx Item_func_le(thd, field, value); - if ((error= setup_conds(thd, this, dummy, &conds))) + if (unlikely((error= setup_conds(thd, this, dummy, &conds)))) return false; // FIXME: (performance) force index 'commit_timestamp' select= make_select(table, 0, 0, conds, NULL, 0, &error); - if (error || !select) + if (unlikely(error || !select)) return false; error= init_read_record(&info, thd, table, select, NULL, 1 /* use_record_cache */, true /* print_error */, @@ -8567,6 +8605,12 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0, return false; } + if (trx_id0 == ULONGLONG_MAX || trx_id1 == 0) + { + result= false; + return false; + } + if (!commit_id1) { if (!query(trx_id1)) @@ -8702,28 +8746,53 @@ bool TR_table::check(bool error) return false; } -void vers_select_conds_t::resolve_units(bool timestamps_only) +bool vers_select_conds_t::resolve_units(THD *thd) { DBUG_ASSERT(type != SYSTEM_TIME_UNSPECIFIED); DBUG_ASSERT(start.item); - start.resolve_unit(timestamps_only); - end.resolve_unit(timestamps_only); + return start.resolve_unit(thd) || + end.resolve_unit(thd); } -void Vers_history_point::resolve_unit(bool timestamps_only) +bool vers_select_conds_t::eq(const vers_select_conds_t &conds) const { - if (item && unit == VERS_UNDEFINED) - { - if (item->type() == Item::FIELD_ITEM || timestamps_only) - unit= VERS_TIMESTAMP; - else if (item->result_type() == INT_RESULT || - item->result_type() == REAL_RESULT) - unit= VERS_TRX_ID; - else - unit= VERS_TIMESTAMP; + if (type != conds.type) + return false; + switch (type) { + case SYSTEM_TIME_UNSPECIFIED: + case SYSTEM_TIME_ALL: + return true; + case SYSTEM_TIME_BEFORE: + DBUG_ASSERT(0); + case SYSTEM_TIME_AS_OF: + return start.eq(conds.start); + case SYSTEM_TIME_FROM_TO: + case SYSTEM_TIME_BETWEEN: + return start.eq(conds.start) && end.eq(conds.end); } + DBUG_ASSERT(0); + return false; +} + + +bool Vers_history_point::resolve_unit(THD *thd) +{ + if (!item) + return false; + if (!item->fixed && item->fix_fields(thd, &item)) + return true; + return item->this_item()->type_handler_for_system_time()-> + Vers_history_point_resolve_unit(thd, this); +} + + +void Vers_history_point::bad_expression_data_type_error(const char *type) const +{ + my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0), + type, "FOR SYSTEM_TIME"); } + void Vers_history_point::fix_item() { if (item && item->decimals == 0 && item->type() == Item::FUNC_ITEM && @@ -8731,8 +8800,14 @@ void Vers_history_point::fix_item() item->decimals= 6; } + +bool Vers_history_point::eq(const vers_history_point_t &point) const +{ + return unit == point.unit && item->eq(point.item, false); +} + void Vers_history_point::print(String *str, enum_query_type query_type, - const char *prefix, size_t plen) + const char *prefix, size_t plen) const { const static LEX_CSTRING unit_type[]= { diff --git a/sql/table.h b/sql/table.h index 1e9dad75b70..46a2ec6c49d 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1,8 +1,7 @@ #ifndef TABLE_INCLUDED #define TABLE_INCLUDED -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, SkySQL Ab. - Copyright (c) 2016, 2017, MariaDB Corporation. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -487,10 +486,11 @@ typedef struct st_table_field_def class Table_check_intact { protected: + bool has_keys; virtual void report_error(uint code, const char *fmt, ...)= 0; public: - Table_check_intact() {} + Table_check_intact(bool keys= false) : has_keys(keys) {} virtual ~Table_check_intact() {} /** Checks whether a table is intact. */ @@ -505,6 +505,8 @@ class Table_check_intact_log_error : public Table_check_intact { protected: void report_error(uint, const char *fmt, ...); +public: + Table_check_intact_log_error() : Table_check_intact(true) {} }; @@ -1825,8 +1827,22 @@ public: fix_item(); } void empty() { unit= VERS_UNDEFINED; item= NULL; } - void print(String *str, enum_query_type, const char *prefix, size_t plen); - void resolve_unit(bool timestamps_only); + void print(String *str, enum_query_type, const char *prefix, size_t plen) const; + bool resolve_unit(THD *thd); + bool resolve_unit_trx_id(THD *thd) + { + if (unit == VERS_UNDEFINED) + unit= VERS_TRX_ID; + return false; + } + bool resolve_unit_timestamp(THD *thd) + { + if (unit == VERS_UNDEFINED) + unit= VERS_TIMESTAMP; + return false; + } + void bad_expression_data_type_error(const char *type) const; + bool eq(const vers_history_point_t &point) const; }; struct vers_select_conds_t @@ -1855,27 +1871,20 @@ struct vers_select_conds_t end= _end; } - void print(String *str, enum_query_type query_type); + void print(String *str, enum_query_type query_type) const; bool init_from_sysvar(THD *thd); - bool operator== (vers_system_time_t b) - { - return type == b; - } - bool operator!= (vers_system_time_t b) - { - return type != b; - } - operator bool() const + bool is_set() const { return type != SYSTEM_TIME_UNSPECIFIED; } - void resolve_units(bool timestamps_only); + bool resolve_units(THD *thd); bool user_defined() const { return !from_query && type != SYSTEM_TIME_UNSPECIFIED; } + bool eq(const vers_select_conds_t &conds) const; }; /* @@ -2259,7 +2268,7 @@ struct TABLE_LIST /* TABLE_TYPE_UNKNOWN if any type is acceptable */ Table_type required_type; handlerton *db_type; /* table_type for handler */ - char timestamp_buffer[20]; /* buffer for timestamp (19+1) */ + char timestamp_buffer[MAX_DATETIME_WIDTH + 1]; /* This TABLE_LIST object is just placeholder for prelocking, it will be used for implicit LOCK TABLES only and won't be used in real statement. @@ -2291,8 +2300,6 @@ struct TABLE_LIST /* TODO: replace with derived_type */ bool merged; bool merged_for_insert; - /* TRUE <=> don't prepare this derived table/view as it should be merged.*/ - bool skip_prepare_derived; bool sequence; /* Part of NEXTVAL/CURVAL/LASTVAL */ /* @@ -2302,7 +2309,6 @@ struct TABLE_LIST List<Item> used_items; /* Sublist (tail) of persistent used_items */ List<Item> persistent_used_items; - Item **materialized_items; /* View creation context. */ @@ -2871,7 +2877,7 @@ enum get_table_share_flags { GTS_FORCE_DISCOVERY = 16 }; -size_t max_row_length(TABLE *table, const uchar *data); +size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data); void init_mdl_requests(TABLE_LIST *table_list); diff --git a/sql/table_cache.cc b/sql/table_cache.cc index e524e0995e2..2c5d25c0308 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -747,7 +747,7 @@ TDC_element *tdc_lock_share(THD *thd, const char *db, const char *table_name) char key[MAX_DBKEY_LENGTH]; DBUG_ENTER("tdc_lock_share"); - if (fix_thd_pins(thd)) + if (unlikely(fix_thd_pins(thd))) DBUG_RETURN((TDC_element*) MY_ERRPTR); element= (TDC_element *) lf_hash_search(&tdc_hash, thd->tdc_hash_pins, @@ -756,7 +756,7 @@ TDC_element *tdc_lock_share(THD *thd, const char *db, const char *table_name) if (element) { mysql_mutex_lock(&element->LOCK_table_share); - if (!element->share || element->share->error) + if (unlikely(!element->share || element->share->error)) { mysql_mutex_unlock(&element->LOCK_table_share); element= 0; @@ -838,7 +838,7 @@ retry: /* note that tdc_acquire_share() *always* uses discovery */ open_table_def(thd, share, flags | GTS_USE_DISCOVERY); - if (share->error) + if (checked_unlikely(share->error)) { free_table_share(share); lf_hash_delete(&tdc_hash, thd->tdc_hash_pins, key, key_length); @@ -894,7 +894,7 @@ retry: We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. */ - if (share->error) + if (unlikely(share->error)) { open_table_error(share, share->error, share->open_errno); goto err; diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 908d28f6629..f23ec7a1acc 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -112,12 +112,14 @@ TABLE *THD::create_and_open_tmp_table(handlerton *hton, @param db [IN] Database name @param table_name [IN] Table name + @param state [IN] State of temp table to open @return Success Pointer to first used table instance. Failure NULL */ TABLE *THD::find_temporary_table(const char *db, - const char *table_name) + const char *table_name, + Temporary_table_state state) { DBUG_ENTER("THD::find_temporary_table"); @@ -134,7 +136,7 @@ TABLE *THD::find_temporary_table(const char *db, key_length= create_tmp_table_def_key(key, db, table_name); locked= lock_temporary_tables(); - table = find_temporary_table(key, key_length, TMP_TABLE_IN_USE); + table= find_temporary_table(key, key_length, state); if (locked) { DBUG_ASSERT(m_tmp_tables_locked); @@ -153,16 +155,12 @@ TABLE *THD::find_temporary_table(const char *db, @return Success Pointer to first used table instance. Failure NULL */ -TABLE *THD::find_temporary_table(const TABLE_LIST *tl) +TABLE *THD::find_temporary_table(const TABLE_LIST *tl, + Temporary_table_state state) { DBUG_ENTER("THD::find_temporary_table"); - - if (!has_temporary_tables()) - { - DBUG_RETURN(NULL); - } - - TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name()); + TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name(), + state); DBUG_RETURN(table); } @@ -1398,7 +1396,8 @@ bool THD::log_events_and_free_tmp_shares() get_stmt_da()->set_overwrite_status(true); transaction.stmt.mark_dropped_temp_table(); - if ((error= (mysql_bin_log.write(&qinfo) || error))) + bool error2= mysql_bin_log.write(&qinfo); + if (unlikely(error|= error2)) { /* If we're here following THD::cleanup, thence the connection diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index e0385c33fd8..fd33ee4c32b 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -27,7 +27,7 @@ extern "C" { void sql_alloc_error_handler(void) { THD *thd= current_thd; - if (thd) + if (likely(thd)) { if (! thd->is_error()) { diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc index a0d1532e31a..24ab972776c 100644 --- a/sql/threadpool_common.cc +++ b/sql/threadpool_common.cc @@ -171,7 +171,7 @@ void tp_callback(TP_connection *c) c->state = TP_STATE_RUNNING; - if (!thd) + if (unlikely(!thd)) { /* No THD, need to login first. */ DBUG_ASSERT(c->connect); diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc index 012f7c5a439..0cc683c631d 100644 --- a/sql/threadpool_win.cc +++ b/sql/threadpool_win.cc @@ -256,7 +256,7 @@ int TP_connection_win::start_io() If skip_completion_port_on_success is set, we need to handle it right here, because completion callback would not be executed by the pool. */ - if(skip_completion_port_on_success) + if (skip_completion_port_on_success) { CancelThreadpoolIo(io); io_completion_callback(callback_instance, this, &overlapped, last_error, @@ -265,7 +265,7 @@ int TP_connection_win::start_io() return 0; } - if(last_error == ERROR_IO_PENDING) + if (last_error == ERROR_IO_PENDING) { return 0; } diff --git a/sql/transaction.cc b/sql/transaction.cc index d8d435e826a..1c2820200d1 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -203,6 +203,7 @@ bool trans_begin(THD *thd, uint flags) thd->transaction.all.reset(); thd->has_waiter= false; thd->waiting_on_group_commit= false; + thd->transaction.start_time.reset(thd); if (res) DBUG_RETURN(TRUE); @@ -656,7 +657,7 @@ bool trans_savepoint(THD *thd, LEX_CSTRING name) we'll lose a little bit of memory in transaction mem_root, but it'll be free'd when transaction ends anyway */ - if (ha_savepoint(thd, newsv)) + if (unlikely(ha_savepoint(thd, newsv))) DBUG_RETURN(TRUE); newsv->prev= thd->transaction.savepoints; diff --git a/sql/tztime.cc b/sql/tztime.cc index 277709ad9e9..61fbee1731a 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1768,7 +1768,8 @@ end_with_setting_default_tz: most of them once more, but this is OK for system tables open for READ. */ - if (!(global_system_variables.time_zone= my_tz_find(thd, &tmp_tzname2))) + if (unlikely(!(global_system_variables.time_zone= + my_tz_find(thd, &tmp_tzname2)))) { sql_print_error("Fatal error: Illegal or unknown default time zone '%s'", default_tzname); @@ -1783,7 +1784,7 @@ end_with_close: end_with_cleanup: /* if there were error free time zone describing structs */ - if (return_val) + if (unlikely(return_val)) my_tz_free(); end: delete thd; diff --git a/sql/uniques.cc b/sql/uniques.cc index 8ed1ceda6a1..6bc870133ff 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -209,7 +209,7 @@ static double get_merge_many_buffs_cost(uint *buffer, uint last_n_elems, int elem_size, uint compare_factor) { - register int i; + int i; double total_cost= 0.0; uint *buff_elems= buffer; /* #s of elements in each of merged sequences */ @@ -509,7 +509,7 @@ static bool merge_walk(uchar *merge_buffer, size_t merge_buffer_size, key_length); /* if piece_size is aligned reuse_freed_buffer will always hit */ uint piece_size= max_key_count_per_piece * key_length; - uint bytes_read; /* to hold return value of read_to_buffer */ + ulong bytes_read; /* to hold return value of read_to_buffer */ BUFFPEK *top; int res= 1; uint cnt_ofs= key_length - (with_counters ? sizeof(element_count) : 0); @@ -525,7 +525,7 @@ static bool merge_walk(uchar *merge_buffer, size_t merge_buffer_size, top->base= merge_buffer + (top - begin) * piece_size; top->max_keys= max_key_count_per_piece; bytes_read= read_to_buffer(file, top, key_length); - if (bytes_read == (uint) (-1)) + if (unlikely(bytes_read == (ulong) -1)) goto end; DBUG_ASSERT(bytes_read); queue_insert(&queue, (uchar *) top); @@ -554,9 +554,9 @@ static bool merge_walk(uchar *merge_buffer, size_t merge_buffer_size, memcpy(save_key_buff, old_key, key_length); old_key= save_key_buff; bytes_read= read_to_buffer(file, top, key_length); - if (bytes_read == (uint) (-1)) + if (unlikely(bytes_read == (ulong) -1)) goto end; - else if (bytes_read > 0) /* top->key, top->mem_count are reset */ + else if (bytes_read) /* top->key, top->mem_count are reset */ queue_replace_top(&queue); /* in read_to_buffer */ else { @@ -602,7 +602,7 @@ static bool merge_walk(uchar *merge_buffer, size_t merge_buffer_size, } while (--top->mem_count); bytes_read= read_to_buffer(file, top, key_length); - if (bytes_read == (uint) (-1)) + if (unlikely(bytes_read == (ulong) -1)) goto end; } while (bytes_read); diff --git a/sql/uniques.h b/sql/uniques.h index efc79953bb6..654b3692aaa 100644 --- a/sql/uniques.h +++ b/sql/uniques.h @@ -77,7 +77,7 @@ public: inline static int get_cost_calc_buff_size(size_t nkeys, uint key_size, size_t max_in_memory_size) { - register size_t max_elems_in_tree= + size_t max_elems_in_tree= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size); return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree)); } diff --git a/sql/unireg.cc b/sql/unireg.cc index 26f02c8983a..796101e0efb 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -118,7 +118,7 @@ vers_get_field(HA_CREATE_INFO *create_info, List<Create_field> &create_fields, b List_iterator<Create_field> it(create_fields); Create_field *sql_field = NULL; - const LString_i row_field= row_start ? create_info->vers_info.as_row.start + const Lex_ident row_field= row_start ? create_info->vers_info.as_row.start : create_info->vers_info.as_row.end; DBUG_ASSERT(row_field); @@ -194,7 +194,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table, error= pack_vcols(&vcols, create_fields, create_info->check_constraint_list); thd->variables.sql_mode= save_sql_mode; - if (error) + if (unlikely(error)) DBUG_RETURN(frm); if (vcols.length()) @@ -202,7 +202,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING *table, error= pack_header(thd, forminfo, create_fields, create_info, (ulong)data_offset, db_file); - if (error) + if (unlikely(error)) DBUG_RETURN(frm); reclength= uint2korr(forminfo+266); diff --git a/sql/vers_string.h b/sql/vers_string.h index 5460838510e..75abd40d5fa 100644 --- a/sql/vers_string.h +++ b/sql/vers_string.h @@ -17,125 +17,85 @@ #ifndef VERS_STRING_INCLUDED #define VERS_STRING_INCLUDED -struct Compare_strncmp +/* + LEX_CSTRING with comparison semantics. +*/ + +// db and table names: case sensitive (or insensitive) in table_alias_charset +struct Compare_table_names { int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const { - return strncmp(a.str, b.str, a.length); - } - static CHARSET_INFO* charset() - { - return system_charset_info; + DBUG_ASSERT(a.str[a.length] == 0); + DBUG_ASSERT(b.str[b.length] == 0); + return my_strnncoll(table_alias_charset, + (uchar*)a.str, a.length, + (uchar*)b.str, b.length); } }; -template <CHARSET_INFO* &CS= system_charset_info> -struct Compare_my_strcasecmp +// column names and other identifiers: case insensitive in system_charset_info +struct Compare_identifiers { int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const { - DBUG_ASSERT(a.str[a.length] == 0 && b.str[b.length] == 0); - return my_strcasecmp(CS, a.str, b.str); - } - static CHARSET_INFO* charset() - { - return CS; + DBUG_ASSERT(a.str[a.length] == 0); + DBUG_ASSERT(b.str[b.length] == 0); + return my_strcasecmp(system_charset_info, a.str, b.str); } }; -typedef Compare_my_strcasecmp<files_charset_info> Compare_fs; -typedef Compare_my_strcasecmp<table_alias_charset> Compare_t; - -template <class Storage= LEX_CSTRING> -struct LEX_STRING_u : public Storage +class Lex_cstring : public LEX_CSTRING { - LEX_STRING_u() - { - Storage::str= NULL; - Storage::length= 0; - } - LEX_STRING_u(const char *_str, size_t _len, CHARSET_INFO *) - { - Storage::str= _str; - Storage::length= _len; - } - uint32 length() const - { - return (uint32)Storage::length; - } - const char *ptr() const - { - return Storage::str; - } - void set(const char *_str, size_t _len, CHARSET_INFO *) + public: + Lex_cstring() { - Storage::str= _str; - Storage::length= _len; + str= NULL; + length= 0; } - const LEX_CSTRING& lex_cstring() const + Lex_cstring(const char *_str, size_t _len) { - return *this; + str= _str; + length= _len; } - const LEX_STRING& lex_string() const + void set(const char *_str, size_t _len) { - return *(LEX_STRING *)this; + str= _str; + length= _len; } }; -template <class Compare= Compare_strncmp, class Storage= LEX_STRING_u<> > -struct XString : public Storage +template <class Compare> +struct Lex_cstring_with_compare : public Lex_cstring { public: - XString() {} - XString(const char *_str, size_t _len) : - Storage(_str, _len, Compare::charset()) - { - } - XString(const LEX_STRING src) : - Storage(src.str, src.length, Compare::charset()) - { - } - XString(const LEX_CSTRING src) : - Storage(src.str, src.length, Compare::charset()) - { - } - XString(const char *_str) : - Storage(_str, strlen(_str), Compare::charset()) - { - } - bool streq(const XString& b) const - { - return Storage::length() == b.length() && 0 == Compare()(this->lex_cstring(), b.lex_cstring()); + Lex_cstring_with_compare() {} + Lex_cstring_with_compare(const char *_str, size_t _len) : + Lex_cstring(_str, _len) + { } + Lex_cstring_with_compare(const LEX_STRING src) : + Lex_cstring(src.str, src.length) + { } + Lex_cstring_with_compare(const LEX_CSTRING src) : Lex_cstring(src.str, src.length) + { } + Lex_cstring_with_compare(const char *_str) : Lex_cstring(_str, strlen(_str)) + { } + bool streq(const Lex_cstring_with_compare& b) const + { + return Lex_cstring::length == b.length && 0 == Compare()(*this, b); } operator const char* () const { - return Storage::ptr(); - } - operator LEX_CSTRING& () const - { - return this->lex_cstring(); - } - operator LEX_STRING () const - { - LEX_STRING res; - res.str= const_cast<char *>(this->ptr()); - res.length= this->length(); - return res; + return str; } operator bool () const { - return Storage::ptr() != NULL; + return str != NULL; } }; -typedef XString<> LString; -typedef XString<Compare_fs> LString_fs; -typedef XString<Compare_my_strcasecmp<> > LString_i; - -typedef XString<Compare_strncmp, String> SString; -typedef XString<Compare_fs, String> SString_fs; -typedef XString<Compare_t, String> SString_t; - +typedef Lex_cstring_with_compare<Compare_identifiers> Lex_ident; +typedef Lex_cstring_with_compare<Compare_table_names> Lex_table_name; #define XSTRING_WITH_LEN(X) (X).ptr(), (X).length() #define DB_WITH_LEN(X) (X).db.str, (X).db.length diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index a5c39887cbd..f2d90def5ef 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -98,11 +98,11 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd, DBUG_RETURN(WSREP_CB_FAILURE); } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_query_state= QUERY_EXEC; if (thd->wsrep_conflict_state!= REPLAYING) thd->wsrep_conflict_state= NO_CONFLICT; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); if (!buf_len) WSREP_DEBUG("empty rbr buffer to apply: %lld", (long long) wsrep_thd_trx_seqno(thd)); @@ -197,9 +197,9 @@ static wsrep_cb_status_t wsrep_apply_events(THD* thd, } error: - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_query_state= QUERY_IDLE; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); assert(thd->wsrep_exec_mode== REPL_RECV); diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index 4efd6703d03..cafd41b2653 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -425,7 +425,7 @@ void wsrep_dump_rbr_direct(THD* thd, IO_CACHE* cache) break; } } while ((bytes_in_cache= my_b_fill(cache))); - if(cache->error == -1) + if (cache->error == -1) { WSREP_ERROR("RBR inconsistent"); goto cleanup; diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 8044b7a3548..3ffd5d7706b 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -240,12 +240,12 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all) DBUG_RETURN(0); } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); switch (thd->wsrep_exec_mode) { case TOTAL_ORDER: case REPL_RECV: - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); WSREP_DEBUG("Avoiding wsrep rollback for failed DDL: %s", thd->query()); DBUG_RETURN(0); default: break; @@ -262,7 +262,7 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all) } wsrep_cleanup_transaction(thd); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(0); } @@ -275,7 +275,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all) DBUG_RETURN(0); } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && (thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY)) { @@ -306,7 +306,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all) wsrep_cleanup_transaction(thd); } } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(0); } @@ -334,20 +334,20 @@ wsrep_run_wsrep_commit(THD *thd, bool all) if (thd->wsrep_exec_mode == REPL_RECV) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state == MUST_ABORT) { if (wsrep_debug) WSREP_INFO("WSREP: must abort for BF"); DBUG_PRINT("wsrep", ("BF apply commit fail")); thd->wsrep_conflict_state = NO_CONFLICT; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); // // TODO: test all calls of the rollback. // rollback must happen automagically innobase_rollback(hton, thd, 1); // DBUG_RETURN(WSREP_TRX_ERROR); } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } if (thd->wsrep_exec_mode != LOCAL_STATE) DBUG_RETURN(WSREP_TRX_OK); @@ -359,11 +359,11 @@ wsrep_run_wsrep_commit(THD *thd, bool all) DBUG_PRINT("wsrep", ("replicating commit")); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state == MUST_ABORT) { DBUG_PRINT("wsrep", ("replicate commit fail")); thd->wsrep_conflict_state = ABORTED; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); if (wsrep_debug) { WSREP_INFO("innobase_commit, abort %s", (thd->query()) ? thd->query() : "void"); @@ -385,7 +385,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all) { mysql_mutex_unlock(&LOCK_wsrep_replaying); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); mysql_mutex_lock(&thd->mysys_var->mutex); thd_proc_info(thd, "WSREP waiting on replaying"); @@ -413,7 +413,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all) thd->mysys_var->current_cond= 0; mysql_mutex_unlock(&thd->mysys_var->mutex); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); mysql_mutex_lock(&LOCK_wsrep_replaying); } mysql_mutex_unlock(&LOCK_wsrep_replaying); @@ -421,14 +421,14 @@ wsrep_run_wsrep_commit(THD *thd, bool all) if (thd->wsrep_conflict_state == MUST_ABORT) { DBUG_PRINT("wsrep", ("replicate commit fail")); thd->wsrep_conflict_state = ABORTED; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); WSREP_DEBUG("innobase_commit abort after replaying wait %s", (thd->query()) ? thd->query() : "void"); DBUG_RETURN(WSREP_TRX_CERT_FAIL); } thd->wsrep_query_state = QUERY_COMMITTING; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); cache = get_trans_log(thd); rcode = 0; @@ -500,10 +500,10 @@ wsrep_run_wsrep_commit(THD *thd, bool all) WSREP_DEBUG("thd: %lld seqno: %lld BF aborted by provider, will replay", (longlong) thd->thread_id, (longlong) thd->wsrep_trx_meta.gtid.seqno); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_conflict_state = MUST_REPLAY; DBUG_ASSERT(wsrep_thd_trx_seqno(thd) > 0); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); mysql_mutex_lock(&LOCK_wsrep_replaying); wsrep_replaying++; WSREP_DEBUG("replaying increased: %d, thd: %lld", @@ -517,7 +517,7 @@ wsrep_run_wsrep_commit(THD *thd, bool all) DBUG_RETURN(WSREP_TRX_ERROR); } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); DEBUG_SYNC(thd, "wsrep_after_replication"); @@ -574,26 +574,26 @@ wsrep_run_wsrep_commit(THD *thd, bool all) WSREP_LOG_CONFLICT(NULL, thd, FALSE); } } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(WSREP_TRX_CERT_FAIL); case WSREP_SIZE_EXCEEDED: WSREP_ERROR("transaction size exceeded"); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(WSREP_TRX_SIZE_EXCEEDED); case WSREP_CONN_FAIL: WSREP_ERROR("connection failure"); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(WSREP_TRX_ERROR); default: WSREP_ERROR("unknown connection failure"); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(WSREP_TRX_ERROR); } thd->wsrep_query_state= QUERY_EXEC; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_RETURN(WSREP_TRX_OK); } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index def52cb2675..0c051d384c9 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -142,7 +142,7 @@ ulong wsrep_running_threads = 0; // # of currently running wsrep threads ulong my_bind_addr; #ifdef HAVE_PSI_INTERFACE -PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_thd, +PSI_mutex_key key_LOCK_wsrep_rollback, key_LOCK_wsrep_replaying, key_LOCK_wsrep_ready, key_LOCK_wsrep_sst, key_LOCK_wsrep_sst_thread, key_LOCK_wsrep_sst_init, key_LOCK_wsrep_slave_threads, key_LOCK_wsrep_desync, @@ -162,7 +162,6 @@ static PSI_mutex_info wsrep_mutexes[]= { &key_LOCK_wsrep_sst_init, "LOCK_wsrep_sst_init", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_sst, "LOCK_wsrep_sst", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_rollback, "LOCK_wsrep_rollback", PSI_FLAG_GLOBAL}, - { &key_LOCK_wsrep_thd, "THD::LOCK_wsrep_thd", 0}, { &key_LOCK_wsrep_replaying, "LOCK_wsrep_replaying", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_slave_threads, "LOCK_wsrep_slave_threads", PSI_FLAG_GLOBAL}, { &key_LOCK_wsrep_desync, "LOCK_wsrep_desync", PSI_FLAG_GLOBAL}, @@ -1688,16 +1687,16 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, if (thd->wsrep_exec_mode == REPL_RECV) return 0; - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); if (thd->wsrep_conflict_state == MUST_ABORT) { WSREP_INFO("thread: %lld schema: %s query: %s has been aborted due to multi-master conflict", (longlong) thd->thread_id, thd->get_db(), thd->query()); - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); return WSREP_TRX_FAIL; } - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); DBUG_ASSERT(thd->wsrep_exec_mode == LOCAL_STATE); DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno == WSREP_SEQNO_UNDEFINED); @@ -1812,7 +1811,7 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx, const char* schema= key->db_name(); int schema_len= key->db_name_length(); - mysql_mutex_lock(&request_thd->LOCK_wsrep_thd); + mysql_mutex_lock(&request_thd->LOCK_thd_data); /* We consider granting MDL exceptions only for appliers (BF THD) and ones @@ -1836,19 +1835,19 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx, if (request_thd->wsrep_exec_mode == TOTAL_ORDER || request_thd->wsrep_exec_mode == REPL_RECV) { - mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&request_thd->LOCK_thd_data); WSREP_MDL_LOG(DEBUG, "MDL conflict ", schema, schema_len, request_thd, granted_thd); ticket->wsrep_report(wsrep_debug); - mysql_mutex_lock(&granted_thd->LOCK_wsrep_thd); + mysql_mutex_lock(&granted_thd->LOCK_thd_data); if (granted_thd->wsrep_exec_mode == TOTAL_ORDER || granted_thd->wsrep_exec_mode == REPL_RECV) { WSREP_MDL_LOG(INFO, "MDL BF-BF conflict", schema, schema_len, request_thd, granted_thd); ticket->wsrep_report(true); - mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&granted_thd->LOCK_thd_data); ret= true; } else if (granted_thd->lex->sql_command == SQLCOM_FLUSH || @@ -1856,7 +1855,7 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx, { WSREP_DEBUG("BF thread waiting for FLUSH"); ticket->wsrep_report(wsrep_debug); - mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&granted_thd->LOCK_thd_data); ret= false; } else @@ -1881,14 +1880,14 @@ bool wsrep_grant_mdl_exception(MDL_context *requestor_ctx, ticket->wsrep_report(true); } - mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&granted_thd->LOCK_thd_data); wsrep_abort_thd((void *) request_thd, (void *) granted_thd, 1); ret= false; } } else { - mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&request_thd->LOCK_thd_data); } return ret; @@ -2045,9 +2044,9 @@ static inline bool is_replaying_connection(THD *thd) { bool ret; - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); ret= (thd->wsrep_conflict_state == REPLAYING) ? true : false; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); return ret; } @@ -2057,9 +2056,9 @@ static inline bool is_committing_connection(THD *thd) { bool ret; - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); ret= (thd->wsrep_query_state == QUERY_COMMITTING) ? true : false; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); return ret; } @@ -2440,13 +2439,13 @@ wsrep_ws_handle_t* wsrep_thd_ws_handle(THD *thd) void wsrep_thd_LOCK(THD *thd) { - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); } void wsrep_thd_UNLOCK(THD *thd) { - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index c6b1f42ce14..5a13575d904 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -266,8 +266,6 @@ extern my_bool wsrep_preordered_opt; extern handlerton *wsrep_hton; #ifdef HAVE_PSI_INTERFACE -extern PSI_mutex_key key_LOCK_wsrep_thd; -extern PSI_cond_key key_COND_wsrep_thd; extern PSI_mutex_key key_LOCK_wsrep_ready; extern PSI_mutex_key key_COND_wsrep_ready; extern PSI_mutex_key key_LOCK_wsrep_sst; diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index e8dda53c95f..ce6d9688cb3 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -47,7 +47,7 @@ int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff, return 0; } -/* must have (&thd->LOCK_wsrep_thd) */ +/* must have (&thd->LOCK_thd_data) */ void wsrep_client_rollback(THD *thd) { WSREP_DEBUG("client rollback due to BF abort for (%lld), query: %s", @@ -56,7 +56,7 @@ void wsrep_client_rollback(THD *thd) WSREP_ATOMIC_ADD_LONG(&wsrep_bf_aborts_counter, 1); thd->wsrep_conflict_state= ABORTING; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); trans_rollback(thd); if (thd->locked_tables_mode && thd->lock) @@ -86,7 +86,7 @@ void wsrep_client_rollback(THD *thd) (longlong) thd->thread_id); thd->clear_binlog_table_maps(); } - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); thd->wsrep_conflict_state= ABORTED; } @@ -232,7 +232,7 @@ void wsrep_replay_transaction(THD *thd) thd->get_stmt_da()->reset_diagnostics_area(); thd->wsrep_conflict_state= REPLAYING; - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); thd->reset_for_next_command(); thd->reset_killed(); @@ -272,7 +272,7 @@ void wsrep_replay_transaction(THD *thd) if (thd->wsrep_conflict_state!= REPLAYING) WSREP_WARN("lost replaying mode: %d", thd->wsrep_conflict_state ); - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); switch (rcode) { @@ -328,7 +328,7 @@ void wsrep_replay_transaction(THD *thd) /* we're now in inconsistent state, must abort */ /* http://bazaar.launchpad.net/~codership/codership-mysql/5.6/revision/3962#sql/wsrep_thd.cc */ - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); unireg_abort(1); break; @@ -495,30 +495,30 @@ static void wsrep_rollback_process(THD *thd) */ mysql_mutex_unlock(&LOCK_wsrep_rollback); - mysql_mutex_lock(&aborting->LOCK_wsrep_thd); + mysql_mutex_lock(&aborting->LOCK_thd_data); if (aborting->wsrep_conflict_state== ABORTED) { WSREP_DEBUG("WSREP, thd already aborted: %llu state: %d", (long long)aborting->real_id, aborting->wsrep_conflict_state); - mysql_mutex_unlock(&aborting->LOCK_wsrep_thd); + mysql_mutex_unlock(&aborting->LOCK_thd_data); mysql_mutex_lock(&LOCK_wsrep_rollback); continue; } aborting->wsrep_conflict_state= ABORTING; - mysql_mutex_unlock(&aborting->LOCK_wsrep_thd); + mysql_mutex_unlock(&aborting->LOCK_thd_data); set_current_thd(aborting); aborting->store_globals(); - mysql_mutex_lock(&aborting->LOCK_wsrep_thd); + mysql_mutex_lock(&aborting->LOCK_thd_data); wsrep_client_rollback(aborting); WSREP_DEBUG("WSREP rollbacker aborted thd: (%lld %lld)", (longlong) aborting->thread_id, (longlong) aborting->real_id); - mysql_mutex_unlock(&aborting->LOCK_wsrep_thd); + mysql_mutex_unlock(&aborting->LOCK_thd_data); set_current_thd(thd); thd->store_globals(); @@ -558,10 +558,10 @@ enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd, my_bool sync) enum wsrep_conflict_state state = NO_CONFLICT; if (thd) { - if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); + if (sync) mysql_mutex_lock(&thd->LOCK_thd_data); state = thd->wsrep_conflict_state; - if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + if (sync) mysql_mutex_unlock(&thd->LOCK_thd_data); } return state; } @@ -585,12 +585,12 @@ my_bool wsrep_thd_is_BF(THD *thd, my_bool sync) if (wsrep_thd_is_wsrep(thd)) { if (sync) - mysql_mutex_lock(&thd->LOCK_wsrep_thd); + mysql_mutex_lock(&thd->LOCK_thd_data); status = ((thd->wsrep_exec_mode == REPL_RECV) || (thd->wsrep_exec_mode == TOTAL_ORDER)); if (sync) - mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + mysql_mutex_unlock(&thd->LOCK_thd_data); } } return status; @@ -603,12 +603,12 @@ my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync) if (thd_ptr) { THD* thd = (THD*)thd_ptr; - if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); + if (sync) mysql_mutex_lock(&thd->LOCK_thd_data); status = ((thd->wsrep_exec_mode == REPL_RECV) || (thd->wsrep_exec_mode == TOTAL_ORDER) || (thd->wsrep_exec_mode == LOCAL_COMMIT)); - if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + if (sync) mysql_mutex_unlock(&thd->LOCK_thd_data); } return status; } @@ -620,10 +620,10 @@ my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync) if (thd_ptr) { THD* thd = (THD*)thd_ptr; - if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); + if (sync) mysql_mutex_lock(&thd->LOCK_thd_data); status = (thd->wsrep_exec_mode == LOCAL_STATE); - if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); + if (sync) mysql_mutex_unlock(&thd->LOCK_thd_data); } return status; } |