diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 4 | ||||
-rw-r--r-- | sql/field.cc | 116 | ||||
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/gen_lex_token.cc | 8 | ||||
-rw-r--r-- | sql/ha_partition.cc | 3 | ||||
-rw-r--r-- | sql/item.cc | 57 | ||||
-rw-r--r-- | sql/item.h | 10 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 18 | ||||
-rw-r--r-- | sql/item_jsonfunc.cc | 1 | ||||
-rw-r--r-- | sql/lex.h | 40 | ||||
-rw-r--r-- | sql/mysql_upgrade_service.cc | 189 | ||||
-rw-r--r-- | sql/semisync_master_ack_receiver.cc | 58 | ||||
-rw-r--r-- | sql/semisync_master_ack_receiver.h | 147 | ||||
-rw-r--r-- | sql/sp_head.cc | 28 | ||||
-rw-r--r-- | sql/sp_pcontext.cc | 13 | ||||
-rw-r--r-- | sql/sp_pcontext.h | 8 | ||||
-rw-r--r-- | sql/sp_rcontext.cc | 27 | ||||
-rw-r--r-- | sql/sql_class.h | 23 | ||||
-rw-r--r-- | sql/sql_cursor.cc | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 83 | ||||
-rw-r--r-- | sql/sql_lex.h | 18 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 12 | ||||
-rw-r--r-- | sql/sql_select.cc | 14 | ||||
-rw-r--r-- | sql/sql_type_int.h | 28 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 505 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 493 | ||||
-rw-r--r-- | sql/structs.h | 29 | ||||
-rw-r--r-- | sql/upgrade_conf_file.cc | 177 |
29 files changed, 1550 insertions, 567 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 83bf909192e..08457214ea5 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -490,9 +490,11 @@ IF(WIN32) ADD_LIBRARY(winservice STATIC winservice.c) TARGET_LINK_LIBRARIES(winservice shell32) + MYSQL_ADD_EXECUTABLE(mysql_upgrade_service mysql_upgrade_service.cc - COMPONENT Server) + upgrade_conf_file.cc + COMPONENT Server) TARGET_LINK_LIBRARIES(mysql_upgrade_service mysys winservice) ENDIF(WIN32) diff --git a/sql/field.cc b/sql/field.cc index 7e27ed1bfc3..3fe2cee1220 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -62,12 +62,20 @@ const char field_separator=','; #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \ ((ulong) ((1LL << MY_MIN(arg, 4) * 8) - 1)) -#define ASSERT_COLUMN_MARKED_FOR_READ \ - DBUG_ASSERT(!table || !table->read_set || \ - bitmap_is_set(table->read_set, field_index)) -#define ASSERT_COLUMN_MARKED_FOR_WRITE \ - DBUG_ASSERT(is_stat_field || !table || !table->write_set || \ - bitmap_is_set(table->write_set, field_index)) +// Column marked for read or the field set to read out or record[0] or [1] +#define ASSERT_COLUMN_MARKED_FOR_READ \ + DBUG_ASSERT(!table || \ + (!table->read_set || \ + bitmap_is_set(table->read_set, field_index) || \ + (!(ptr >= table->record[0] && \ + ptr < table->record[0] + table->s->reclength)))) + +#define ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED \ + DBUG_ASSERT(is_stat_field || !table || \ + (!table->write_set || \ + bitmap_is_set(table->write_set, field_index) || \ + (!(ptr >= table->record[0] && \ + ptr < table->record[0] + table->s->reclength)))) #define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") @@ -2034,7 +2042,7 @@ longlong Field::convert_decimal2longlong(const my_decimal *val, int Field_int::store_decimal(const my_decimal *val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int err= 0; longlong i= convert_decimal2longlong(val, unsigned_flag, &err); return MY_TEST(err | store(i, unsigned_flag)); @@ -2201,7 +2209,7 @@ void Field_num::make_send_field(Send_field *field) int Field_str::store_decimal(const my_decimal *d) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; double val; /* TODO: use decimal2string? */ int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR & @@ -2271,7 +2279,7 @@ bool Field::get_date(MYSQL_TIME *to, date_mode_t mode) int Field::store_time_dec(const MYSQL_TIME *ltime, uint dec) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[MAX_DATE_STRING_REP_LENGTH]; uint length= (uint) my_TIME_to_str(ltime, buff, dec); /* Avoid conversion when field character set is ASCII compatible */ @@ -2528,7 +2536,7 @@ void Field_decimal::overflow(bool negative) int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff,sizeof(buff), &my_charset_bin); const uchar *from= (uchar*) from_arg; @@ -2894,7 +2902,7 @@ int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs) int Field_decimal::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; if (unsigned_flag && nr < 0) { overflow(1); @@ -2932,7 +2940,7 @@ int Field_decimal::store(double nr) int Field_decimal::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[22]; uint length, int_part; char fyllchar; @@ -3175,7 +3183,7 @@ void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value, bool Field_new_decimal::store_value(const my_decimal *decimal_value, int *native_error) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; DBUG_ENTER("Field_new_decimal::store_value"); #ifndef DBUG_OFF @@ -3233,7 +3241,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) int Field_new_decimal::store(const char *from, size_t length, CHARSET_INFO *charset_arg) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; my_decimal decimal_value; THD *thd= get_thd(); DBUG_ENTER("Field_new_decimal::store(char*)"); @@ -3317,7 +3325,7 @@ int Field_new_decimal::store(const char *from, size_t length, int Field_new_decimal::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; my_decimal decimal_value; int err; THD *thd= get_thd(); @@ -3342,7 +3350,7 @@ int Field_new_decimal::store(double nr) int Field_new_decimal::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; my_decimal decimal_value; int err; @@ -3364,7 +3372,7 @@ int Field_new_decimal::store(longlong nr, bool unsigned_val) int Field_new_decimal::store_decimal(const my_decimal *decimal_value) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; return store_value(decimal_value); } @@ -3581,7 +3589,7 @@ int Field_int::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) int Field_tiny::store(const char *from,size_t len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error; longlong rnd; @@ -3593,7 +3601,7 @@ int Field_tiny::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_tiny::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; nr=rint(nr); if (unsigned_flag) @@ -3636,7 +3644,7 @@ int Field_tiny::store(double nr) int Field_tiny::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if (unsigned_flag) @@ -3741,7 +3749,7 @@ void Field_tiny::sql_type(String &res) const int Field_short::store(const char *from,size_t len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int store_tmp; int error; longlong rnd; @@ -3755,7 +3763,7 @@ int Field_short::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_short::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int16 res; nr=rint(nr); @@ -3800,7 +3808,7 @@ int Field_short::store(double nr) int Field_short::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int16 res; @@ -3915,7 +3923,7 @@ void Field_short::sql_type(String &res) const int Field_medium::store(const char *from,size_t len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int store_tmp; int error; longlong rnd; @@ -3929,7 +3937,7 @@ int Field_medium::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_medium::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; nr=rint(nr); if (unsigned_flag) @@ -3975,7 +3983,7 @@ int Field_medium::store(double nr) int Field_medium::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if (unsigned_flag) @@ -4113,7 +4121,7 @@ void Field_medium::sql_type(String &res) const int Field_long::store(const char *from,size_t len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; long store_tmp; int error; longlong rnd; @@ -4127,7 +4135,7 @@ int Field_long::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_long::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int32 res; nr=rint(nr); @@ -4172,7 +4180,7 @@ int Field_long::store(double nr) int Field_long::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; int32 res; @@ -4286,7 +4294,7 @@ void Field_long::sql_type(String &res) const int Field_longlong::store(const char *from,size_t len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; char *end; ulonglong tmp; @@ -4309,7 +4317,7 @@ int Field_longlong::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_longlong::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; Converter_double_to_longlong conv(nr, unsigned_flag); if (unlikely(conv.error())) @@ -4322,7 +4330,7 @@ int Field_longlong::store(double nr) int Field_longlong::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if (unlikely(nr < 0)) // Only possible error @@ -4433,7 +4441,7 @@ void Field_longlong::sql_type(String &res) const void Field_longlong::set_max() { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; set_notnull(); int8store(ptr, unsigned_flag ? ULONGLONG_MAX : LONGLONG_MAX); } @@ -4470,7 +4478,7 @@ int Field_float::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_float::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= truncate_double(&nr, field_length, not_fixed ? NOT_FIXED_DEC : dec, unsigned_flag, FLT_MAX); @@ -4649,7 +4657,7 @@ int Field_double::store(const char *from,size_t len,CHARSET_INFO *cs) int Field_double::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= truncate_double(&nr, field_length, not_fixed ? NOT_FIXED_DEC : dec, unsigned_flag, DBL_MAX); @@ -5026,7 +5034,7 @@ my_time_t Field_timestamp::get_timestamp(const uchar *pos, int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt, const ErrConv *str, int was_cut) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; static const timeval zero= {0, (uint) 0 }; // Handle totally bad values @@ -5471,7 +5479,7 @@ void Field_timestampf::store_TIMEVAL(const timeval &tm) void Field_timestampf::set_max() { DBUG_ENTER("Field_timestampf::set_max"); - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; DBUG_ASSERT(dec == TIME_SECOND_PART_DIGITS); set_notnull(); @@ -5543,7 +5551,7 @@ int Field_datetime::store_TIME_with_warning(const Datetime *dt, const ErrConv *str, int was_cut) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; // Handle totally bad values if (!dt->is_valid_datetime()) return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATETIME); @@ -5684,7 +5692,7 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd, int Field_time::store_TIME_with_warning(const Time *t, const ErrConv *str, int warn) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; // Handle totally bad values if (!t->is_valid_time()) return store_invalid_with_warning(str, warn, MYSQL_TIMESTAMP_TIME); @@ -6096,7 +6104,7 @@ bool Field_timef::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) int Field_year::store(const char *from, size_t len,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char *end; int error; longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); @@ -6144,7 +6152,7 @@ int Field_year::store(double nr) int Field_year::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; if (nr < 0 || (nr >= 100 && nr <= 1900) || nr > 2155) { *ptr= 0; @@ -6238,7 +6246,7 @@ int Field_date_common::store_TIME_with_warning(const Datetime *dt, const ErrConv *str, int was_cut) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; // Handle totally bad values if (!dt->is_valid_datetime()) return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATE); @@ -6876,7 +6884,7 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end, int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length; int rc; @@ -6922,7 +6930,7 @@ int Field_str::store(longlong nr, bool unsigned_val) int Field_str::store(double nr) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint local_char_length= MY_MIN(sizeof(buff), field_length / field_charset->mbmaxlen); @@ -7419,7 +7427,7 @@ int Field_varstring::save_field_metadata(uchar *metadata_ptr) int Field_varstring::store(const char *from,size_t length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint copy_length; int rc; @@ -7956,7 +7964,7 @@ String *Field_longstr::uncompress(String *val_buffer, String *val_ptr, int Field_varstring_compressed::store(const char *from, size_t length, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint compressed_length; int rc= compress((char*) get_data(), field_length, from, (uint) length, Field_varstring_compressed::max_display_length(), @@ -8088,7 +8096,7 @@ int Field_blob::copy_value(Field_blob *from) int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; size_t copy_length, new_length; uint copy_len; char *tmp; @@ -8576,7 +8584,7 @@ uint Field_blob::is_equal(Create_field *new_field) int Field_blob_compressed::store(const char *from, size_t length, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint compressed_length; uint max_length= max_data_length(); uint to_length= (uint) MY_MIN(max_length, @@ -8919,7 +8927,7 @@ void Field_enum::store_type(ulonglong value) int Field_enum::store(const char *from,size_t length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int err= 0; char buff[STRING_BUFFER_USUAL_SIZE]; String tmpstr(buff,sizeof(buff), &my_charset_bin); @@ -8971,7 +8979,7 @@ int Field_enum::store(double nr) int Field_enum::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; if ((ulonglong) nr > typelib->count || nr == 0) { @@ -9102,7 +9110,7 @@ Field *Field_enum::make_new_field(MEM_ROOT *root, TABLE *new_table, int Field_set::store(const char *from,size_t length,CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; bool got_warning= 0; int err= 0; char *not_used; @@ -9142,7 +9150,7 @@ int Field_set::store(const char *from,size_t length,CHARSET_INFO *cs) int Field_set::store(longlong nr, bool unsigned_val) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int error= 0; ulonglong max_nr; @@ -9521,7 +9529,7 @@ uint Field_bit::is_equal(Create_field *new_field) int Field_bit::store(const char *from, size_t length, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int delta; for (; length && !*from; from++, length--) // skip left 0's @@ -9957,7 +9965,7 @@ Field_bit_as_char::Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, int Field_bit_as_char::store(const char *from, size_t length, CHARSET_INFO *cs) { - ASSERT_COLUMN_MARKED_FOR_WRITE; + ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; int delta; uchar bits= (uchar) (field_length & 7); diff --git a/sql/field.h b/sql/field.h index eb39b6bcec9..d5cfe2faa86 100644 --- a/sql/field.h +++ b/sql/field.h @@ -541,6 +541,7 @@ public: bool utf8; /* Already in utf8 */ Item *expr; LEX_CSTRING name; /* Name of constraint */ + /* see VCOL_* (VCOL_FIELD_REF, ...) */ uint flags; Virtual_column_info() diff --git a/sql/gen_lex_token.cc b/sql/gen_lex_token.cc index c03bfe66f47..7e0cfd097f9 100644 --- a/sql/gen_lex_token.cc +++ b/sql/gen_lex_token.cc @@ -33,7 +33,7 @@ from bison. See also YYMAXUTOK. */ -#define MY_MAX_TOKEN 1000 +#define MY_MAX_TOKEN 1100 /** Generated token. */ struct gen_lex_token_string { @@ -255,9 +255,11 @@ void compute_tokens() set_start_expr_token(STARTS_SYM); set_start_expr_token(ENDS_SYM); set_start_expr_token(DEFAULT); - set_start_expr_token(RETURN_SYM); + set_start_expr_token(RETURN_MARIADB_SYM); + set_start_expr_token(RETURN_ORACLE_SYM); set_start_expr_token(IF_SYM); - set_start_expr_token(ELSEIF_SYM); + set_start_expr_token(ELSEIF_MARIADB_SYM); + set_start_expr_token(ELSEIF_ORACLE_SYM); set_start_expr_token(CASE_SYM); set_start_expr_token(WHEN_SYM); set_start_expr_token(WHILE_SYM); diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 37a3decdbca..2115c39339c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3516,7 +3516,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) if (init_partition_bitmaps()) goto err_alloc; - if (unlikely((error= + if (!MY_TEST(m_is_clone_of) && + unlikely((error= m_part_info->set_partition_bitmaps(m_partitions_to_open)))) goto err_alloc; diff --git a/sql/item.cc b/sql/item.cc index d4cfa790986..fc1669fe9f1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7375,13 +7375,21 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg) return this; if (!item_equal && used_tables() != tab_map) return this; - return get_field_item_for_having(thd, this, sel); + Item *item= get_field_item_for_having(thd, this, sel); + if (item) + item->marker|= SUBSTITUTION_FL; + return item; } Item *Item_direct_view_ref::derived_field_transformer_for_having(THD *thd, uchar *arg) { + if ((*ref)->marker & SUBSTITUTION_FL) + { + this->marker|= SUBSTITUTION_FL; + return this; + } st_select_lex *sel= (st_select_lex *)arg; table_map tab_map= sel->master_unit()->derived->table->map; if ((item_equal && !(item_equal->used_tables() & tab_map)) || @@ -7432,13 +7440,20 @@ Item *Item_field::derived_field_transformer_for_where(THD *thd, uchar *arg) st_select_lex *sel= (st_select_lex *)arg; Item *producing_item= find_producing_item(this, sel); if (producing_item) - return producing_item->build_clone(thd); + { + Item *producing_clone= producing_item->build_clone(thd); + if (producing_clone) + producing_clone->marker|= SUBSTITUTION_FL; + return producing_clone; + } return this; } Item *Item_direct_view_ref::derived_field_transformer_for_where(THD *thd, uchar *arg) { + if ((*ref)->marker & SUBSTITUTION_FL) + return (*ref); if (item_equal) { st_select_lex *sel= (st_select_lex *)arg; @@ -7489,7 +7504,13 @@ Item *Item_field::grouping_field_transformer_for_where(THD *thd, uchar *arg) st_select_lex *sel= (st_select_lex *)arg; Field_pair *gr_field= find_matching_grouping_field(this, sel); if (gr_field) - return gr_field->corresponding_item->build_clone(thd); + { + Item *producing_clone= + gr_field->corresponding_item->build_clone(thd); + if (producing_clone) + producing_clone->marker|= SUBSTITUTION_FL; + return producing_clone; + } return this; } @@ -7498,6 +7519,11 @@ Item * Item_direct_view_ref::grouping_field_transformer_for_where(THD *thd, uchar *arg) { + if ((*ref)->marker & SUBSTITUTION_FL) + { + this->marker|= SUBSTITUTION_FL; + return this; + } if (!item_equal) return this; st_select_lex *sel= (st_select_lex *)arg; @@ -9021,8 +9047,19 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) fixed= 1; return FALSE; } + + /* + DEFAULT() do not need table field so should not ask handler to bring + field value (mark column for read) + */ + enum_column_usage save_column_usage= thd->column_usage; + thd->column_usage= COLUMNS_READ; if (arg->fix_fields_if_needed(thd, &arg)) + { + thd->column_usage= save_column_usage; goto error; + } + thd->column_usage= save_column_usage; real_arg= arg->real_item(); if (real_arg->type() != FIELD_ITEM) @@ -9042,15 +9079,19 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) goto error; memcpy((void *)def_field, (void *)field_arg->field, field_arg->field->size_of()); - IF_DBUG_ASSERT(def_field->is_stat_field=1,); // a hack to fool ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED + // If non-constant default value expression if (def_field->default_value && def_field->default_value->flags) { uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length()); if (!newptr) goto error; + /* + Even if DEFAULT() do not read tables fields, the default value + expression can do it. + */ fix_session_vcol_expr_for_read(thd, def_field, def_field->default_value); if (should_mark_column(thd->column_usage)) - def_field->default_value->expr->walk(&Item::register_field_in_read_map, 1, 0); + def_field->default_value->expr->update_used_tables(); def_field->move_field(newptr+1, def_field->maybe_null() ? newptr : 0, 1); } else @@ -9074,6 +9115,12 @@ void Item_default_value::print(String *str, enum_query_type query_type) return; } str->append(STRING_WITH_LEN("default(")); + /* + We take DEFAULT from a field so do not need it value in case of const + tables but its name so we set QT_NO_DATA_EXPANSION (as we print for + table definition, also we do not need table and database name) + */ + query_type= (enum_query_type) (query_type | QT_NO_DATA_EXPANSION); arg->print(str, query_type); str->append(')'); } diff --git a/sql/item.h b/sql/item.h index c2666c35c67..2c9395ff89d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -151,6 +151,7 @@ bool mark_unsupported_function(const char *w1, const char *w2, #define NO_EXTRACTION_FL (1 << 6) #define FULL_EXTRACTION_FL (1 << 7) +#define SUBSTITUTION_FL (1 << 8) #define EXTRACTION_MASK (NO_EXTRACTION_FL | FULL_EXTRACTION_FL) extern const char *item_empty_name; @@ -1183,6 +1184,10 @@ public: If value is not null null_value flag will be reset to FALSE. */ virtual longlong val_int()=0; + Longlong_hybrid to_longlong_hybrid() + { + return Longlong_hybrid(val_int(), unsigned_flag); + } Longlong_null to_longlong_null() { longlong nr= val_int(); @@ -6020,6 +6025,11 @@ public: return false; } table_map used_tables() const; + virtual void update_used_tables() + { + if (field && field->default_value) + field->default_value->expr->update_used_tables(); + } Field *get_tmp_table_field() { return 0; } Item *get_tmp_table_item(THD *thd) { return this; } Item_field *field_for_view_update() { return 0; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f5c49214076..9488391f602 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2044,7 +2044,7 @@ bool Item_func_between::fix_length_and_dec() if (!args[0] || !args[1] || !args[2]) return TRUE; if (m_comparator.aggregate_for_comparison(Item_func_between::func_name(), - args, 3, true)) + args, 3, false)) { DBUG_ASSERT(current_thd->is_error()); return TRUE; @@ -2152,12 +2152,20 @@ longlong Item_func_between::val_int_cmp_string() longlong Item_func_between::val_int_cmp_int() { - longlong value= args[0]->val_int(), a, b; + Longlong_hybrid value= args[0]->to_longlong_hybrid(); if ((null_value= args[0]->null_value)) return 0; /* purecov: inspected */ - a= args[1]->val_int(); - b= args[2]->val_int(); - return val_int_cmp_int_finalize(value, a, b); + Longlong_hybrid a= args[1]->to_longlong_hybrid(); + Longlong_hybrid b= args[2]->to_longlong_hybrid(); + if (!args[1]->null_value && !args[2]->null_value) + return (longlong) ((value.cmp(a) >= 0 && value.cmp(b) <= 0) != negated); + if (args[1]->null_value && args[2]->null_value) + null_value= true; + else if (args[1]->null_value) + null_value= value.cmp(b) <= 0; // not null if false range. + else + null_value= value.cmp(a) >= 0; + return (longlong) (!null_value && negated); } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 4ec481cf439..31d5dd50b35 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -1563,6 +1563,7 @@ bool Item_func_json_array_append::fix_length_and_dec() } fix_char_length_ulonglong(char_length); + maybe_null= 1; return FALSE; } diff --git a/sql/lex.h b/sql/lex.h index d336c273a18..da20468d593 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -82,15 +82,15 @@ static SYMBOL symbols[] = { { "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH)}, { "BACKUP", SYM(BACKUP_SYM)}, { "BEFORE", SYM(BEFORE_SYM)}, - { "BEGIN", SYM(BEGIN_SYM)}, + { "BEGIN", SYM(BEGIN_MARIADB_SYM)}, { "BETWEEN", SYM(BETWEEN_SYM)}, { "BIGINT", SYM(BIGINT)}, { "BINARY", SYM(BINARY)}, { "BINLOG", SYM(BINLOG_SYM)}, { "BIT", SYM(BIT_SYM)}, - { "BLOB", SYM(BLOB_SYM)}, + { "BLOB", SYM(BLOB_MARIADB_SYM)}, { "BLOCK", SYM(BLOCK_SYM)}, - { "BODY", SYM(BODY_SYM)}, + { "BODY", SYM(BODY_MARIADB_SYM)}, { "BOOL", SYM(BOOL_SYM)}, { "BOOLEAN", SYM(BOOLEAN_SYM)}, { "BOTH", SYM(BOTH)}, @@ -115,7 +115,7 @@ static SYMBOL symbols[] = { { "CIPHER", SYM(CIPHER_SYM)}, { "CLASS_ORIGIN", SYM(CLASS_ORIGIN_SYM)}, { "CLIENT", SYM(CLIENT_SYM)}, - { "CLOB", SYM(CLOB)}, + { "CLOB", SYM(CLOB_MARIADB_SYM)}, { "CLOSE", SYM(CLOSE_SYM)}, { "COALESCE", SYM(COALESCE)}, { "CODE", SYM(CODE_SYM)}, @@ -145,7 +145,7 @@ static SYMBOL symbols[] = { { "CONSTRAINT_SCHEMA", SYM(CONSTRAINT_SCHEMA_SYM)}, { "CONTAINS", SYM(CONTAINS_SYM)}, { "CONTEXT", SYM(CONTEXT_SYM)}, - { "CONTINUE", SYM(CONTINUE_SYM)}, + { "CONTINUE", SYM(CONTINUE_MARIADB_SYM)}, { "CONTRIBUTORS", SYM(CONTRIBUTORS_SYM)}, { "CONVERT", SYM(CONVERT_SYM)}, { "CPU", SYM(CPU_SYM)}, @@ -176,7 +176,7 @@ static SYMBOL symbols[] = { { "DEALLOCATE", SYM(DEALLOCATE_SYM)}, { "DEC", SYM(DECIMAL_SYM)}, { "DECIMAL", SYM(DECIMAL_SYM)}, - { "DECLARE", SYM(DECLARE_SYM)}, + { "DECLARE", SYM(DECLARE_MARIADB_SYM)}, { "DEFAULT", SYM(DEFAULT)}, { "DEFINER", SYM(DEFINER_SYM)}, { "DELAYED", SYM(DELAYED_SYM)}, @@ -205,8 +205,8 @@ static SYMBOL symbols[] = { { "DYNAMIC", SYM(DYNAMIC_SYM)}, { "EACH", SYM(EACH_SYM)}, { "ELSE", SYM(ELSE)}, - { "ELSEIF", SYM(ELSEIF_SYM)}, - { "ELSIF", SYM(ELSIF_SYM)}, + { "ELSEIF", SYM(ELSEIF_MARIADB_SYM)}, + { "ELSIF", SYM(ELSIF_MARIADB_SYM)}, { "ENABLE", SYM(ENABLE_SYM)}, { "ENCLOSED", SYM(ENCLOSED)}, { "END", SYM(END)}, @@ -226,9 +226,9 @@ static SYMBOL symbols[] = { { "EXCHANGE", SYM(EXCHANGE_SYM)}, { "EXCLUDE", SYM(EXCLUDE_SYM)}, { "EXECUTE", SYM(EXECUTE_SYM)}, - { "EXCEPTION", SYM(EXCEPTION_SYM)}, + { "EXCEPTION", SYM(EXCEPTION_MARIADB_SYM)}, { "EXISTS", SYM(EXISTS)}, - { "EXIT", SYM(EXIT_SYM)}, + { "EXIT", SYM(EXIT_MARIADB_SYM)}, { "EXPANSION", SYM(EXPANSION_SYM)}, { "EXPORT", SYM(EXPORT_SYM)}, { "EXPLAIN", SYM(DESCRIBE)}, @@ -264,7 +264,7 @@ static SYMBOL symbols[] = { { "GET_FORMAT", SYM(GET_FORMAT)}, { "GET", SYM(GET_SYM)}, { "GLOBAL", SYM(GLOBAL_SYM)}, - { "GOTO", SYM(GOTO_SYM)}, + { "GOTO", SYM(GOTO_MARIADB_SYM)}, { "GRANT", SYM(GRANT)}, { "GRANTS", SYM(GRANTS)}, { "GROUP", SYM(GROUP_SYM)}, @@ -434,7 +434,7 @@ static SYMBOL symbols[] = { { "NOTFOUND", SYM(NOTFOUND_SYM)}, { "NO_WRITE_TO_BINLOG", SYM(NO_WRITE_TO_BINLOG)}, { "NULL", SYM(NULL_SYM)}, - { "NUMBER", SYM(NUMBER_SYM)}, + { "NUMBER", SYM(NUMBER_MARIADB_SYM)}, { "NUMERIC", SYM(NUMERIC_SYM)}, { "NVARCHAR", SYM(NVARCHAR_SYM)}, { "OF", SYM(OF_SYM)}, @@ -451,13 +451,13 @@ static SYMBOL symbols[] = { { "OPTIONALLY", SYM(OPTIONALLY)}, { "OR", SYM(OR_SYM)}, { "ORDER", SYM(ORDER_SYM)}, - { "OTHERS", SYM(OTHERS_SYM)}, + { "OTHERS", SYM(OTHERS_MARIADB_SYM)}, { "OUT", SYM(OUT_SYM)}, { "OUTER", SYM(OUTER)}, { "OUTFILE", SYM(OUTFILE)}, { "OVER", SYM(OVER_SYM)}, { "OWNER", SYM(OWNER_SYM)}, - { "PACKAGE", SYM(PACKAGE_SYM)}, + { "PACKAGE", SYM(PACKAGE_MARIADB_SYM)}, { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, { "PAGE", SYM(PAGE_SYM)}, { "PAGE_CHECKSUM", SYM(PAGE_CHECKSUM_SYM)}, @@ -495,9 +495,9 @@ static SYMBOL symbols[] = { { "QUARTER", SYM(QUARTER_SYM)}, { "QUERY", SYM(QUERY_SYM)}, { "QUICK", SYM(QUICK)}, - { "RAISE", SYM(RAISE_SYM)}, + { "RAISE", SYM(RAISE_MARIADB_SYM)}, { "RANGE", SYM(RANGE_SYM)}, - { "RAW", SYM(RAW)}, + { "RAW", SYM(RAW_MARIADB_SYM)}, { "READ", SYM(READ_SYM)}, { "READ_ONLY", SYM(READ_ONLY_SYM)}, { "READ_WRITE", SYM(READ_WRITE_SYM)}, @@ -534,7 +534,7 @@ static SYMBOL symbols[] = { { "RESTRICT", SYM(RESTRICT)}, { "RESUME", SYM(RESUME_SYM)}, { "RETURNED_SQLSTATE",SYM(RETURNED_SQLSTATE_SYM)}, - { "RETURN", SYM(RETURN_SYM)}, + { "RETURN", SYM(RETURN_MARIADB_SYM)}, { "RETURNING", SYM(RETURNING_SYM)}, { "RETURNS", SYM(RETURNS_SYM)}, { "REUSE", SYM(REUSE_SYM)}, @@ -549,7 +549,7 @@ static SYMBOL symbols[] = { { "ROW", SYM(ROW_SYM)}, { "ROWCOUNT", SYM(ROWCOUNT_SYM)}, /* Oracle-N */ { "ROWS", SYM(ROWS_SYM)}, - { "ROWTYPE", SYM(ROWTYPE_SYM)}, + { "ROWTYPE", SYM(ROWTYPE_MARIADB_SYM)}, { "ROW_COUNT", SYM(ROW_COUNT_SYM)}, { "ROW_FORMAT", SYM(ROW_FORMAT_SYM)}, { "RTREE", SYM(RTREE_SYM)}, @@ -694,7 +694,7 @@ static SYMBOL symbols[] = { { "VARBINARY", SYM(VARBINARY)}, { "VARCHAR", SYM(VARCHAR)}, { "VARCHARACTER", SYM(VARCHAR)}, - { "VARCHAR2", SYM(VARCHAR2)}, + { "VARCHAR2", SYM(VARCHAR2_MARIADB_SYM)}, { "VARIABLES", SYM(VARIABLES)}, { "VARYING", SYM(VARYING)}, { "VIA", SYM(VIA_SYM)}, @@ -739,7 +739,7 @@ static SYMBOL sql_functions[] = { { "DATE_ADD", SYM(DATE_ADD_INTERVAL)}, { "DATE_SUB", SYM(DATE_SUB_INTERVAL)}, { "DATE_FORMAT", SYM(DATE_FORMAT_SYM)}, - { "DECODE", SYM(DECODE_SYM)}, + { "DECODE", SYM(DECODE_MARIADB_SYM)}, { "DENSE_RANK", SYM(DENSE_RANK_SYM)}, { "EXTRACT", SYM(EXTRACT_SYM)}, { "FIRST_VALUE", SYM(FIRST_VALUE_SYM)}, diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index 1a3df4f5536..9ea78accf44 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -29,6 +29,9 @@ #include <winservice.h> #include <windows.h> +#include <string> + +extern int upgrade_config_file(const char *myini_path); /* We're using version APIs */ #pragma comment(lib, "version") @@ -47,6 +50,8 @@ static char mysqlupgrade_path[MAX_PATH]; static char defaults_file_param[MAX_PATH + 16]; /*--defaults-file=<path> */ static char logfile_path[MAX_PATH]; +char my_ini_bck[MAX_PATH]; +mysqld_service_properties service_properties; static char *opt_service; static SC_HANDLE service; static SC_HANDLE scm; @@ -59,7 +64,7 @@ HANDLE logfile_handle; Maybe,they can be made parameters */ static unsigned int startup_timeout= 60; -static unsigned int shutdown_timeout= 60; +static unsigned int shutdown_timeout= 60*60; static struct my_option my_long_options[]= { @@ -112,6 +117,7 @@ static void die(const char *fmt, ...) fprintf(stderr, "FATAL ERROR: "); vfprintf(stderr, fmt, args); + fputc('\n', stderr); if (logfile_path[0]) { fprintf(stderr, "Additional information can be found in the log file %s", @@ -122,6 +128,11 @@ static void die(const char *fmt, ...) fflush(stdout); /* Cleanup */ + if (my_ini_bck[0]) + { + MoveFileEx(my_ini_bck, service_properties.inifile,MOVEFILE_REPLACE_EXISTING); + } + /* Stop service that we started, if it was not initally running at program start. @@ -309,77 +320,76 @@ void initiate_mysqld_shutdown() } } - -/* - Change service configuration (binPath) to point to mysqld from - this installation. -*/ -static void change_service_config() +static void get_service_config() { - - char defaults_file[MAX_PATH]; - char default_character_set[64]; - char buf[MAX_PATH]; - char commandline[3*MAX_PATH + 19]; - int i; - - scm= OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if(!scm) + scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (!scm) die("OpenSCManager failed with %u", GetLastError()); - service= OpenService(scm, opt_service, SERVICE_ALL_ACCESS); + service = OpenService(scm, opt_service, SERVICE_ALL_ACCESS); if (!service) die("OpenService failed with %u", GetLastError()); - BYTE config_buffer[8*1024]; - LPQUERY_SERVICE_CONFIGW config= (LPQUERY_SERVICE_CONFIGW)config_buffer; - DWORD size= sizeof(config_buffer); + BYTE config_buffer[8 * 1024]; + LPQUERY_SERVICE_CONFIGW config = (LPQUERY_SERVICE_CONFIGW)config_buffer; + DWORD size = sizeof(config_buffer); DWORD needed; if (!QueryServiceConfigW(service, config, size, &needed)) die("QueryServiceConfig failed with %u", GetLastError()); - mysqld_service_properties props; - if (get_mysql_service_properties(config->lpBinaryPathName, &props)) + if (get_mysql_service_properties(config->lpBinaryPathName, &service_properties)) { die("Not a valid MySQL service"); } - int my_major= MYSQL_VERSION_ID/10000; - int my_minor= (MYSQL_VERSION_ID %10000)/100; - int my_patch= MYSQL_VERSION_ID%100; + int my_major = MYSQL_VERSION_ID / 10000; + int my_minor = (MYSQL_VERSION_ID % 10000) / 100; + int my_patch = MYSQL_VERSION_ID % 100; - if(my_major < props.version_major || - (my_major == props.version_major && my_minor < props.version_minor)) + if (my_major < service_properties.version_major || + (my_major == service_properties.version_major && my_minor < service_properties.version_minor)) { die("Can not downgrade, the service is currently running as version %d.%d.%d" - ", my version is %d.%d.%d", props.version_major, props.version_minor, - props.version_patch, my_major, my_minor, my_patch); + ", my version is %d.%d.%d", service_properties.version_major, service_properties.version_minor, + service_properties.version_patch, my_major, my_minor, my_patch); } - - if(props.inifile[0] == 0) + if (service_properties.inifile[0] == 0) { /* Weird case, no --defaults-file in service definition, need to create one. */ - sprintf_s(props.inifile, MAX_PATH, "%s\\my.ini", props.datadir); + sprintf_s(service_properties.inifile, MAX_PATH, "%s\\my.ini", service_properties.datadir); } + sprintf(defaults_file_param, "--defaults-file=%s", service_properties.inifile); +} +/* + Change service configuration (binPath) to point to mysqld from + this installation. +*/ +static void change_service_config() +{ + char defaults_file[MAX_PATH]; + char default_character_set[64]; + char buf[MAX_PATH]; + char commandline[3 * MAX_PATH + 19]; + int i; /* Write datadir to my.ini, after converting backslashes to unix style slashes. */ - strcpy_s(buf, MAX_PATH, props.datadir); + strcpy_s(buf, MAX_PATH, service_properties.datadir); for(i= 0; buf[i]; i++) { if (buf[i] == '\\') buf[i]= '/'; } - WritePrivateProfileString("mysqld", "datadir",buf, props.inifile); + WritePrivateProfileString("mysqld", "datadir",buf, service_properties.inifile); /* Remove basedir from defaults file, otherwise the service wont come up in the new version, and will complain about mismatched message file. */ - WritePrivateProfileString("mysqld", "basedir",NULL, props.inifile); + WritePrivateProfileString("mysqld", "basedir",NULL, service_properties.inifile); /* Replace default-character-set with character-set-server, to avoid @@ -397,7 +407,7 @@ static void change_service_config() default_character_set, defaults_file); } - sprintf(defaults_file_param,"--defaults-file=%s", props.inifile); + sprintf(defaults_file_param,"--defaults-file=%s", service_properties.inifile); sprintf_s(commandline, "\"%s\" \"%s\" \"%s\"", mysqld_path, defaults_file_param, opt_service); if (!ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, @@ -449,23 +459,97 @@ int main(int argc, char **argv) reads them from pipe and uses as progress indicator. */ setvbuf(stdout, NULL, _IONBF, 0); + int phase = 0; + int max_phases=10; + get_service_config(); - log("Phase 1/8: Changing service configuration"); - change_service_config(); + bool my_ini_exists; + bool old_mysqld_exe_exists; - log("Phase 2/8: Stopping service"); + log("Phase %d/%d: Stopping service", ++phase,max_phases); stop_mysqld_service(); + my_ini_exists = (GetFileAttributes(service_properties.inifile) != INVALID_FILE_ATTRIBUTES); + if (!my_ini_exists) + { + HANDLE h = CreateFile(service_properties.inifile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + 0, CREATE_NEW, 0 ,0); + if (h != INVALID_HANDLE_VALUE) + { + CloseHandle(h); + } + else if (GetLastError() != ERROR_FILE_EXISTS) + { + die("Can't create ini file %s, last error %u", service_properties.inifile, GetLastError()); + } + } + + old_mysqld_exe_exists = (GetFileAttributes(service_properties.mysqld_exe) != INVALID_FILE_ATTRIBUTES); + log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases, my_ini_exists ? "" : "(skipped)"); + + snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK", service_properties.inifile); + CopyFile(service_properties.inifile, my_ini_bck, FALSE); + upgrade_config_file(service_properties.inifile); + + log("Phase %d/%d: Ensuring innodb slow shutdown%s", ++phase, max_phases, + old_mysqld_exe_exists?",this can take some time":"(skipped)"); + + char socket_param[FN_REFLEN]; + sprintf_s(socket_param, "--socket=mysql_upgrade_service_%d", + GetCurrentProcessId()); + + DWORD start_duration_ms = 0; + + if (old_mysqld_exe_exists) + { + /* Start/stop server with --loose-innodb-fast-shutdown=0 */ + mysqld_process = (HANDLE)run_tool(P_NOWAIT, service_properties.mysqld_exe, + defaults_file_param, "--loose-innodb-fast-shutdown=0", "--skip-networking", + "--enable-named-pipe", socket_param, "--skip-slave-start", NULL); + + if (mysqld_process == INVALID_HANDLE_VALUE) + { + die("Cannot start mysqld.exe process, last error =%u", GetLastError()); + } + char pipe_name[64]; + snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\mysql_upgrade_service_%u", + GetCurrentProcessId()); + for (;;) + { + if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT) + die("mysqld.exe did not start"); + + if (WaitNamedPipe(pipe_name, 0)) + { + // Server started, shut it down. + initiate_mysqld_shutdown(); + if (WaitForSingleObject((HANDLE)mysqld_process, shutdown_timeout * 1000) != WAIT_OBJECT_0) + { + die("Could not shutdown server started with '--innodb-fast-shutdown=0'"); + } + DWORD exit_code; + if (!GetExitCodeProcess((HANDLE)mysqld_process, &exit_code)) + { + die("Could not get mysqld's exit code"); + } + if (exit_code) + { + die("Could not get successfully shutdown mysqld"); + } + CloseHandle(mysqld_process); + break; + } + Sleep(500); + start_duration_ms += 500; + } + } /* Start mysqld.exe as non-service skipping privileges (so we do not care about the password). But disable networking and enable pipe for communication, for security reasons. */ - char socket_param[FN_REFLEN]; - sprintf_s(socket_param,"--socket=mysql_upgrade_service_%d", - GetCurrentProcessId()); - log("Phase 3/8: Starting mysqld for upgrade"); + log("Phase %d/%d: Starting mysqld for upgrade",++phase,max_phases); mysqld_process= (HANDLE)run_tool(P_NOWAIT, mysqld_path, defaults_file_param, "--skip-networking", "--skip-grant-tables", "--enable-named-pipe", socket_param,"--skip-slave-start", NULL); @@ -475,8 +559,8 @@ int main(int argc, char **argv) die("Cannot start mysqld.exe process, errno=%d", errno); } - log("Phase 4/8: Waiting for startup to complete"); - DWORD start_duration_ms= 0; + log("Phase %d/%d: Waiting for startup to complete",++phase,max_phases); + start_duration_ms= 0; for(;;) { if (WaitForSingleObject(mysqld_process, 0) != WAIT_TIMEOUT) @@ -493,7 +577,7 @@ int main(int argc, char **argv) start_duration_ms+= 500; } - log("Phase 5/8: Running mysql_upgrade"); + log("Phase %d/%d: Running mysql_upgrade",++phase,max_phases); int upgrade_err= (int) run_tool(P_WAIT, mysqlupgrade_path, "--protocol=pipe", "--force", socket_param, NULL); @@ -501,10 +585,13 @@ int main(int argc, char **argv) if (upgrade_err) die("mysql_upgrade failed with error code %d\n", upgrade_err); - log("Phase 6/8: Initiating server shutdown"); + log("Phase %d/%d: Changing service configuration", ++phase, max_phases); + change_service_config(); + + log("Phase %d/%d: Initiating server shutdown",++phase, max_phases); initiate_mysqld_shutdown(); - log("Phase 7/8: Waiting for shutdown to complete"); + log("Phase %d/%d: Waiting for shutdown to complete",++phase, max_phases); if (WaitForSingleObject(mysqld_process, shutdown_timeout*1000) != WAIT_OBJECT_0) { @@ -514,7 +601,7 @@ int main(int argc, char **argv) CloseHandle(mysqld_process); mysqld_process= NULL; - log("Phase 8/8: Starting service%s", + log("Phase %d/%d: Starting service%s",++phase,max_phases, (initial_service_state == SERVICE_RUNNING)?"":" (skipped)"); if (initial_service_state == SERVICE_RUNNING) { @@ -527,6 +614,10 @@ int main(int argc, char **argv) CloseServiceHandle(scm); if (logfile_handle) CloseHandle(logfile_handle); + if(my_ini_bck[0]) + { + DeleteFile(my_ini_bck); + } my_end(0); exit(0); } diff --git a/sql/semisync_master_ack_receiver.cc b/sql/semisync_master_ack_receiver.cc index fc36ee35d5d..607d4844658 100644 --- a/sql/semisync_master_ack_receiver.cc +++ b/sql/semisync_master_ack_receiver.cc @@ -173,25 +173,6 @@ inline void Ack_receiver::wait_for_slave_connection() mysql_cond_wait(&m_cond, &m_mutex); } -my_socket Ack_receiver::get_slave_sockets(fd_set *fds, uint *count) -{ - my_socket max_fd= INVALID_SOCKET; - Slave *slave; - I_List_iterator<Slave> it(m_slaves); - - *count= 0; - FD_ZERO(fds); - while ((slave= it++)) - { - (*count)++; - my_socket fd= slave->sock_fd(); - max_fd= (fd > max_fd ? fd : max_fd); - FD_SET(fd, fds); - } - - return max_fd; -} - /* Auxilary function to initialize a NET object with given net buffer. */ static void init_net(NET *net, unsigned char *buff, unsigned int buff_len) { @@ -208,14 +189,17 @@ void Ack_receiver::run() THD *thd= new THD(next_thread_id(), false, true); NET net; unsigned char net_buff[REPLY_MESSAGE_MAX_LENGTH]; - fd_set read_fds; - my_socket max_fd= INVALID_SOCKET; - Slave *slave; my_thread_init(); DBUG_ENTER("Ack_receiver::run"); +#ifdef HAVE_POLL + Poll_socket_listener listener(m_slaves); +#else + Select_socket_listener listener(m_slaves); +#endif //HAVE_POLL + sql_print_information("Starting ack receiver thread"); thd->system_thread= SYSTEM_THREAD_SEMISYNC_MASTER_BACKGROUND; thd->thread_stack= (char*) &thd; @@ -231,9 +215,9 @@ void Ack_receiver::run() while (1) { - fd_set fds; int ret; - uint slave_count; + uint slave_count __attribute__((unused))= 0; + Slave *slave; mysql_mutex_lock(&m_mutex); if (unlikely(m_status == ST_STOPPING)) @@ -249,23 +233,26 @@ void Ack_receiver::run() continue; } - max_fd= get_slave_sockets(&read_fds, &slave_count); + if ((slave_count= listener.init_slave_sockets()) == 0) + goto end; m_slaves_changed= false; - DBUG_PRINT("info", ("fd count %u, max_fd %d", slave_count,(int) max_fd)); +#ifdef HAVE_POLL + DBUG_PRINT("info", ("fd count %u", slave_count)); +#else + DBUG_PRINT("info", ("fd count %u, max_fd %d", slave_count, + (int) listener.get_max_fd())); +#endif } - struct timeval tv= {1, 0}; - fds= read_fds; - /* select requires max fd + 1 for the first argument */ - ret= select((int)(max_fd+1), &fds, NULL, NULL, &tv); + ret= listener.listen_on_sockets(); if (ret <= 0) { mysql_mutex_unlock(&m_mutex); ret= DBUG_EVALUATE_IF("rpl_semisync_simulate_select_error", -1, ret); - if (ret == -1) - sql_print_information("Failed to select() on semi-sync dump sockets, " + if (ret == -1 && errno != EINTR) + sql_print_information("Failed to wait on semi-sync sockets, " "error: errno=%d", socket_errno); /* Sleep 1us, so other threads can catch the m_mutex easily. */ my_sleep(1); @@ -273,11 +260,10 @@ void Ack_receiver::run() } set_stage_info(stage_reading_semi_sync_ack); - I_List_iterator<Slave> it(m_slaves); - + Slave_ilist_iterator it(m_slaves); while ((slave= it++)) { - if (FD_ISSET(slave->sock_fd(), &fds)) + if (listener.is_socket_active(slave)) { ulong len; @@ -289,7 +275,7 @@ void Ack_receiver::run() repl_semisync_master.report_reply_packet(slave->server_id(), net.read_pos, len); else if (net.last_errno == ER_NET_READ_ERROR) - FD_CLR(slave->sock_fd(), &read_fds); + listener.clear_socket_info(slave); } } mysql_mutex_unlock(&m_mutex); diff --git a/sql/semisync_master_ack_receiver.h b/sql/semisync_master_ack_receiver.h index 619748a2159..feb3a51ccea 100644 --- a/sql/semisync_master_ack_receiver.h +++ b/sql/semisync_master_ack_receiver.h @@ -20,6 +20,22 @@ #include "my_pthread.h" #include "sql_class.h" #include "semisync.h" +#include <vector> + +struct Slave :public ilink +{ + THD *thd; + Vio vio; +#ifdef HAVE_POLL + uint m_fds_index; +#endif + my_socket sock_fd() const { return vio.mysql_socket.fd; } + uint server_id() const { return thd->variables.server_id; } +}; + +typedef I_List<Slave> Slave_ilist; +typedef I_List_iterator<Slave> Slave_ilist_iterator; + /** Ack_receiver is responsible to control ack receive thread and maintain slave information used by ack receive thread. @@ -92,18 +108,7 @@ private: /* If slave list is updated(add or remove). */ bool m_slaves_changed; - class Slave :public ilink - { -public: - THD *thd; - Vio vio; - - my_socket sock_fd() { return vio.mysql_socket.fd; } - uint server_id() { return thd->variables.server_id; } - }; - - I_List<Slave> m_slaves; - + Slave_ilist m_slaves; pthread_t m_pid; /* Declare them private, so no one can copy the object. */ @@ -112,8 +117,124 @@ public: void set_stage_info(const PSI_stage_info &stage); void wait_for_slave_connection(); - my_socket get_slave_sockets(fd_set *fds, uint *count); }; + +#ifdef HAVE_POLL +#include <sys/poll.h> +#include <vector> + +class Poll_socket_listener +{ +public: + Poll_socket_listener(const Slave_ilist &slaves) + :m_slaves(slaves) + { + } + + bool listen_on_sockets() + { + return poll(m_fds.data(), m_fds.size(), 1000 /*1 Second timeout*/); + } + + bool is_socket_active(const Slave *slave) + { + return m_fds[slave->m_fds_index].revents & POLLIN; + } + + void clear_socket_info(const Slave *slave) + { + m_fds[slave->m_fds_index].fd= -1; + m_fds[slave->m_fds_index].events= 0; + } + + uint init_slave_sockets() + { + Slave_ilist_iterator it(const_cast<Slave_ilist&>(m_slaves)); + Slave *slave; + uint fds_index= 0; + + m_fds.clear(); + while ((slave= it++)) + { + pollfd poll_fd; + poll_fd.fd= slave->sock_fd(); + poll_fd.events= POLLIN; + m_fds.push_back(poll_fd); + slave->m_fds_index= fds_index++; + } + return fds_index; + } + +private: + const Slave_ilist &m_slaves; + std::vector<pollfd> m_fds; +}; + +#else //NO POLL + +class Select_socket_listener +{ +public: + Select_socket_listener(const Slave_ilist &slaves) + :m_slaves(slaves), m_max_fd(INVALID_SOCKET) + { + } + + bool listen_on_sockets() + { + /* Reinitialze the fds with active fds before calling select */ + m_fds= m_init_fds; + struct timeval tv= {1,0}; + /* select requires max fd + 1 for the first argument */ + return select((int) m_max_fd+1, &m_fds, NULL, NULL, &tv); + } + + bool is_socket_active(const Slave *slave) + { + return FD_ISSET(slave->sock_fd(), &m_fds); + } + + void clear_socket_info(const Slave *slave) + { + FD_CLR(slave->sock_fd(), &m_init_fds); + } + + uint init_slave_sockets() + { + Slave_ilist_iterator it(const_cast<Slave_ilist&>(m_slaves)); + Slave *slave; + uint fds_index= 0; + + FD_ZERO(&m_init_fds); + while ((slave= it++)) + { + my_socket socket_id= slave->sock_fd(); + m_max_fd= (socket_id > m_max_fd ? socket_id : m_max_fd); +#ifndef WINDOWS + if (socket_id > FD_SETSIZE) + { + sql_print_error("Semisync slave socket fd is %u. " + "select() cannot handle if the socket fd is " + "greater than %u (FD_SETSIZE).", socket_id, FD_SETSIZE); + return 0; + } +#endif //WINDOWS + FD_SET(socket_id, &m_init_fds); + fds_index++; + } + return fds_index; + } + my_socket get_max_fd() { return m_max_fd; } + +private: + const Slave_ilist &m_slaves; + my_socket m_max_fd; + fd_set m_init_fds; + fd_set m_fds; +}; + +#endif //HAVE_POLL + extern Ack_receiver ack_receiver; #endif diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c86edc47bf9..56b4fc8c948 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -4444,24 +4444,26 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) */ if (!row->arguments()) { - sp_cursor tmp(thd, &m_lex_keeper); + sp_cursor tmp(thd, &m_lex_keeper, true); // Open the cursor without copying data - if (!(ret= tmp.open_view_structure_only(thd))) + if (!(ret= tmp.open(thd))) { Row_definition_list defs; + /* + Create row elements on the caller arena. + It's the same arena that was used during sp_rcontext::create(). + This puts cursor%ROWTYPE elements on the same mem_root + where explicit ROW elements and table%ROWTYPE reside: + - tmp.export_structure() allocates new Spvar_definition instances + and their components (such as TYPELIBs). + - row->row_create_items() creates new Item_field instances. + They all are created on the same mem_root. + */ + Query_arena current_arena; + thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena); if (!(ret= tmp.export_structure(thd, &defs))) - { - /* - Create row elements on the caller arena. - It's the same arena that was used during sp_rcontext::create(). - This puts cursor%ROWTYPE elements on the same mem_root - where explicit ROW elements and table%ROWTYPE reside. - */ - Query_arena current_arena; - thd->set_n_backup_active_arena(thd->spcont->callers_arena, ¤t_arena); row->row_create_items(thd, &defs); - thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena); - } + thd->restore_active_arena(thd->spcont->callers_arena, ¤t_arena); tmp.close(thd); } } diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 83d674e7500..b0fee18ef05 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -409,6 +409,19 @@ sp_condition_value *sp_pcontext::find_condition(const LEX_CSTRING *name, NULL; } +sp_condition_value * +sp_pcontext::find_declared_or_predefined_condition(THD *thd, + const LEX_CSTRING *name) + const +{ + sp_condition_value *p= find_condition(name, false); + if (p) + return p; + if (thd->variables.sql_mode & MODE_ORACLE) + return find_predefined_condition(name); + return NULL; +} + static sp_condition_value // Warnings diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index e30af3fcde5..e607315cdaf 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -592,13 +592,7 @@ public: bool current_scope_only) const; sp_condition_value * - find_declared_or_predefined_condition(const LEX_CSTRING *name) const - { - sp_condition_value *p= find_condition(name, false); - if (p) - return p; - return find_predefined_condition(name); - } + find_declared_or_predefined_condition(THD *thd, const LEX_CSTRING *name) const; bool declare_condition(THD *thd, const LEX_CSTRING *name, sp_condition_value *val) diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index a31631e33ef..e71a529bc07 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -750,33 +750,6 @@ int sp_cursor::open(THD *thd) } -/** - Open the cursor, but do not copy data. - This method is used to fetch the cursor structure - to cursor%ROWTYPE routine variables. - Data copying is suppressed by setting thd->lex->limit_rows_examined to 0. -*/ -int sp_cursor::open_view_structure_only(THD *thd) -{ - int res; - int thd_no_errors_save= thd->no_errors; - Item *limit_rows_examined= thd->lex->limit_rows_examined; // No data copying - if (!(thd->lex->limit_rows_examined= new (thd->mem_root) Item_uint(thd, 0))) - return -1; - thd->no_errors= true; // Suppress ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT - DBUG_ASSERT(!thd->killed); - res= open(thd); - /* - The query possibly exited on LIMIT ROWS EXAMINED and set thd->killed. - Reset it now. - */ - thd->reset_killed(); - thd->no_errors= thd_no_errors_save; - thd->lex->limit_rows_examined= limit_rows_examined; - return res; -} - - int sp_cursor::close(THD *thd) { if (! server_side_cursor) diff --git a/sql/sql_class.h b/sql/sql_class.h index 52cc54b85ef..c0d1e3c8ce5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5108,6 +5108,14 @@ public: Currently all intercepting classes derive from select_result_interceptor. */ virtual bool is_result_interceptor()=0; + + /* + This method is used to distinguish an normal SELECT from the cursor + structure discovery for cursor%ROWTYPE routine variables. + If this method returns "true", then a SELECT execution performs only + all preparation stages, but does not fetch any rows. + */ + virtual bool view_structure_only() const { return false; } }; @@ -5227,9 +5235,13 @@ private: { List<sp_variable> *spvar_list; uint field_count; + bool m_view_structure_only; bool send_data_to_variable_list(List<sp_variable> &vars, List<Item> &items); public: - Select_fetch_into_spvars(THD *thd_arg): select_result_interceptor(thd_arg) {} + Select_fetch_into_spvars(THD *thd_arg, bool view_structure_only) + :select_result_interceptor(thd_arg), + m_view_structure_only(view_structure_only) + {} void reset(THD *thd_arg) { select_result_interceptor::reset(thd_arg); @@ -5242,16 +5254,17 @@ private: virtual bool send_eof() { return FALSE; } virtual int send_data(List<Item> &items); virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u); + virtual bool view_structure_only() const { return m_view_structure_only; } }; public: sp_cursor() - :result(NULL), + :result(NULL, false), m_lex_keeper(NULL), server_side_cursor(NULL) { } - sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper) - :result(thd_arg), + sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper, bool view_structure_only) + :result(thd_arg, view_structure_only), m_lex_keeper(lex_keeper), server_side_cursor(NULL) {} @@ -5263,8 +5276,6 @@ public: int open(THD *thd); - int open_view_structure_only(THD *thd); - int close(THD *thd); my_bool is_open() diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 2a200d279b5..4f3b15c3254 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -92,6 +92,11 @@ public: if (materialized_cursor) materialized_cursor->on_table_fill_finished(); } + + bool view_structure_only() const + { + return result->view_structure_only(); + } }; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a7b36c901d6..1b8f448553b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -856,6 +856,32 @@ int Lex_input_stream::find_keyword(Lex_ident_cli_st *kwd, DBUG_ASSERT(tok >= get_buf()); DBUG_ASSERT(tok < get_end_of_query()); + if (m_thd->variables.sql_mode & MODE_ORACLE) + { + switch (symbol->tok) { + case BEGIN_MARIADB_SYM: return BEGIN_ORACLE_SYM; + case BLOB_MARIADB_SYM: return BLOB_ORACLE_SYM; + case BODY_MARIADB_SYM: return BODY_ORACLE_SYM; + case CLOB_MARIADB_SYM: return CLOB_ORACLE_SYM; + case CONTINUE_MARIADB_SYM: return CONTINUE_ORACLE_SYM; + case DECLARE_MARIADB_SYM: return DECLARE_ORACLE_SYM; + case DECODE_MARIADB_SYM: return DECODE_ORACLE_SYM; + case ELSEIF_MARIADB_SYM: return ELSEIF_ORACLE_SYM; + case ELSIF_MARIADB_SYM: return ELSIF_ORACLE_SYM; + case EXCEPTION_MARIADB_SYM: return EXCEPTION_ORACLE_SYM; + case EXIT_MARIADB_SYM: return EXIT_ORACLE_SYM; + case GOTO_MARIADB_SYM: return GOTO_ORACLE_SYM; + case NUMBER_MARIADB_SYM: return NUMBER_ORACLE_SYM; + case OTHERS_MARIADB_SYM: return OTHERS_ORACLE_SYM; + case PACKAGE_MARIADB_SYM: return PACKAGE_ORACLE_SYM; + case RAISE_MARIADB_SYM: return RAISE_ORACLE_SYM; + case RAW_MARIADB_SYM: return RAW_ORACLE_SYM; + case RETURN_MARIADB_SYM: return RETURN_ORACLE_SYM; + case ROWTYPE_MARIADB_SYM: return ROWTYPE_ORACLE_SYM; + case VARCHAR2_MARIADB_SYM: return VARCHAR2_ORACLE_SYM; + } + } + if ((symbol->tok == NOT_SYM) && (m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE)) return NOT2_SYM; @@ -1470,6 +1496,12 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) } /* Fall through */ case MY_LEX_CHAR: // Unknown or single char token + if (c == '%' && (m_thd->variables.sql_mode & MODE_ORACLE)) + { + next_state= MY_LEX_START; + return PERCENT_ORACLE_SYM; + } + /* Fall through */ case MY_LEX_SKIP: // This should not happen if (c != ')') next_state= MY_LEX_START; // Allow signed numbers @@ -1908,8 +1940,13 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) case MY_LEX_SET_VAR: // Check if ':=' if (yyPeek() != '=') { - state= MY_LEX_CHAR; // Return ':' - break; + next_state= MY_LEX_START; + if (m_thd->variables.sql_mode & MODE_ORACLE) + { + yylval->kwd.set_keyword(m_tok_start, 1); + return COLON_ORACLE_SYM; + } + return (int) ':'; } yySkip(); return (SET_VAR); @@ -5926,7 +5963,7 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd, return true; DBUG_ASSERT(thd->lex == this); bounds->m_direction= 1; - bounds->m_upper_bound= NULL; + bounds->m_target_bound= NULL; bounds->m_implicit_cursor= true; return false; } @@ -5970,7 +6007,7 @@ bool LEX::sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop) Item_splocal *args[2]; for (uint i= 0 ; i < 2; i++) { - sp_variable *src= i == 0 ? loop.m_index : loop.m_upper_bound; + sp_variable *src= i == 0 ? loop.m_index : loop.m_target_bound; args[i]= new (thd->mem_root) Item_splocal(thd, &sp_rcontext_handler_local, &src->name, src->offset, src->type_handler()); @@ -6033,7 +6070,7 @@ bool LEX::sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop, my_error(ER_SP_UNDECLARED_VAR, MYF(0), item->full_name()); return true; } - if ((item= bounds.m_upper_bound->get_item())->type() == Item::FIELD_ITEM) + if ((item= bounds.m_target_bound->get_item())->type() == Item::FIELD_ITEM) { // We're here is the upper bound is unknown identifier my_error(ER_SP_UNDECLARED_VAR, MYF(0), item->full_name()); @@ -6043,11 +6080,11 @@ bool LEX::sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop, bounds.m_index->sp_add_for_loop_variable(thd, index, bounds.m_index->get_item()))) return true; - if (unlikely(!(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_target_bound= + bounds.m_target_bound-> + sp_add_for_loop_target_bound(thd, + bounds. + m_target_bound->get_item())))) return true; loop->m_direction= bounds.m_direction; loop->m_implicit_cursor= 0; @@ -6110,7 +6147,7 @@ bool LEX::sp_for_loop_cursor_declarations(THD *thd, bounds.m_index, item_func_sp))) return true; - loop->m_upper_bound= NULL; + loop->m_target_bound= NULL; loop->m_direction= bounds.m_direction; loop->m_cursor_offset= coffs; loop->m_implicit_cursor= bounds.m_implicit_cursor; @@ -6916,6 +6953,30 @@ Item *LEX::make_item_colon_ident_ident(THD *thd, } +Item *LEX::make_item_plsql_cursor_attr(THD *thd, const LEX_CSTRING *name, + plsql_cursor_attr_t attr) +{ + uint offset; + if (unlikely(!spcont || !spcont->find_cursor(name, &offset, false))) + { + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), name->str); + return NULL; + } + switch (attr) { + case PLSQL_CURSOR_ATTR_ISOPEN: + return new (thd->mem_root) Item_func_cursor_isopen(thd, name, offset); + case PLSQL_CURSOR_ATTR_FOUND: + return new (thd->mem_root) Item_func_cursor_found(thd, name, offset); + case PLSQL_CURSOR_ATTR_NOTFOUND: + return new (thd->mem_root) Item_func_cursor_notfound(thd, name, offset); + case PLSQL_CURSOR_ATTR_ROWCOUNT: + return new (thd->mem_root) Item_func_cursor_rowcount(thd, name, offset); + } + DBUG_ASSERT(0); + return NULL; +} + + Item *LEX::make_item_sysvar(THD *thd, enum_var_type type, const LEX_CSTRING *name, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index b10119b55de..3604082612d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -207,6 +207,16 @@ enum enum_view_suid VIEW_SUID_DEFAULT= 2 }; + +enum plsql_cursor_attr_t +{ + PLSQL_CURSOR_ATTR_ISOPEN, + PLSQL_CURSOR_ATTR_FOUND, + PLSQL_CURSOR_ATTR_NOTFOUND, + PLSQL_CURSOR_ATTR_ROWCOUNT +}; + + /* These may not be declared yet */ class Table_ident; class sql_exchange; @@ -3878,6 +3888,10 @@ public: Item *make_item_colon_ident_ident(THD *thd, const Lex_ident_cli_st *a, const Lex_ident_cli_st *b); + // PLSQL: cursor%ISOPEN etc + Item *make_item_plsql_cursor_attr(THD *thd, const LEX_CSTRING *name, + plsql_cursor_attr_t attr); + // For "SELECT @@var", "SELECT @@var.field" Item *make_item_sysvar(THD *thd, enum_var_type type, @@ -3958,9 +3972,9 @@ public: /* Integer range FOR LOOP methods */ sp_variable *sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name, Item *value); - sp_variable *sp_add_for_loop_upper_bound(THD *thd, Item *value) + sp_variable *sp_add_for_loop_target_bound(THD *thd, Item *value) { - LEX_CSTRING name= { STRING_WITH_LEN("[upper_bound]") }; + LEX_CSTRING name= { STRING_WITH_LEN("[target_bound]") }; return sp_add_for_loop_variable(thd, &name, value); } bool sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 6def798b1c7..cb822fc2e98 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2915,6 +2915,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) { SELECT_LEX *sl= lex->all_selects_list; DBUG_ENTER("reinit_stmt_before_use"); + Window_spec *win_spec; /* We have to update "thd" pointer in LEX, all its units and in LEX::result, @@ -2983,6 +2984,17 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) /* Fix ORDER list */ for (order= sl->order_list.first; order; order= order->next) order->item= &order->item_ptr; + /* Fix window functions too */ + List_iterator<Window_spec> it(sl->window_specs); + + while ((win_spec= it++)) + { + for (order= win_spec->partition_list->first; order; order= order->next) + order->item= &order->item_ptr; + for (order= win_spec->order_list->first; order; order= order->next) + order->item= &order->item_ptr; + } + { #ifdef DBUG_ASSERT_EXISTS bool res= diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7ae4e7aaa27..1c7010ebb81 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2655,6 +2655,18 @@ setup_subq_exit: if (!tables_list || !table_count) { choose_tableless_subquery_plan(); + + /* The output has atmost one row */ + if (group_list) + { + group_list= NULL; + group_optimized_away= 1; + rollup.state= ROLLUP::STATE_NONE; + } + order= NULL; + simple_order= TRUE; + select_distinct= FALSE; + if (select_lex->have_window_funcs()) { if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) @@ -4079,7 +4091,7 @@ void JOIN::exec_inner() procedure ? procedure_fields_list : *fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); - error= do_select(this, procedure); + error= result->view_structure_only() ? false : do_select(this, procedure); /* Accumulate the counts from all join iterations of all join parts. */ thd->inc_examined_row_count(join_examined_rows); DBUG_PRINT("counts", ("thd->examined_row_count: %lu", diff --git a/sql/sql_type_int.h b/sql/sql_type_int.h index 1cc93415176..f9fb163b6a6 100644 --- a/sql/sql_type_int.h +++ b/sql/sql_type_int.h @@ -51,11 +51,24 @@ class Longlong_hybrid: public Longlong { protected: bool m_unsigned; + int cmp_signed(const Longlong_hybrid& other) const + { + return m_value < other.m_value ? -1 : m_value == other.m_value ? 0 : 1; + } + int cmp_unsigned(const Longlong_hybrid& other) const + { + return (ulonglong) m_value < (ulonglong) other.m_value ? -1 : + m_value == other.m_value ? 0 : 1; + } public: Longlong_hybrid(longlong nr, bool unsigned_flag) :Longlong(nr), m_unsigned(unsigned_flag) { } bool is_unsigned() const { return m_unsigned; } + bool is_unsigned_outside_of_signed_range() const + { + return m_unsigned && ((ulonglong) m_value) > (ulonglong) LONGLONG_MAX; + } bool neg() const { return m_value < 0 && !m_unsigned; } ulonglong abs() const { @@ -65,6 +78,21 @@ public: return ((ulonglong) LONGLONG_MAX) + 1; return m_value < 0 ? -m_value : m_value; } + int cmp(const Longlong_hybrid& other) const + { + if (m_unsigned == other.m_unsigned) + return m_unsigned ? cmp_unsigned(other) : cmp_signed(other); + if (is_unsigned_outside_of_signed_range()) + return 1; + if (other.is_unsigned_outside_of_signed_range()) + return -1; + /* + The unsigned argument is in the range 0..LONGLONG_MAX. + The signed argument is in the range LONGLONG_MIN..LONGLONG_MAX. + Safe to compare as signed. + */ + return cmp_signed(other); + } }; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 63240c1547d..d74da408dfc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2580,7 +2580,7 @@ int multi_update::do_updates() check_opt_it.rewind(); while(TABLE *tbl= check_opt_it++) { - if (unlikely((local_error= tbl->file->ha_rnd_init(1)))) + if (unlikely((local_error= tbl->file->ha_rnd_init(0)))) { err_table= tbl; goto err; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3a2c9bb67d6..350bc7a351c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -687,11 +687,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) Lex_for_loop_st for_loop; Lex_for_loop_bounds_st for_loop_bounds; Lex_trim_st trim; - struct - { - LEX_CSTRING name; - uint offset; - } sp_cursor_name_and_offset; vers_history_point_t vers_history_point; struct { @@ -789,6 +784,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) DDL_options_st object_ddl_options; enum vers_sys_type_t vers_range_unit; enum Column_definition::enum_column_versioning vers_column_versioning; + enum plsql_cursor_attr_t plsql_cursor_attr; } %{ @@ -799,10 +795,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 52 shift/reduce conflicts. + Currently there are 48 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 52 +%expect 48 /* Comments for TOKENS. @@ -846,7 +842,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token BIT_AND /* MYSQL-FUNC */ %token BIT_OR /* MYSQL-FUNC */ %token BIT_XOR /* MYSQL-FUNC */ -%token BLOB_SYM /* SQL-2003-R */ +%token BLOB_MARIADB_SYM /* SQL-2003-R */ +%token BLOB_ORACLE_SYM /* Oracle-R */ +%token BODY_ORACLE_SYM /* Oracle-R */ %token BOTH /* SQL-2003-R */ %token BY /* SQL-2003-R */ %token CALL_SYM /* SQL-2003-R */ @@ -859,7 +857,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token COLLATE_SYM /* SQL-2003-R */ %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ %token CONSTRAINT /* SQL-2003-R */ -%token CONTINUE_SYM /* SQL-2003-R */ +%token CONTINUE_MARIADB_SYM /* SQL-2003-R, Oracle-R */ +%token CONTINUE_ORACLE_SYM /* SQL-2003-R, Oracle-R */ %token CONVERT_SYM /* SQL-2003-N */ %token COUNT_SYM /* SQL-2003-N */ %token CREATE /* SQL-2003-R */ @@ -880,7 +879,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DAY_SECOND_SYM %token DECIMAL_NUM %token DECIMAL_SYM /* SQL-2003-R */ -%token DECLARE_SYM /* SQL-2003-R */ +%token DECLARE_MARIADB_SYM /* SQL-2003-R */ +%token DECLARE_ORACLE_SYM /* Oracle-R */ %token DEFAULT /* SQL-2003-R */ %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ @@ -897,7 +897,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DUAL_SYM %token EACH_SYM /* SQL-2003-R */ %token ELSE /* SQL-2003-R */ -%token ELSEIF_SYM +%token ELSEIF_MARIADB_SYM +%token ELSIF_ORACLE_SYM /* PLSQL-R */ %token ENCLOSED %token END_OF_INPUT /* INTERNAL */ %token EQUAL_SYM /* OPERATOR */ @@ -916,6 +917,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token FROM %token FULLTEXT_SYM %token GE +%token GOTO_ORACLE_SYM /* Oracle-R */ %token GRANT /* SQL-2003-R */ %token GROUP_SYM /* SQL-2003-R */ %token GROUP_CONCAT_SYM @@ -1004,14 +1006,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token OR2_SYM %token ORDER_SYM /* SQL-2003-R */ %token OR_SYM /* SQL-2003-R */ +%token OTHERS_ORACLE_SYM /* SQL-2011-N, PLSQL-R */ %token OUTER %token OUTFILE %token OUT_SYM /* SQL-2003-R */ %token OVER_SYM +%token PACKAGE_ORACLE_SYM /* Oracle-R */ %token PAGE_CHECKSUM_SYM %token PARAM_MARKER %token PARSE_VCOL_EXPR_SYM %token PARTITION_SYM /* SQL-2003-R */ +%token PERCENT_ORACLE_SYM /* INTERNAL */ %token PERCENT_RANK_SYM %token PERCENTILE_CONT_SYM %token PERCENTILE_DISC_SYM @@ -1020,6 +1025,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token PRIMARY_SYM /* SQL-2003-R */ %token PROCEDURE_SYM /* SQL-2003-R */ %token PURGE +%token RAISE_ORACLE_SYM /* PLSQL-R */ %token RANGE_SYM /* SQL-2003-R */ %token RANK_SYM %token READS_SYM /* SQL-2003-R */ @@ -1038,10 +1044,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token RESIGNAL_SYM /* SQL-2003-R */ %token RESTRICT %token RETURNING_SYM -%token RETURN_SYM /* SQL-2003-R */ +%token RETURN_MARIADB_SYM /* SQL-2003-R, PLSQL-R */ +%token RETURN_ORACLE_SYM /* SQL-2003-R, PLSQL-R */ %token REVOKE /* SQL-2003-R */ %token RIGHT /* SQL-2003-R */ %token ROWS_SYM /* SQL-2003-R */ +%token ROWTYPE_ORACLE_SYM /* PLSQL-R */ %token ROW_NUMBER_SYM %token SECOND_MICROSECOND_SYM %token SELECT_SYM /* SQL-2003-R */ @@ -1126,13 +1134,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* Keywords that have different reserved status in std/oracle modes. */ -%token <kwd> BODY_SYM /* Oracle-R */ -%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 */ +%token <kwd> BODY_MARIADB_SYM // Oracle-R +%token <kwd> ELSEIF_ORACLE_SYM +%token <kwd> ELSIF_MARIADB_SYM // PLSQL-R +%token <kwd> EXCEPTION_ORACLE_SYM // SQL-2003-N, PLSQL-R +%token <kwd> GOTO_MARIADB_SYM // Oracle-R +%token <kwd> OTHERS_MARIADB_SYM // SQL-2011-N, PLSQL-R +%token <kwd> PACKAGE_MARIADB_SYM // Oracle-R +%token <kwd> RAISE_MARIADB_SYM // PLSQL-R +%token <kwd> ROWTYPE_MARIADB_SYM // PLSQL-R /* Non-reserved keywords @@ -1157,7 +1167,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> BEGIN_MARIADB_SYM /* SQL-2003-R, PLSQL-R */ +%token <kwd> BEGIN_ORACLE_SYM /* SQL-2003-R, PLSQL-R */ %token <kwd> BINLOG_SYM %token <kwd> BIT_SYM /* MYSQL-FUNC */ %token <kwd> BLOCK_SYM @@ -1176,11 +1187,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> CIPHER_SYM %token <kwd> CLASS_ORIGIN_SYM /* SQL-2003-N */ %token <kwd> CLIENT_SYM -%token <kwd> CLOB /* SQL-2003-R */ +%token <kwd> CLOB_MARIADB_SYM /* SQL-2003-R */ +%token <kwd> CLOB_ORACLE_SYM /* Oracle-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> COLON_ORACLE_SYM /* INTERNAL */ %token <kwd> COLUMNS %token <kwd> COLUMN_ADD_SYM %token <kwd> COLUMN_CHECK_SYM @@ -1217,7 +1230,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> DECODE_MARIADB_SYM /* Function, non-reserved */ +%token <kwd> DECODE_ORACLE_SYM /* Function, non-reserved */ %token <kwd> DEFINER_SYM %token <kwd> DELAYED_SYM %token <kwd> DELAY_KEY_WRITE_SYM @@ -1247,8 +1261,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> EXCEPTION_MARIADB_SYM /* SQL-2003-N, PLSQL-R */ +%token <kwd> EXIT_MARIADB_SYM /* PLSQL-R */ +%token <kwd> EXIT_ORACLE_SYM /* PLSQL-R */ %token <kwd> EXPANSION_SYM %token <kwd> EXPORT_SYM %token <kwd> EXTENDED_SYM @@ -1265,7 +1280,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> FUNCTION_SYM /* SQL-2003-R, Oracle-R */ %token <kwd> GENERAL %token <kwd> GENERATED_SYM %token <kwd> GEOMETRYCOLLECTION @@ -1378,7 +1393,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> NUMBER_MARIADB_SYM /* SQL-2003-N */ +%token <kwd> NUMBER_ORACLE_SYM /* Oracle-R, PLSQL-R */ %token <kwd> NVARCHAR_SYM %token <kwd> OF_SYM /* SQL-1992-R, Oracle-R */ %token <kwd> OFFSET_SYM @@ -1420,7 +1436,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> QUARTER_SYM %token <kwd> QUERY_SYM %token <kwd> QUICK -%token <kwd> RAW /* Oracle-R */ +%token <kwd> RAW_MARIADB_SYM +%token <kwd> RAW_ORACLE_SYM /* Oracle-R */ %token <kwd> READ_ONLY_SYM %token <kwd> REBUILD_SYM %token <kwd> RECOVER_SYM @@ -1539,7 +1556,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> VARCHAR2_MARIADB_SYM +%token <kwd> VARCHAR2_ORACLE_SYM /* Oracle-R, PLSQL-R */ %token <kwd> VARIABLES %token <kwd> VERSIONING_SYM /* SQL-2011-R */ %token <kwd> VIA_SYM @@ -1607,7 +1625,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); 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: + - PERIOD: identifier, period for system time: SELECT period FROM t1; ALTER TABLE DROP PERIOD FOR SYSTEM TIME; @@ -1619,7 +1637,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); SELECT user FROM t1; KILL USER foo; - Note, we need here only tokens that cause shirt/reduce conflicts + Note, we need here only tokens that cause shift/reduce conflicts with keyword identifiers. For example: opt_clause1: %empty | KEYWORD ... ; clause2: opt_clause1 ident; @@ -1703,6 +1721,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ident label_ident sp_decl_ident + ident_set_usual_case ident_or_empty ident_table_alias ident_sysvar_name @@ -1725,6 +1744,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keyword_data_type keyword_ident keyword_label + keyword_set_special_case + keyword_set_usual_case keyword_sp_block_section keyword_sp_decl keyword_sp_head @@ -1835,7 +1856,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); 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 @@ -1844,6 +1865,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); inverse_distribution_function percentile_function inverse_distribution_function_def + explicit_cursor_attr function_call_keyword function_call_keyword_timestamp function_call_nonkeyword @@ -1852,6 +1874,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); signal_allowed_expr simple_target_specification condition_number + reset_lex_expr %type <item_param> param_marker @@ -1863,6 +1886,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <item_list> expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else ident_list ident_list_arg opt_expr_list + decode_when_list_oracle %type <sp_cursor_stmt> sp_cursor_stmt_lex @@ -1979,7 +2003,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); do drop insert replace insert2 insert_values update delete truncate rename compound_statement show describe load alter optimize keycache preload flush - reset purge begin commit rollback savepoint release + reset purge begin_stmt_mariadb commit rollback savepoint release slave master_def master_defs master_file_def slave_until_opts repair analyze opt_with_admin opt_with_admin_option analyze_table_list analyze_table_elem_spec @@ -2050,8 +2074,11 @@ END_OF_INPUT %type <NONE> sp_proc_stmt_if %type <NONE> sp_labeled_control sp_unlabeled_control %type <NONE> sp_labeled_block sp_unlabeled_block sp_unlabeled_block_not_atomic +%type <NONE> sp_proc_stmt_continue_oracle +%type <NONE> sp_proc_stmt_exit_oracle %type <NONE> sp_proc_stmt_leave %type <NONE> sp_proc_stmt_iterate +%type <NONE> sp_proc_stmt_goto_oracle %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type <NONE> case_stmt_specification %type <NONE> loop_body while_body repeat_body @@ -2059,9 +2086,12 @@ END_OF_INPUT %type <num> view_algorithm view_check_option %type <view_suid> view_suid opt_view_suid +%type <plsql_cursor_attr> plsql_cursor_attr + %type <num> sp_decl_idents sp_decl_idents_init_vars %type <num> sp_handler_type sp_hcond_list %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value +%type <spblock> sp_decl_handler %type <spblock> sp_decls sp_decl sp_decl_body sp_decl_variable_list %type <spname> sp_name %type <spvar> sp_param_name sp_param_name_and_type @@ -2074,7 +2104,7 @@ END_OF_INPUT %type <num> index_hint_clause normal_join inner_join %type <filetype> data_or_xml -%type <NONE> signal_stmt resignal_stmt +%type <NONE> signal_stmt resignal_stmt raise_stmt_oracle %type <diag_condition_item_name> signal_condition_information_item_name %type <trg_execution_order> trigger_follows_precedes_clause; @@ -2188,7 +2218,7 @@ opt_end_of_input: verb_clause: statement - | begin + | begin_stmt_mariadb | compound_statement ; @@ -2228,6 +2258,7 @@ statement: | preload | prepare | purge + | raise_stmt_oracle | release | rename | repair @@ -3500,7 +3531,7 @@ sp_decls: ; sp_decl: - DECLARE_SYM sp_decl_body { $$= $2; } + DECLARE_MARIADB_SYM sp_decl_body { $$= $2; } ; @@ -3616,18 +3647,7 @@ sp_decl_body: $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } - | sp_handler_type HANDLER_SYM FOR_SYM - { - if (unlikely(Lex->sp_handler_declaration_init(thd, $1))) - MYSQL_YYABORT; - } - sp_hcond_list sp_proc_stmt - { - if (unlikely(Lex->sp_handler_declaration_finalize(thd, $1))) - MYSQL_YYABORT; - $$.vars= $$.conds= $$.curs= 0; - $$.hndlrs= 1; - } + | sp_decl_handler | sp_decl_ident CURSOR_SYM { Lex->sp_block_init(thd); @@ -3645,6 +3665,21 @@ sp_decl_body: } ; +sp_decl_handler: + sp_handler_type HANDLER_SYM FOR_SYM + { + if (unlikely(Lex->sp_handler_declaration_init(thd, $1))) + MYSQL_YYABORT; + } + sp_hcond_list sp_proc_stmt + { + if (unlikely(Lex->sp_handler_declaration_finalize(thd, $1))) + MYSQL_YYABORT; + $$.vars= $$.conds= $$.curs= 0; + $$.hndlrs= 1; + } + ; + opt_parenthesized_cursor_formal_parameters: /* Empty */ | '(' sp_fdparams ')' @@ -3677,8 +3712,10 @@ sp_cursor_stmt: ; sp_handler_type: - EXIT_SYM { $$= sp_handler::EXIT; } - | CONTINUE_SYM { $$= sp_handler::CONTINUE; } + EXIT_MARIADB_SYM { $$= sp_handler::EXIT; } + | CONTINUE_MARIADB_SYM { $$= sp_handler::CONTINUE; } + | EXIT_ORACLE_SYM { $$= sp_handler::EXIT; } + | CONTINUE_ORACLE_SYM { $$= sp_handler::CONTINUE; } /*| UNDO_SYM { QQ No yet } */ ; @@ -3748,7 +3785,7 @@ sp_hcond: } | ident /* CONDITION name */ { - $$= Lex->spcont->find_condition(&$1, false); + $$= Lex->spcont->find_declared_or_predefined_condition(thd, &$1); if (unlikely($$ == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); } @@ -3770,6 +3807,26 @@ sp_hcond: if (unlikely($$ == NULL)) MYSQL_YYABORT; } + | OTHERS_ORACLE_SYM /* All other SQLSTATEs */ + { + $$= new (thd->mem_root) sp_condition_value(sp_condition_value::EXCEPTION); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + ; + + +raise_stmt_oracle: + RAISE_ORACLE_SYM opt_set_signal_information + { + if (unlikely(Lex->add_resignal_statement(thd, NULL))) + MYSQL_YYABORT; + } + | RAISE_ORACLE_SYM signal_value opt_set_signal_information + { + if (unlikely(Lex->add_signal_statement(thd, $2))) + MYSQL_YYABORT; + } ; signal_stmt: @@ -3789,7 +3846,7 @@ signal_value: /* SIGNAL foo cannot be used outside of stored programs */ if (unlikely(lex->spcont == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); - cond= lex->spcont->find_condition(&$1, false); + cond= lex->spcont->find_declared_or_predefined_condition(thd, &$1); if (unlikely(cond == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); if (unlikely(cond->type != sp_condition_value::SQLSTATE)) @@ -3978,7 +4035,9 @@ simple_target_specification: ; statement_information_item_name: - NUMBER_SYM + NUMBER_MARIADB_SYM + { $$= Statement_information_item::NUMBER; } + | NUMBER_ORACLE_SYM { $$= Statement_information_item::NUMBER; } | ROW_COUNT_SYM { $$= Statement_information_item::ROW_COUNT; } @@ -4108,8 +4167,11 @@ sp_proc_stmt_in_returns_clause: sp_proc_stmt: sp_proc_stmt_in_returns_clause | sp_proc_stmt_statement + | sp_proc_stmt_continue_oracle + | sp_proc_stmt_exit_oracle | sp_proc_stmt_leave | sp_proc_stmt_iterate + | sp_proc_stmt_goto_oracle | sp_proc_stmt_open | sp_proc_stmt_fetch | sp_proc_stmt_close @@ -4149,8 +4211,14 @@ sp_proc_stmt_statement: } ; + +RETURN_ALLMODES_SYM: + RETURN_MARIADB_SYM + | RETURN_ORACLE_SYM + ; + sp_proc_stmt_return: - RETURN_SYM + RETURN_ALLMODES_SYM { Lex->sphead->reset_lex(thd); } expr { @@ -4161,8 +4229,71 @@ sp_proc_stmt_return: unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } + | RETURN_ORACLE_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + if (unlikely(sp->m_handler->add_instr_preturn(thd, sp, + lex->spcont))) + MYSQL_YYABORT; + } + ; + +reset_lex_expr: + { Lex->sphead->reset_lex(thd); } expr { $$= $2; } ; +sp_proc_stmt_exit_oracle: + EXIT_ORACLE_SYM + { + if (unlikely(Lex->sp_exit_statement(thd, NULL))) + MYSQL_YYABORT; + } + | EXIT_ORACLE_SYM label_ident + { + if (unlikely(Lex->sp_exit_statement(thd, &$2, NULL))) + MYSQL_YYABORT; + } + | EXIT_ORACLE_SYM WHEN_SYM reset_lex_expr + { + if (unlikely(Lex->sp_exit_statement(thd, $3)) || + unlikely(Lex->sphead->restore_lex(thd))) + MYSQL_YYABORT; + } + | EXIT_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr + { + if (unlikely(Lex->sp_exit_statement(thd, &$2, $4)) || + unlikely(Lex->sphead->restore_lex(thd))) + MYSQL_YYABORT; + } + ; + +sp_proc_stmt_continue_oracle: + CONTINUE_ORACLE_SYM + { + if (unlikely(Lex->sp_continue_statement(thd, NULL))) + MYSQL_YYABORT; + } + | CONTINUE_ORACLE_SYM label_ident + { + if (unlikely(Lex->sp_continue_statement(thd, &$2, NULL))) + MYSQL_YYABORT; + } + | CONTINUE_ORACLE_SYM WHEN_SYM reset_lex_expr + { + if (unlikely(Lex->sp_continue_statement(thd, $3)) || + unlikely(Lex->sphead->restore_lex(thd))) + MYSQL_YYABORT; + } + | CONTINUE_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr + { + if (unlikely(Lex->sp_continue_statement(thd, &$2, $4)) || + unlikely(Lex->sphead->restore_lex(thd))) + MYSQL_YYABORT; + } + ; + + sp_proc_stmt_leave: LEAVE_SYM label_ident { @@ -4179,6 +4310,14 @@ sp_proc_stmt_iterate: } ; +sp_proc_stmt_goto_oracle: + GOTO_ORACLE_SYM label_ident + { + if (unlikely(Lex->sp_goto_statement(thd, &$2))) + MYSQL_YYABORT; + } + ; + assignment_source_lex: { DBUG_ASSERT(Lex->sphead); @@ -4374,7 +4513,7 @@ sp_if: sp_elseifs: /* Empty */ - | ELSEIF_SYM sp_if + | ELSEIF_MARIADB_SYM sp_if | ELSE sp_proc_stmts1 ; @@ -4555,7 +4694,7 @@ sp_block_label: sp_labeled_block: sp_block_label - BEGIN_SYM + BEGIN_MARIADB_SYM { Lex->sp_block_init(thd, &$1); } @@ -4570,7 +4709,7 @@ sp_labeled_block: ; sp_unlabeled_block: - BEGIN_SYM + BEGIN_MARIADB_SYM { Lex->sp_block_init(thd); } @@ -4584,7 +4723,7 @@ sp_unlabeled_block: ; sp_unlabeled_block_not_atomic: - BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ + BEGIN_MARIADB_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ { if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; @@ -4617,16 +4756,13 @@ sp_for_loop_bounds: IN_SYM opt_sp_for_loop_direction for_loop_bound_expr DOT_DOT_SYM for_loop_bound_expr { - $$.m_direction= $2; - $$.m_index= $3; - $$.m_upper_bound= $5; - $$.m_implicit_cursor= false; + $$= Lex_for_loop_bounds_intrange($2, $3, $5); } | IN_SYM opt_sp_for_loop_direction for_loop_bound_expr { $$.m_direction= $2; $$.m_index= $3; - $$.m_upper_bound= NULL; + $$.m_target_bound= NULL; $$.m_implicit_cursor= false; } | IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')' @@ -6769,6 +6905,13 @@ field_type_numeric: } | DECIMAL_SYM float_options field_options { $$.set(&type_handler_newdecimal, $2);} + | NUMBER_ORACLE_SYM float_options field_options + { + if ($2.length() != 0) + $$.set(&type_handler_newdecimal, $2); + else + $$.set(&type_handler_double); + } | NUMERIC_SYM float_options field_options { $$.set(&type_handler_newdecimal, $2);} | FIXED_SYM float_options field_options @@ -6795,6 +6938,10 @@ field_type_string: { $$.set(&type_handler_varchar, $2); } + | VARCHAR2_ORACLE_SYM field_length opt_binary + { + $$.set(&type_handler_varchar, $2); + } | nvarchar field_length opt_bin_mod { $$.set(&type_handler_varchar, $2); @@ -6805,6 +6952,11 @@ field_type_string: Lex->charset=&my_charset_bin; $$.set(&type_handler_varchar, $2); } + | RAW_ORACLE_SYM field_length + { + Lex->charset= &my_charset_bin; + $$.set(&type_handler_varchar, $2); + } ; field_type_temporal: @@ -6871,11 +7023,16 @@ field_type_lob: Lex->charset=&my_charset_bin; $$.set(&type_handler_tiny_blob); } - | BLOB_SYM opt_field_length + | BLOB_MARIADB_SYM opt_field_length { Lex->charset=&my_charset_bin; $$.set(&type_handler_blob, $2); } + | BLOB_ORACLE_SYM opt_field_length + { + Lex->charset=&my_charset_bin; + $$.set(&type_handler_long_blob); + } | spatial_type float_options srid_option { #ifdef HAVE_SPATIAL @@ -6912,6 +7069,8 @@ field_type_lob: { $$.set(&type_handler_medium_blob); } | LONGTEXT opt_binary { $$.set(&type_handler_long_blob); } + | CLOB_ORACLE_SYM opt_binary + { $$.set(&type_handler_long_blob); } | LONG_SYM opt_binary { $$.set(&type_handler_medium_blob); } | JSON_SYM @@ -9953,6 +10112,23 @@ dyncall_create_list: } ; + +plsql_cursor_attr: + ISOPEN_SYM { $$= PLSQL_CURSOR_ATTR_ISOPEN; } + | FOUND_SYM { $$= PLSQL_CURSOR_ATTR_FOUND; } + | NOTFOUND_SYM { $$= PLSQL_CURSOR_ATTR_NOTFOUND; } + | ROWCOUNT_SYM { $$= PLSQL_CURSOR_ATTR_ROWCOUNT; } + ; + +explicit_cursor_attr: + ident PERCENT_ORACLE_SYM plsql_cursor_attr + { + if (unlikely(!($$= Lex->make_item_plsql_cursor_attr(thd, &$1, $3)))) + MYSQL_YYABORT; + } + ; + + trim_operands: expr { $$.set(TRIM_BOTH, $1); } | LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); } @@ -10130,6 +10306,7 @@ column_default_non_parenthesized_expr: primary_expr: column_default_non_parenthesized_expr + | explicit_cursor_attr | '(' parenthesized_expr ')' { $$= $2; } ; @@ -10316,6 +10493,14 @@ function_call_keyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } + | SQL_SYM PERCENT_ORACLE_SYM ROWCOUNT_SYM + { + $$= new (thd->mem_root) Item_func_oracle_sql_rowcount(thd); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION); + Lex->safe_to_cache_query= 0; + } | TIME_SYM '(' expr ')' { $$= new (thd->mem_root) Item_time_typecast(thd, $3, @@ -10412,12 +10597,18 @@ function_call_nonkeyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | DECODE_SYM '(' expr ',' expr ')' + | DECODE_MARIADB_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_decode(thd, $3, $5); if (unlikely($$ == NULL)) MYSQL_YYABORT; } + | DECODE_ORACLE_SYM '(' expr ',' decode_when_list_oracle ')' + { + $5->push_front($3, thd->mem_root); + if (unlikely(!($$= new (thd->mem_root) Item_func_decode_oracle(thd, *$5)))) + MYSQL_YYABORT; + } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); @@ -11481,6 +11672,14 @@ cast_type: { Lex->charset= thd->variables.collation_connection; } opt_binary { $$.set(&type_handler_long_blob, $2); } + | VARCHAR field_length + { Lex->charset= thd->variables.collation_connection; } + opt_binary + { $$.set(&type_handler_long_blob, $2); } + | VARCHAR2_ORACLE_SYM field_length + { Lex->charset= thd->variables.collation_connection; } + opt_binary + { $$.set(&type_handler_long_blob, $2); } | NCHAR_SYM opt_field_length { Lex->charset= national_charset_info; @@ -11575,6 +11774,25 @@ when_list_opt_else: } ; +decode_when_list_oracle: + expr ',' expr + { + $$= new (thd->mem_root) List<Item>; + if (unlikely($$ == NULL) || + unlikely($$->push_back($1, thd->mem_root)) || + unlikely($$->push_back($3, thd->mem_root))) + MYSQL_YYABORT; + + } + | decode_when_list_oracle ',' expr + { + $$= $1; + if (unlikely($$->push_back($3, thd->mem_root))) + MYSQL_YYABORT; + } + ; + + /* Equivalent to <table reference> in the SQL:2003 standard. */ /* Warning - may return NULL in case of incomplete SELECT */ table_ref: @@ -12298,7 +12516,9 @@ opt_window_frame_exclusion: { $$= Window_frame::EXCL_GROUP; } | EXCLUDE_SYM TIES_SYM { $$= Window_frame::EXCL_TIES; } - | EXCLUDE_SYM NO_SYM OTHERS_SYM + | EXCLUDE_SYM NO_SYM OTHERS_MARIADB_SYM + { $$= Window_frame::EXCL_NONE; } + | EXCLUDE_SYM NO_SYM OTHERS_ORACLE_SYM { $$= Window_frame::EXCL_NONE; } ; @@ -13879,13 +14099,13 @@ show_param: lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; lex->spname= $3; } - | CREATE PACKAGE_SYM sp_name + | CREATE PACKAGE_MARIADB_SYM sp_name { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE; lex->spname= $3; } - | CREATE PACKAGE_SYM BODY_SYM sp_name + | CREATE PACKAGE_MARIADB_SYM BODY_MARIADB_SYM sp_name { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE_BODY; @@ -13924,14 +14144,14 @@ show_param: if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } - | PACKAGE_SYM STATUS_SYM wild_and_where + | PACKAGE_MARIADB_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE; if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } - | PACKAGE_SYM BODY_SYM STATUS_SYM wild_and_where + | PACKAGE_MARIADB_SYM BODY_MARIADB_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE_BODY; @@ -13948,7 +14168,7 @@ show_param: Lex->sql_command= SQLCOM_SHOW_FUNC_CODE; Lex->spname= $3; } - | PACKAGE_SYM BODY_SYM CODE_SYM sp_name + | PACKAGE_MARIADB_SYM BODY_MARIADB_SYM CODE_SYM sp_name { Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE; Lex->spname= $4; @@ -14712,6 +14932,19 @@ param_marker: YYLIP->get_tok_start() + 1)))) MYSQL_YYABORT; } + | COLON_ORACLE_SYM ident_cli + { + if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str, + $1.pos(), $2.end())))) + MYSQL_YYABORT; + } + | COLON_ORACLE_SYM NUM + { + if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str, + $1.pos(), + YYLIP->get_ptr())))) + MYSQL_YYABORT; + } ; signed_literal: @@ -15021,6 +15254,11 @@ simple_ident: if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } + | COLON_ORACLE_SYM ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4)))) + MYSQL_YYABORT; + } ; simple_ident_nospvar: @@ -15029,20 +15267,17 @@ simple_ident_nospvar: if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1)))) MYSQL_YYABORT; } - | simple_ident_q { $$= $1; } - ; - -simple_ident_q: - ident '.' ident + | ident '.' ident { if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3)))) MYSQL_YYABORT; } - | simple_ident_q2 - ; - -simple_ident_q2: - '.' ident '.' ident + | COLON_ORACLE_SYM ident_cli '.' ident_cli + { + if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4)))) + MYSQL_YYABORT; + } + | '.' ident '.' ident { Lex_ident_sys none; if (unlikely(!($$= Lex->create_item_ident(thd, &none, &$2, &$4)))) @@ -15178,6 +15413,14 @@ ident_table_alias: } ; +ident_set_usual_case: + IDENT_sys + | keyword_set_usual_case + { + if (unlikely($$.copy_keyword(thd, &$1))) + MYSQL_YYABORT; + } + ; ident_sysvar_name: IDENT_sys @@ -15285,6 +15528,7 @@ user: user_maybe_role /* Keywords which we allow as table aliases. */ keyword_table_alias: keyword_data_type + | keyword_set_special_case | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15296,6 +15540,7 @@ keyword_table_alias: /* Keyword that we allow for identifiers (except SP labels) */ keyword_ident: keyword_data_type + | keyword_set_special_case | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15311,12 +15556,14 @@ keyword_ident: */ keyword_label: keyword_data_type + | keyword_set_special_case | keyword_sp_var_and_label | keyword_sysvar_type ; keyword_sysvar_name: keyword_data_type + | keyword_set_special_case | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15327,6 +15574,18 @@ keyword_sysvar_name: keyword_sp_decl: keyword_data_type + | keyword_set_special_case + | 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 + ; + +keyword_set_usual_case: + keyword_data_type | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15372,7 +15631,7 @@ keyword_sp_var_not_label: | INSTALL_SYM | OPTION | OPTIONS_SYM - | OTHERS_SYM + | OTHERS_MARIADB_SYM | OWNER_SYM | PARSER_SYM | PERIOD_SYM @@ -15468,11 +15727,18 @@ keyword_verb_clause: | TRUNCATE_SYM /* Verb clause. Reserved in Oracle */ ; +keyword_set_special_case: + NAMES_SYM + | ROLE_SYM + | PASSWORD_SYM + ; + /* Keywords that start an SP block section. */ keyword_sp_block_section: - BEGIN_SYM + BEGIN_MARIADB_SYM + | EXCEPTION_ORACLE_SYM | END ; @@ -15491,7 +15757,8 @@ keyword_data_type: BIT_SYM | BOOLEAN_SYM | BOOL_SYM - | CLOB + | CLOB_MARIADB_SYM + | CLOB_ORACLE_SYM | DATE_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 | DATETIME | ENUM @@ -15506,17 +15773,20 @@ keyword_data_type: | MULTIPOLYGON | NATIONAL_SYM | NCHAR_SYM - | NUMBER_SYM + | NUMBER_MARIADB_SYM + | NUMBER_ORACLE_SYM | NVARCHAR_SYM | POINT_SYM | POLYGON - | RAW + | RAW_MARIADB_SYM + | RAW_ORACLE_SYM | ROW_SYM | SERIAL_SYM | TEXT_SYM | TIMESTAMP %prec PREC_BELOW_CONTRACTION_TOKEN2 | TIME_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 - | VARCHAR2 + | VARCHAR2_MARIADB_SYM + | VARCHAR2_ORACLE_SYM | YEAR_SYM ; @@ -15543,7 +15813,7 @@ keyword_sp_var_and_label: | AVG_ROW_LENGTH | AVG_SYM | BLOCK_SYM - | BODY_SYM + | BODY_MARIADB_SYM | BTREE_SYM | CASCADED | CATALOG_NAME_SYM @@ -15583,7 +15853,8 @@ keyword_sp_var_and_label: | DATAFILE_SYM | DATE_FORMAT_SYM | DAY_SYM - | DECODE_SYM + | DECODE_MARIADB_SYM + | DECODE_ORACLE_SYM | DEFINER_SYM | DELAY_KEY_WRITE_SYM | DES_KEY_FILE @@ -15595,7 +15866,8 @@ keyword_sp_var_and_label: | DUMPFILE | DUPLICATE_SYM | DYNAMIC_SYM - | ELSIF_SYM + | ELSEIF_ORACLE_SYM + | ELSIF_MARIADB_SYM | ENDS_SYM | ENGINE_SYM | ENGINES_SYM @@ -15605,7 +15877,7 @@ keyword_sp_var_and_label: | EVENT_SYM | EVENTS_SYM | EVERY_SYM - | EXCEPTION_SYM + | EXCEPTION_MARIADB_SYM | EXCHANGE_SYM | EXPANSION_SYM | EXPORT_SYM @@ -15622,7 +15894,7 @@ keyword_sp_var_and_label: | GENERATED_SYM | GET_FORMAT | GRANTS - | GOTO_SYM + | GOTO_MARIADB_SYM | HASH_SYM | HARD_SYM | HISTORY_SYM @@ -15698,7 +15970,6 @@ keyword_sp_var_and_label: | MYSQL_SYM | MYSQL_ERRNO_SYM | NAME_SYM - | NAMES_SYM | NEXT_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 | NEXTVAL_SYM | NEW_SYM @@ -15717,13 +15988,12 @@ keyword_sp_var_and_label: | ONE_SYM | ONLINE_SYM | ONLY_SYM - | PACKAGE_SYM + | PACKAGE_MARIADB_SYM | PACK_KEYS_SYM | PAGE_SYM | PARTIAL | PARTITIONING_SYM | PARTITIONS_SYM - | PASSWORD_SYM | PERSISTENT_SYM | PHASE_SYM | PLUGIN_SYM @@ -15740,7 +16010,7 @@ keyword_sp_var_and_label: | QUARTER_SYM | QUERY_SYM | QUICK - | RAISE_SYM + | RAISE_MARIADB_SYM | READ_ONLY_SYM | REBUILD_SYM | RECOVER_SYM @@ -15763,11 +16033,10 @@ keyword_sp_var_and_label: | RETURNS_SYM | REUSE_SYM | REVERSE_SYM - | ROLE_SYM | ROLLUP_SYM | ROUTINE_SYM | ROWCOUNT_SYM - | ROWTYPE_SYM + | ROWTYPE_MARIADB_SYM | ROW_COUNT_SYM | ROW_FORMAT_SYM | RTREE_SYM @@ -16018,7 +16287,7 @@ option_value_following_option_type: /* Option values without preceding option_type. */ option_value_no_option_type: - ident equal set_expr_or_default + ident_set_usual_case equal set_expr_or_default { if (unlikely(Lex->set_variable(&$1, $3))) MYSQL_YYABORT; @@ -16135,6 +16404,11 @@ option_value_no_option_type: unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; } + | ROLE_SYM equal set_expr_or_default + { + if (unlikely(Lex->set_variable(&$1, $3))) + MYSQL_YYABORT; + } | PASSWORD_SYM opt_for_user text_or_password { LEX *lex = Lex; @@ -16479,6 +16753,20 @@ revoke_command: TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } + | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident + FROM user_and_role_list + { + if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, + TYPE_ENUM_PACKAGE))) + MYSQL_YYABORT; + } + | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident + FROM user_and_role_list + { + 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 { Lex->sql_command = SQLCOM_REVOKE_ALL; @@ -16532,6 +16820,20 @@ grant_command: TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } + | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident TO_SYM grant_list + opt_require_clause opt_grant_options + { + if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, + TYPE_ENUM_PACKAGE))) + MYSQL_YYABORT; + } + | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident TO_SYM grant_list + opt_require_clause opt_grant_options + { + 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 { LEX *lex= Lex; @@ -16951,8 +17253,8 @@ grant_option: | resource_option {} ; -begin: - BEGIN_SYM +begin_stmt_mariadb: + BEGIN_MARIADB_SYM { LEX *lex=Lex; lex->sql_command = SQLCOM_BEGIN; @@ -17442,7 +17744,8 @@ xid: ; begin_or_start: - BEGIN_SYM {} + BEGIN_MARIADB_SYM {} + | BEGIN_ORACLE_SYM {} | START_SYM {} ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 6c28c571dce..c3fd7a78824 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -183,11 +183,6 @@ void ORAerror(THD *thd, const char *s) Lex_for_loop_st for_loop; Lex_for_loop_bounds_st for_loop_bounds; Lex_trim_st trim; - struct - { - LEX_CSTRING name; - uint offset; - } sp_cursor_name_and_offset; vers_history_point_t vers_history_point; struct { @@ -286,6 +281,7 @@ void ORAerror(THD *thd, const char *s) DDL_options_st object_ddl_options; enum vers_sys_type_t vers_range_unit; enum Column_definition::enum_column_versioning vers_column_versioning; + enum plsql_cursor_attr_t plsql_cursor_attr; } %{ @@ -296,10 +292,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 53 shift/reduce conflicts. + Currently there are 49 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 53 +%expect 49 /* Comments for TOKENS. @@ -343,7 +339,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token BIT_AND /* MYSQL-FUNC */ %token BIT_OR /* MYSQL-FUNC */ %token BIT_XOR /* MYSQL-FUNC */ -%token BLOB_SYM /* SQL-2003-R */ +%token BLOB_MARIADB_SYM /* SQL-2003-R */ +%token BLOB_ORACLE_SYM /* Oracle-R */ +%token BODY_ORACLE_SYM /* Oracle-R */ %token BOTH /* SQL-2003-R */ %token BY /* SQL-2003-R */ %token CALL_SYM /* SQL-2003-R */ @@ -356,7 +354,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token COLLATE_SYM /* SQL-2003-R */ %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ %token CONSTRAINT /* SQL-2003-R */ -%token CONTINUE_SYM /* SQL-2003-R */ +%token CONTINUE_MARIADB_SYM /* SQL-2003-R, Oracle-R */ +%token CONTINUE_ORACLE_SYM /* SQL-2003-R, Oracle-R */ %token CONVERT_SYM /* SQL-2003-N */ %token COUNT_SYM /* SQL-2003-N */ %token CREATE /* SQL-2003-R */ @@ -377,7 +376,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DAY_SECOND_SYM %token DECIMAL_NUM %token DECIMAL_SYM /* SQL-2003-R */ -%token DECLARE_SYM /* SQL-2003-R */ +%token DECLARE_MARIADB_SYM /* SQL-2003-R */ +%token DECLARE_ORACLE_SYM /* Oracle-R */ %token DEFAULT /* SQL-2003-R */ %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ @@ -394,7 +394,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DUAL_SYM %token EACH_SYM /* SQL-2003-R */ %token ELSE /* SQL-2003-R */ -%token ELSEIF_SYM +%token ELSEIF_MARIADB_SYM +%token ELSIF_ORACLE_SYM /* PLSQL-R */ %token ENCLOSED %token END_OF_INPUT /* INTERNAL */ %token EQUAL_SYM /* OPERATOR */ @@ -413,6 +414,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token FROM %token FULLTEXT_SYM %token GE +%token GOTO_ORACLE_SYM /* Oracle-R */ %token GRANT /* SQL-2003-R */ %token GROUP_SYM /* SQL-2003-R */ %token GROUP_CONCAT_SYM @@ -501,14 +503,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token OR2_SYM %token ORDER_SYM /* SQL-2003-R */ %token OR_SYM /* SQL-2003-R */ +%token OTHERS_ORACLE_SYM /* SQL-2011-N, PLSQL-R */ %token OUTER %token OUTFILE %token OUT_SYM /* SQL-2003-R */ %token OVER_SYM +%token PACKAGE_ORACLE_SYM /* Oracle-R */ %token PAGE_CHECKSUM_SYM %token PARAM_MARKER %token PARSE_VCOL_EXPR_SYM %token PARTITION_SYM /* SQL-2003-R */ +%token PERCENT_ORACLE_SYM /* INTERNAL */ %token PERCENT_RANK_SYM %token PERCENTILE_CONT_SYM %token PERCENTILE_DISC_SYM @@ -517,6 +522,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token PRIMARY_SYM /* SQL-2003-R */ %token PROCEDURE_SYM /* SQL-2003-R */ %token PURGE +%token RAISE_ORACLE_SYM /* PLSQL-R */ %token RANGE_SYM /* SQL-2003-R */ %token RANK_SYM %token READS_SYM /* SQL-2003-R */ @@ -535,10 +541,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token RESIGNAL_SYM /* SQL-2003-R */ %token RESTRICT %token RETURNING_SYM -%token RETURN_SYM /* SQL-2003-R */ +%token RETURN_MARIADB_SYM /* SQL-2003-R, PLSQL-R */ +%token RETURN_ORACLE_SYM /* SQL-2003-R, PLSQL-R */ %token REVOKE /* SQL-2003-R */ %token RIGHT /* SQL-2003-R */ %token ROWS_SYM /* SQL-2003-R */ +%token ROWTYPE_ORACLE_SYM /* PLSQL-R */ %token ROW_NUMBER_SYM %token SECOND_MICROSECOND_SYM %token SELECT_SYM /* SQL-2003-R */ @@ -623,13 +631,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* Keywords that have different reserved status in std/oracle modes. */ -%token BODY_SYM /* Oracle-R */ -%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 */ +%token <kwd> BODY_MARIADB_SYM // Oracle-R +%token <kwd> ELSEIF_ORACLE_SYM +%token <kwd> ELSIF_MARIADB_SYM // PLSQL-R +%token <kwd> EXCEPTION_ORACLE_SYM // SQL-2003-N, PLSQL-R +%token <kwd> GOTO_MARIADB_SYM // Oracle-R +%token <kwd> OTHERS_MARIADB_SYM // SQL-2011-N, PLSQL-R +%token <kwd> PACKAGE_MARIADB_SYM // Oracle-R +%token <kwd> RAISE_MARIADB_SYM // PLSQL-R +%token <kwd> ROWTYPE_MARIADB_SYM // PLSQL-R /* Non-reserved keywords @@ -654,7 +664,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> BEGIN_MARIADB_SYM /* SQL-2003-R, PLSQL-R */ +%token <kwd> BEGIN_ORACLE_SYM /* SQL-2003-R, PLSQL-R */ %token <kwd> BINLOG_SYM %token <kwd> BIT_SYM /* MYSQL-FUNC */ %token <kwd> BLOCK_SYM @@ -673,11 +684,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> CIPHER_SYM %token <kwd> CLASS_ORIGIN_SYM /* SQL-2003-N */ %token <kwd> CLIENT_SYM -%token <kwd> CLOB /* SQL-2003-R */ +%token <kwd> CLOB_MARIADB_SYM /* SQL-2003-R */ +%token <kwd> CLOB_ORACLE_SYM /* Oracle-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> COLON_ORACLE_SYM /* INTERNAL */ %token <kwd> COLUMNS %token <kwd> COLUMN_ADD_SYM %token <kwd> COLUMN_CHECK_SYM @@ -714,7 +727,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> DECODE_MARIADB_SYM /* Function, non-reserved */ +%token <kwd> DECODE_ORACLE_SYM /* Function, non-reserved */ %token <kwd> DEFINER_SYM %token <kwd> DELAYED_SYM %token <kwd> DELAY_KEY_WRITE_SYM @@ -744,8 +758,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> EXCEPTION_MARIADB_SYM /* SQL-2003-N, PLSQL-R */ +%token <kwd> EXIT_MARIADB_SYM /* PLSQL-R */ +%token <kwd> EXIT_ORACLE_SYM /* PLSQL-R */ %token <kwd> EXPANSION_SYM %token <kwd> EXPORT_SYM %token <kwd> EXTENDED_SYM @@ -762,7 +777,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> FUNCTION_SYM /* SQL-2003-R, Oracle-R */ %token <kwd> GENERAL %token <kwd> GENERATED_SYM %token <kwd> GEOMETRYCOLLECTION @@ -875,7 +890,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> NUMBER_MARIADB_SYM /* SQL-2003-N */ +%token <kwd> NUMBER_ORACLE_SYM /* Oracle-R, PLSQL-R */ %token <kwd> NVARCHAR_SYM %token <kwd> OF_SYM /* SQL-1992-R, Oracle-R */ %token <kwd> OFFSET_SYM @@ -917,7 +933,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> QUARTER_SYM %token <kwd> QUERY_SYM %token <kwd> QUICK -%token <kwd> RAW /* Oracle-R */ +%token <kwd> RAW_MARIADB_SYM +%token <kwd> RAW_ORACLE_SYM /* Oracle-R */ %token <kwd> READ_ONLY_SYM %token <kwd> REBUILD_SYM %token <kwd> RECOVER_SYM @@ -1036,7 +1053,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %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> VARCHAR2_MARIADB_SYM +%token <kwd> VARCHAR2_ORACLE_SYM /* Oracle-R, PLSQL-R */ %token <kwd> VARIABLES %token <kwd> VERSIONING_SYM /* SQL-2011-R */ %token <kwd> VIA_SYM @@ -1085,7 +1103,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %left '&' %left SHIFT_LEFT SHIFT_RIGHT %left '-' '+' ORACLE_CONCAT_SYM -%left '*' '/' DIV_SYM MOD_SYM +%left '*' '/' '%' DIV_SYM MOD_SYM %left '^' %left MYSQL_CONCAT_SYM %left NEG '~' NOT2_SYM BINARY @@ -1104,7 +1122,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); 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: + - PERIOD: identifier, period for system time: SELECT period FROM t1; ALTER TABLE DROP PERIOD FOR SYSTEM TIME; @@ -1116,7 +1134,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); SELECT user FROM t1; KILL USER foo; - Note, we need here only tokens that cause shirt/reduce conflicts + Note, we need here only tokens that cause shift/reduce conflicts with keyword identifiers. For example: opt_clause1: %empty | KEYWORD ... ; clause2: opt_clause1 ident; @@ -1202,6 +1220,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ident label_ident sp_decl_ident + ident_set_usual_case ident_or_empty ident_table_alias ident_sysvar_name @@ -1225,6 +1244,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keyword_data_type keyword_ident keyword_label + keyword_set_special_case + keyword_set_usual_case keyword_sp_block_section keyword_sp_decl keyword_sp_head @@ -1247,7 +1268,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); remember_name remember_end remember_end_opt remember_tok_start remember_tok_end wild_and_where - colon_with_pos %type <const_simple_string> field_length opt_field_length opt_field_length_default_1 @@ -1370,7 +1390,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <item_list> expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else ident_list ident_list_arg opt_expr_list - decode_when_list + decode_when_list_oracle %type <sp_cursor_stmt> sp_cursor_stmt_lex @@ -1489,7 +1509,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); do drop insert replace insert2 insert_values update delete truncate rename compound_statement show describe load alter optimize keycache preload flush - reset purge commit rollback savepoint release + reset purge begin_stmt_mariadb commit rollback savepoint release slave master_def master_defs master_file_def slave_until_opts repair analyze opt_with_admin opt_with_admin_option analyze_table_list analyze_table_elem_spec @@ -1502,8 +1522,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); assign_to_keycache_parts preload_list preload_list_or_parts preload_keys preload_keys_parts select_item_list select_item values_list no_braces - no_braces_with_names opt_values_with_names values_with_names delete_limit_clause fields opt_values values + no_braces_with_names opt_values_with_names values_with_names procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict @@ -1563,17 +1583,19 @@ END_OF_INPUT %type <NONE> sp_labeled_control sp_unlabeled_control %type <NONE> sp_labeled_block sp_unlabeled_block %type <NONE> sp_labelable_stmt -%type <NONE> sp_proc_stmt_continue -%type <NONE> sp_proc_stmt_exit +%type <NONE> sp_proc_stmt_continue_oracle +%type <NONE> sp_proc_stmt_exit_oracle %type <NONE> sp_proc_stmt_leave %type <NONE> sp_proc_stmt_iterate -%type <NONE> sp_proc_stmt_goto +%type <NONE> sp_proc_stmt_goto_oracle %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type <NONE> case_stmt_specification %type <NONE> loop_body while_body repeat_body %type <num> view_algorithm view_check_option %type <view_suid> view_suid opt_view_suid + +%type <plsql_cursor_attr> plsql_cursor_attr %type <sp_suid> sp_suid %type <num> sp_decl_idents sp_decl_idents_init_vars @@ -1591,7 +1613,6 @@ END_OF_INPUT %type <spblock_handlers> sp_block_statements_and_exceptions %type <spblock_handlers> package_implementation_executable_section %type <sp_instr_addr> sp_instr_addr -%type <sp_cursor_name_and_offset> sp_cursor_name_and_offset %type <num> opt_exception_clause exception_handlers %type <lex> remember_lex package_routine_lex package_specification_function @@ -1607,7 +1628,7 @@ END_OF_INPUT %type <num> index_hint_clause normal_join inner_join %type <filetype> data_or_xml -%type <NONE> signal_stmt resignal_stmt raise_stmt +%type <NONE> signal_stmt resignal_stmt raise_stmt_oracle %type <diag_condition_item_name> signal_condition_information_item_name %type <trg_execution_order> trigger_follows_precedes_clause; @@ -1721,6 +1742,7 @@ opt_end_of_input: verb_clause: statement + | begin_stmt_mariadb | compound_statement ; @@ -1760,7 +1782,7 @@ statement: | preload | prepare | purge - | raise_stmt + | raise_stmt_oracle | release | rename | repair @@ -2414,7 +2436,7 @@ create: | create_or_replace { Lex->set_command(SQLCOM_CREATE_SERVER, $1); } server_def { } - | create_or_replace definer_opt PACKAGE_SYM + | create_or_replace definer_opt PACKAGE_ORACLE_SYM opt_if_not_exists sp_name opt_create_package_chistics_init sp_tail_is remember_name @@ -2434,7 +2456,7 @@ create: if (unlikely(Lex->create_package_finalize(thd, $5, $13, $8, $12))) MYSQL_YYABORT; } - | create_or_replace definer_opt PACKAGE_SYM BODY_SYM + | create_or_replace definer_opt PACKAGE_ORACLE_SYM BODY_ORACLE_SYM opt_if_not_exists sp_name opt_create_package_chistics_init sp_tail_is remember_name @@ -2474,11 +2496,11 @@ package_implementation_executable_section: MYSQL_YYABORT; $$.init(0); } - | BEGIN_SYM sp_block_statements_and_exceptions END { $$= $2; } + | BEGIN_ORACLE_SYM sp_block_statements_and_exceptions END { $$= $2; } ; /* - Inside CREATE PACKATE BODY, package-wide items (e.g. variables) + Inside CREATE PACKAGE BODY, package-wide items (e.g. variables) must be declared before routine definitions. */ package_implementation_declare_section: @@ -3153,22 +3175,22 @@ sp_param_name_and_type: if (unlikely(Lex->sp_param_fill_definition($$= $1))) MYSQL_YYABORT; } - | sp_param_name sp_decl_ident '.' ident '%' TYPE_SYM + | sp_param_name sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM { if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4))) MYSQL_YYABORT; } - | sp_param_name sp_decl_ident '.' ident '.' ident '%' TYPE_SYM + | sp_param_name sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM { if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6))) MYSQL_YYABORT; } - | sp_param_name sp_decl_ident '%' ROWTYPE_SYM + | sp_param_name sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM { if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2))) MYSQL_YYABORT; } - | sp_param_name sp_decl_ident '.' ident '%' ROWTYPE_SYM + | sp_param_name sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM { if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2, $4))) MYSQL_YYABORT; @@ -3198,25 +3220,25 @@ sp_pdparam: if (unlikely(Lex->sp_param_fill_definition($1))) MYSQL_YYABORT; } - | sp_param_name sp_opt_inout sp_decl_ident '.' ident '%' TYPE_SYM + | sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM { $1->mode= $2; 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 + | sp_param_name sp_opt_inout sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM { $1->mode= $2; 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 + | sp_param_name sp_opt_inout sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM { $1->mode= $2; 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 + | sp_param_name sp_opt_inout sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM { $1->mode= $2; if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $1, $3, $5))) @@ -3421,7 +3443,7 @@ sp_decl_vars: $$.init_using_vars($1); } | sp_decl_idents_init_vars - optionally_qualified_column_ident '%' TYPE_SYM + optionally_qualified_column_ident PERCENT_ORACLE_SYM TYPE_SYM sp_opt_default { if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $2, $5))) @@ -3429,7 +3451,7 @@ sp_decl_vars: $$.init_using_vars($1); } | sp_decl_idents_init_vars - optionally_qualified_column_ident '%' ROWTYPE_SYM + optionally_qualified_column_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM sp_opt_default { if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $2, $5))) @@ -3455,7 +3477,7 @@ sp_decl_non_handler: $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; } - | ident_directly_assignable EXCEPTION_SYM + | ident_directly_assignable EXCEPTION_ORACLE_SYM { sp_condition_value *spcond= new (thd->mem_root) sp_condition_value_user_defined(); @@ -3529,8 +3551,10 @@ sp_cursor_stmt: ; sp_handler_type: - EXIT_SYM { $$= sp_handler::EXIT; } - | CONTINUE_SYM { $$= sp_handler::CONTINUE; } + EXIT_MARIADB_SYM { $$= sp_handler::EXIT; } + | CONTINUE_MARIADB_SYM { $$= sp_handler::CONTINUE; } + | EXIT_ORACLE_SYM { $$= sp_handler::EXIT; } + | CONTINUE_ORACLE_SYM { $$= sp_handler::CONTINUE; } /*| UNDO_SYM { QQ No yet } */ ; @@ -3600,7 +3624,7 @@ sp_hcond: } | ident /* CONDITION name */ { - $$= Lex->spcont->find_declared_or_predefined_condition(&$1); + $$= Lex->spcont->find_declared_or_predefined_condition(thd, &$1); if (unlikely($$ == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); } @@ -3616,7 +3640,13 @@ sp_hcond: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | OTHERS_SYM /* All other SQLSTATEs */ + | SQLEXCEPTION_SYM /* All other SQLSTATEs */ + { + $$= new (thd->mem_root) sp_condition_value(sp_condition_value::EXCEPTION); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | OTHERS_ORACLE_SYM /* All other SQLSTATEs */ { $$= new (thd->mem_root) sp_condition_value(sp_condition_value::EXCEPTION); if (unlikely($$ == NULL)) @@ -3625,13 +3655,13 @@ sp_hcond: ; -raise_stmt: - RAISE_SYM opt_set_signal_information +raise_stmt_oracle: + RAISE_ORACLE_SYM opt_set_signal_information { if (unlikely(Lex->add_resignal_statement(thd, NULL))) MYSQL_YYABORT; } - | RAISE_SYM signal_value opt_set_signal_information + | RAISE_ORACLE_SYM signal_value opt_set_signal_information { if (unlikely(Lex->add_signal_statement(thd, $2))) MYSQL_YYABORT; @@ -3655,7 +3685,7 @@ signal_value: /* SIGNAL foo cannot be used outside of stored programs */ 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); + cond= lex->spcont->find_declared_or_predefined_condition(thd, &$1); if (unlikely(cond == NULL)) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); if (unlikely(!cond->has_sql_state())) @@ -3844,7 +3874,9 @@ simple_target_specification: ; statement_information_item_name: - NUMBER_SYM + NUMBER_MARIADB_SYM + { $$= Statement_information_item::NUMBER; } + | NUMBER_ORACLE_SYM { $$= Statement_information_item::NUMBER; } | ROW_COUNT_SYM { $$= Statement_information_item::ROW_COUNT; } @@ -3966,11 +3998,11 @@ sp_proc_stmt: sp_labelable_stmt: sp_proc_stmt_statement - | sp_proc_stmt_continue - | sp_proc_stmt_exit + | sp_proc_stmt_continue_oracle + | sp_proc_stmt_exit_oracle | sp_proc_stmt_leave | sp_proc_stmt_iterate - | sp_proc_stmt_goto + | sp_proc_stmt_goto_oracle | sp_proc_stmt_open | sp_proc_stmt_fetch | sp_proc_stmt_close @@ -4031,8 +4063,14 @@ sp_proc_stmt_statement: } ; + +RETURN_ALLMODES_SYM: + RETURN_MARIADB_SYM + | RETURN_ORACLE_SYM + ; + sp_proc_stmt_return: - RETURN_SYM + RETURN_ALLMODES_SYM { Lex->sphead->reset_lex(thd); } expr { @@ -4043,7 +4081,7 @@ sp_proc_stmt_return: unlikely(sp->restore_lex(thd))) MYSQL_YYABORT; } - | RETURN_SYM + | RETURN_ORACLE_SYM { LEX *lex= Lex; sp_head *sp= lex->sphead; @@ -4059,24 +4097,24 @@ reset_lex_expr: { $$= $2; } ; -sp_proc_stmt_exit: - EXIT_SYM +sp_proc_stmt_exit_oracle: + EXIT_ORACLE_SYM { if (unlikely(Lex->sp_exit_statement(thd, NULL))) MYSQL_YYABORT; } - | EXIT_SYM label_ident + | EXIT_ORACLE_SYM label_ident { if (unlikely(Lex->sp_exit_statement(thd, &$2, NULL))) MYSQL_YYABORT; } - | EXIT_SYM WHEN_SYM reset_lex_expr + | EXIT_ORACLE_SYM WHEN_SYM reset_lex_expr { if (Lex->sp_exit_statement(thd, $3) || Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } - | EXIT_SYM label_ident WHEN_SYM reset_lex_expr + | EXIT_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr { if (Lex->sp_exit_statement(thd, &$2, $4) || Lex->sphead->restore_lex(thd)) @@ -4084,24 +4122,24 @@ sp_proc_stmt_exit: } ; -sp_proc_stmt_continue: - CONTINUE_SYM +sp_proc_stmt_continue_oracle: + CONTINUE_ORACLE_SYM { if (unlikely(Lex->sp_continue_statement(thd, NULL))) MYSQL_YYABORT; } - | CONTINUE_SYM label_ident + | CONTINUE_ORACLE_SYM label_ident { if (unlikely(Lex->sp_continue_statement(thd, &$2, NULL))) MYSQL_YYABORT; } - | CONTINUE_SYM WHEN_SYM reset_lex_expr + | CONTINUE_ORACLE_SYM WHEN_SYM reset_lex_expr { if (Lex->sp_continue_statement(thd, $3) || Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } - | CONTINUE_SYM label_ident WHEN_SYM reset_lex_expr + | CONTINUE_ORACLE_SYM label_ident WHEN_SYM reset_lex_expr { if (Lex->sp_continue_statement(thd, &$2, $4) || Lex->sphead->restore_lex(thd)) @@ -4126,8 +4164,8 @@ sp_proc_stmt_iterate: } ; -sp_proc_stmt_goto: - GOTO_SYM label_ident +sp_proc_stmt_goto_oracle: + GOTO_ORACLE_SYM label_ident { if (unlikely(Lex->sp_goto_statement(thd, &$2))) MYSQL_YYABORT; @@ -4324,7 +4362,7 @@ sp_if: sp_elseifs: /* Empty */ - | ELSIF_SYM sp_if + | ELSIF_ORACLE_SYM sp_if | ELSE sp_proc_stmts1_implicit_block ; @@ -4501,7 +4539,7 @@ sp_block_label: sp_labeled_block: sp_block_label - BEGIN_SYM + BEGIN_ORACLE_SYM { Lex->sp_block_init(thd, &$1); if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) @@ -4515,7 +4553,7 @@ sp_labeled_block: MYSQL_YYABORT; } | sp_block_label - DECLARE_SYM + DECLARE_ORACLE_SYM { Lex->sp_block_init(thd, &$1); } @@ -4524,7 +4562,7 @@ sp_labeled_block: if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } - BEGIN_SYM + BEGIN_ORACLE_SYM sp_block_statements_and_exceptions END sp_opt_label @@ -4541,7 +4579,7 @@ opt_not_atomic: ; sp_unlabeled_block: - BEGIN_SYM opt_not_atomic + BEGIN_ORACLE_SYM opt_not_atomic { if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; @@ -4555,7 +4593,7 @@ sp_unlabeled_block: if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4)))) MYSQL_YYABORT; } - | DECLARE_SYM + | DECLARE_ORACLE_SYM { if (unlikely(Lex->maybe_start_compound_statement(thd))) MYSQL_YYABORT; @@ -4566,7 +4604,7 @@ sp_unlabeled_block: if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } - BEGIN_SYM + BEGIN_ORACLE_SYM sp_block_statements_and_exceptions END { @@ -4589,7 +4627,7 @@ sp_body: if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd))) MYSQL_YYABORT; } - BEGIN_SYM + BEGIN_ORACLE_SYM sp_block_statements_and_exceptions { $2.hndlrs+= $5.hndlrs; @@ -4615,8 +4653,8 @@ sp_block_statements_and_exceptions: ; opt_exception_clause: - /* Empty */ { $$= 0; } - | EXCEPTION_SYM exception_handlers { $$= $2; } + /* Empty */ { $$= 0; } + | EXCEPTION_ORACLE_SYM exception_handlers { $$= $2; } ; exception_handlers: @@ -4657,16 +4695,13 @@ sp_for_loop_bounds: IN_SYM opt_sp_for_loop_direction for_loop_bound_expr DOT_DOT_SYM for_loop_bound_expr { - $$.m_direction= $2; - $$.m_index= $3; - $$.m_upper_bound= $5; - $$.m_implicit_cursor= false; + $$= Lex_for_loop_bounds_intrange($2, $3, $5); } | IN_SYM opt_sp_for_loop_direction for_loop_bound_expr { $$.m_direction= $2; $$.m_index= $3; - $$.m_upper_bound= NULL; + $$.m_target_bound= NULL; $$.m_implicit_cursor= false; } | IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')' @@ -6820,7 +6855,7 @@ field_type_numeric: } | DECIMAL_SYM float_options field_options { $$.set(&type_handler_newdecimal, $2);} - | NUMBER_SYM float_options field_options + | NUMBER_ORACLE_SYM float_options field_options { if ($2.length() != 0) $$.set(&type_handler_newdecimal, $2); @@ -6853,7 +6888,7 @@ field_type_string: { $$.set(&type_handler_varchar, $2); } - | VARCHAR2 field_length opt_binary + | VARCHAR2_ORACLE_SYM field_length opt_binary { $$.set(&type_handler_varchar, $2); } @@ -6867,7 +6902,7 @@ field_type_string: Lex->charset=&my_charset_bin; $$.set(&type_handler_varchar, $2); } - | RAW field_length + | RAW_ORACLE_SYM field_length { Lex->charset= &my_charset_bin; $$.set(&type_handler_varchar, $2); @@ -6894,7 +6929,7 @@ sp_param_field_type_string: { $$.set(&type_handler_varchar, $2); } - | VARCHAR2 opt_field_length_default_sp_param_varchar opt_binary + | VARCHAR2_ORACLE_SYM opt_field_length_default_sp_param_varchar opt_binary { $$.set(&type_handler_varchar, $2); } @@ -6908,7 +6943,7 @@ sp_param_field_type_string: Lex->charset= &my_charset_bin; $$.set(&type_handler_varchar, $2); } - | RAW opt_field_length_default_sp_param_varchar + | RAW_ORACLE_SYM opt_field_length_default_sp_param_varchar { Lex->charset= &my_charset_bin; $$.set(&type_handler_varchar, $2); @@ -6980,7 +7015,12 @@ field_type_lob: Lex->charset=&my_charset_bin; $$.set(&type_handler_tiny_blob); } - | BLOB_SYM opt_field_length + | BLOB_MARIADB_SYM opt_field_length + { + Lex->charset=&my_charset_bin; + $$.set(&type_handler_blob, $2); + } + | BLOB_ORACLE_SYM opt_field_length { Lex->charset=&my_charset_bin; $$.set(&type_handler_long_blob); @@ -7021,7 +7061,7 @@ field_type_lob: { $$.set(&type_handler_medium_blob); } | LONGTEXT opt_binary { $$.set(&type_handler_long_blob); } - | CLOB opt_binary + | CLOB_ORACLE_SYM opt_binary { $$.set(&type_handler_long_blob); } | LONG_SYM opt_binary { $$.set(&type_handler_medium_blob); } @@ -9534,13 +9574,6 @@ select_item: } ; -colon_with_pos: - ':' - { - $$= (char *) YYLIP->get_tok_start(); - } - ; - remember_tok_start: { $$= (char*) YYLIP->get_tok_start(); @@ -9970,6 +10003,12 @@ bit_expr: if (unlikely($$ == NULL)) MYSQL_YYABORT; } + | bit_expr '%' bit_expr %prec '%' + { + $$= new (thd->mem_root) Item_func_mod(thd, $1, $3); + 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); @@ -10107,44 +10146,23 @@ dyncall_create_list: } ; -sp_cursor_name_and_offset: - ident - { - LEX *lex= Lex; - $$.name= $1; - if (unlikely(!lex->spcont || - !lex->spcont->find_cursor(&$1, &$$.offset, false))) - my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $1.str)); - } + +plsql_cursor_attr: + ISOPEN_SYM { $$= PLSQL_CURSOR_ATTR_ISOPEN; } + | FOUND_SYM { $$= PLSQL_CURSOR_ATTR_FOUND; } + | NOTFOUND_SYM { $$= PLSQL_CURSOR_ATTR_NOTFOUND; } + | ROWCOUNT_SYM { $$= PLSQL_CURSOR_ATTR_ROWCOUNT; } ; explicit_cursor_attr: - sp_cursor_name_and_offset '%' ISOPEN_SYM + ident PERCENT_ORACLE_SYM plsql_cursor_attr { - 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 (unlikely(!($$= new (thd->mem_root) - Item_func_cursor_found(thd, &$1.name, $1.offset)))) - MYSQL_YYABORT; - } - | sp_cursor_name_and_offset '%' NOTFOUND_SYM - { - 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 (unlikely(!($$= new (thd->mem_root) - Item_func_cursor_rowcount(thd, &$1.name, $1.offset)))) + if (unlikely(!($$= Lex->make_item_plsql_cursor_attr(thd, &$1, $3)))) MYSQL_YYABORT; } ; + trim_operands: expr { $$.set(TRIM_BOTH, $1); } | LEADING expr FROM expr { $$.set(TRIM_LEADING, $2, $4); } @@ -10265,24 +10283,6 @@ column_default_non_parenthesized_expr: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | DATE_FORMAT_SYM '(' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' - { - $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); - if (unlikely($$ == NULL)) - MYSQL_YYABORT; - } - | DECODE_SYM '(' expr ',' decode_when_list ')' - { - $5->push_front($3, thd->mem_root); - if (unlikely(!($$= new (thd->mem_root) Item_func_decode_oracle(thd, *$5)))) - MYSQL_YYABORT; - } | DEFAULT '(' simple_ident ')' { Item_splocal *il= $3->get_item_splocal(); @@ -10527,7 +10527,7 @@ function_call_keyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | SQL_SYM '%' ROWCOUNT_SYM + | SQL_SYM PERCENT_ORACLE_SYM ROWCOUNT_SYM { $$= new (thd->mem_root) Item_func_oracle_sql_rowcount(thd); if (unlikely($$ == NULL)) @@ -10619,6 +10619,30 @@ function_call_nonkeyword: if (unlikely($$ == NULL)) MYSQL_YYABORT; } + | DATE_FORMAT_SYM '(' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | DECODE_MARIADB_SYM '(' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_decode(thd, $3, $5); + if (unlikely($$ == NULL)) + MYSQL_YYABORT; + } + | DECODE_ORACLE_SYM '(' expr ',' decode_when_list_oracle ')' + { + $5->push_front($3, thd->mem_root); + if (unlikely(!($$= new (thd->mem_root) Item_func_decode_oracle(thd, *$5)))) + MYSQL_YYABORT; + } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); @@ -11686,7 +11710,7 @@ cast_type: { Lex->charset= thd->variables.collation_connection; } opt_binary { $$.set(&type_handler_long_blob, $2); } - | VARCHAR2 field_length + | VARCHAR2_ORACLE_SYM field_length { Lex->charset= thd->variables.collation_connection; } opt_binary { $$.set(&type_handler_long_blob, $2); } @@ -11784,7 +11808,7 @@ when_list_opt_else: } ; -decode_when_list: +decode_when_list_oracle: expr ',' expr { $$= new (thd->mem_root) List<Item>; @@ -11794,7 +11818,7 @@ decode_when_list: MYSQL_YYABORT; } - | decode_when_list ',' expr + | decode_when_list_oracle ',' expr { $$= $1; if (unlikely($$->push_back($3, thd->mem_root))) @@ -12525,7 +12549,9 @@ opt_window_frame_exclusion: { $$= Window_frame::EXCL_GROUP; } | EXCLUDE_SYM TIES_SYM { $$= Window_frame::EXCL_TIES; } - | EXCLUDE_SYM NO_SYM OTHERS_SYM + | EXCLUDE_SYM NO_SYM OTHERS_MARIADB_SYM + { $$= Window_frame::EXCL_NONE; } + | EXCLUDE_SYM NO_SYM OTHERS_ORACLE_SYM { $$= Window_frame::EXCL_NONE; } ; @@ -13057,7 +13083,7 @@ drop: lex->set_command(SQLCOM_DROP_DB, $3); lex->name= $4; } - | DROP PACKAGE_SYM opt_if_exists sp_name + | DROP PACKAGE_ORACLE_SYM opt_if_exists sp_name { LEX *lex= Lex; lex->set_command(SQLCOM_DROP_PACKAGE, $3); @@ -13065,7 +13091,7 @@ drop: my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PACKAGE")); lex->spname= $4; } - | DROP PACKAGE_SYM BODY_SYM opt_if_exists sp_name + | DROP PACKAGE_ORACLE_SYM BODY_ORACLE_SYM opt_if_exists sp_name { LEX *lex= Lex; lex->set_command(SQLCOM_DROP_PACKAGE_BODY, $4); @@ -14128,13 +14154,13 @@ show_param: lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; lex->spname= $3; } - | CREATE PACKAGE_SYM sp_name + | CREATE PACKAGE_ORACLE_SYM sp_name { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE; lex->spname= $3; } - | CREATE PACKAGE_SYM BODY_SYM sp_name + | CREATE PACKAGE_ORACLE_SYM BODY_ORACLE_SYM sp_name { LEX *lex= Lex; lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE_BODY; @@ -14173,14 +14199,14 @@ show_param: if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } - | PACKAGE_SYM STATUS_SYM wild_and_where + | PACKAGE_ORACLE_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE; if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES))) MYSQL_YYABORT; } - | PACKAGE_SYM BODY_SYM STATUS_SYM wild_and_where + | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE_BODY; @@ -14197,7 +14223,7 @@ show_param: Lex->sql_command= SQLCOM_SHOW_FUNC_CODE; Lex->spname= $3; } - | PACKAGE_SYM BODY_SYM CODE_SYM sp_name + | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM CODE_SYM sp_name { Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE; Lex->spname= $4; @@ -14958,16 +14984,17 @@ param_marker: YYLIP->get_tok_start() + 1)))) MYSQL_YYABORT; } - | colon_with_pos ident_cli + | COLON_ORACLE_SYM ident_cli { if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str, - $1, $2.end())))) + $1.pos(), $2.end())))) MYSQL_YYABORT; } - | colon_with_pos NUM + | COLON_ORACLE_SYM NUM { if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str, - $1, YYLIP->get_ptr())))) + $1.pos(), + YYLIP->get_ptr())))) MYSQL_YYABORT; } ; @@ -15279,7 +15306,7 @@ simple_ident: if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5)))) MYSQL_YYABORT; } - | colon_with_pos ident_cli '.' ident_cli + | COLON_ORACLE_SYM ident_cli '.' ident_cli { if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4)))) MYSQL_YYABORT; @@ -15297,7 +15324,7 @@ simple_ident_nospvar: if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3)))) MYSQL_YYABORT; } - | colon_with_pos ident_cli '.' ident_cli + | COLON_ORACLE_SYM ident_cli '.' ident_cli { if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4)))) MYSQL_YYABORT; @@ -15438,6 +15465,14 @@ ident_table_alias: } ; +ident_set_usual_case: + IDENT_sys + | keyword_set_usual_case + { + if (unlikely($$.copy_keyword(thd, &$1))) + MYSQL_YYABORT; + } + ; ident_sysvar_name: IDENT_sys @@ -15569,6 +15604,7 @@ user: user_maybe_role /* Keywords which we allow as table aliases. */ keyword_table_alias: keyword_data_type + | keyword_set_special_case | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15581,6 +15617,7 @@ keyword_table_alias: /* Keyword that we allow for identifiers (except SP labels) */ keyword_ident: keyword_data_type + | keyword_set_special_case | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15597,6 +15634,7 @@ keyword_ident: */ keyword_label: keyword_data_type + | keyword_set_special_case | keyword_sp_var_and_label | keyword_sysvar_type | FUNCTION_SYM @@ -15604,6 +15642,7 @@ keyword_label: keyword_sysvar_name: keyword_data_type + | keyword_set_special_case | keyword_sp_block_section | keyword_sp_head | keyword_sp_var_and_label @@ -15615,15 +15654,29 @@ keyword_sysvar_name: keyword_sp_decl: keyword_sp_head + | keyword_set_special_case + | keyword_sp_var_and_label + | keyword_sp_var_not_label + | keyword_sysvar_type + | keyword_verb_clause + | WINDOW_SYM + ; + +keyword_set_usual_case: + 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 ; keyword_directly_assignable: keyword_data_type + | keyword_set_special_case | keyword_sp_var_and_label | keyword_sp_var_not_label | keyword_sysvar_type @@ -15663,11 +15716,11 @@ keyword_sp_var_not_label: | FORMAT_SYM | GET_SYM | HELP_SYM - | HISTORY_SYM | HOST_SYM | INSTALL_SYM | OPTION | OPTIONS_SYM + | OTHERS_MARIADB_SYM | OWNER_SYM | PARSER_SYM | PERIOD_SYM @@ -15687,15 +15740,11 @@ keyword_sp_var_not_label: | 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 @@ -15767,12 +15816,18 @@ keyword_verb_clause: | TRUNCATE_SYM /* Verb clause. Reserved in Oracle */ ; +keyword_set_special_case: + NAMES_SYM + | ROLE_SYM + | PASSWORD_SYM + ; + /* Keywords that start an SP block section. */ keyword_sp_block_section: - BEGIN_SYM - | EXCEPTION_SYM + BEGIN_ORACLE_SYM + | EXCEPTION_ORACLE_SYM | END ; @@ -15791,7 +15846,8 @@ keyword_data_type: BIT_SYM | BOOLEAN_SYM | BOOL_SYM - | CLOB + | CLOB_MARIADB_SYM + | CLOB_ORACLE_SYM | DATE_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 | DATETIME | ENUM @@ -15806,17 +15862,20 @@ keyword_data_type: | MULTIPOLYGON | NATIONAL_SYM | NCHAR_SYM - | NUMBER_SYM + | NUMBER_MARIADB_SYM + | NUMBER_ORACLE_SYM | NVARCHAR_SYM | POINT_SYM | POLYGON - | RAW + | RAW_MARIADB_SYM + | RAW_ORACLE_SYM | ROW_SYM | SERIAL_SYM | TEXT_SYM | TIMESTAMP %prec PREC_BELOW_CONTRACTION_TOKEN2 | TIME_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 - | VARCHAR2 + | VARCHAR2_MARIADB_SYM + | VARCHAR2_ORACLE_SYM | YEAR_SYM ; @@ -15843,6 +15902,7 @@ keyword_sp_var_and_label: | AVG_ROW_LENGTH | AVG_SYM | BLOCK_SYM + | BODY_MARIADB_SYM | BTREE_SYM | CASCADED | CATALOG_NAME_SYM @@ -15882,7 +15942,8 @@ keyword_sp_var_and_label: | DATAFILE_SYM | DATE_FORMAT_SYM | DAY_SYM - | DECODE_SYM + | DECODE_MARIADB_SYM + | DECODE_ORACLE_SYM | DEFINER_SYM | DELAY_KEY_WRITE_SYM | DES_KEY_FILE @@ -15894,6 +15955,8 @@ keyword_sp_var_and_label: | DUMPFILE | DUPLICATE_SYM | DYNAMIC_SYM + | ELSEIF_ORACLE_SYM + | ELSIF_MARIADB_SYM | ENDS_SYM | ENGINE_SYM | ENGINES_SYM @@ -15903,7 +15966,7 @@ keyword_sp_var_and_label: | EVENT_SYM | EVENTS_SYM | EVERY_SYM - + | EXCEPTION_MARIADB_SYM | EXCHANGE_SYM | EXPANSION_SYM | EXPORT_SYM @@ -15920,8 +15983,10 @@ keyword_sp_var_and_label: | GENERATED_SYM | GET_FORMAT | GRANTS + | GOTO_MARIADB_SYM | HASH_SYM | HARD_SYM + | HISTORY_SYM | HOSTS_SYM | HOUR_SYM | ID_SYM @@ -15994,7 +16059,6 @@ keyword_sp_var_and_label: | MYSQL_SYM | MYSQL_ERRNO_SYM | NAME_SYM - | NAMES_SYM | NEXT_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 | NEXTVAL_SYM | NEW_SYM @@ -16013,13 +16077,12 @@ keyword_sp_var_and_label: | ONE_SYM | ONLINE_SYM | ONLY_SYM - + | PACKAGE_MARIADB_SYM | PACK_KEYS_SYM | PAGE_SYM | PARTIAL | PARTITIONING_SYM | PARTITIONS_SYM - | PASSWORD_SYM | PERSISTENT_SYM | PHASE_SYM | PLUGIN_SYM @@ -16036,7 +16099,7 @@ keyword_sp_var_and_label: | QUARTER_SYM | QUERY_SYM | QUICK - + | RAISE_MARIADB_SYM | READ_ONLY_SYM | REBUILD_SYM | RECOVER_SYM @@ -16059,10 +16122,10 @@ keyword_sp_var_and_label: | RETURNS_SYM | REUSE_SYM | REVERSE_SYM - | ROLE_SYM | ROLLUP_SYM | ROUTINE_SYM | ROWCOUNT_SYM + | ROWTYPE_MARIADB_SYM | ROW_COUNT_SYM | ROW_FORMAT_SYM | RTREE_SYM @@ -16098,6 +16161,8 @@ keyword_sp_var_and_label: | SUSPEND_SYM | SWAPS_SYM | SWITCHES_SYM + | SYSTEM + | SYSTEM_TIME_SYM | TABLE_NAME_SYM | TABLES | TABLE_CHECKSUM_SYM @@ -16123,6 +16188,7 @@ keyword_sp_var_and_label: | USER_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2 | USE_FRM | VARIABLES + | VERSIONING_SYM | VIEW_SYM | VIRTUAL_SYM | VALUE_SYM @@ -16130,6 +16196,7 @@ keyword_sp_var_and_label: | WAIT_SYM | WEEK_SYM | WEIGHT_STRING_SYM + | WITHOUT | WORK_SYM | X509_SYM | XML_SYM @@ -16209,12 +16276,12 @@ set_assign: unlikely(lex->sphead->restore_lex(thd))) MYSQL_YYABORT; } - | colon_with_pos ident '.' ident SET_VAR + | COLON_ORACLE_SYM ident '.' ident SET_VAR { LEX *lex= Lex; if (unlikely(!lex->is_trigger_new_or_old_reference(&$2))) { - thd->parse_error(ER_SYNTAX_ERROR, $1); + thd->parse_error(ER_SYNTAX_ERROR, $1.pos()); MYSQL_YYABORT; } lex->set_stmt_init(); @@ -16358,7 +16425,7 @@ option_value_following_option_type: /* Option values without preceding option_type. */ option_value_no_option_type: - ident equal set_expr_or_default + ident_set_usual_case equal set_expr_or_default { if (unlikely(Lex->set_variable(&$1, $3))) MYSQL_YYABORT; @@ -16475,6 +16542,11 @@ option_value_no_option_type: unlikely(lex->var_list.push_back(var, thd->mem_root))) MYSQL_YYABORT; } + | ROLE_SYM equal set_expr_or_default + { + if (unlikely(Lex->set_variable(&$1, $3))) + MYSQL_YYABORT; + } | PASSWORD_SYM opt_for_user text_or_password { LEX *lex = Lex; @@ -16819,13 +16891,15 @@ revoke_command: TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } - | grant_privileges ON PACKAGE_SYM grant_ident FROM user_and_role_list + | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident + FROM user_and_role_list { 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 + | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident + FROM user_and_role_list { if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE, TYPE_ENUM_PACKAGE_BODY))) @@ -16884,14 +16958,14 @@ grant_command: TYPE_ENUM_PROCEDURE))) MYSQL_YYABORT; } - | grant_privileges ON PACKAGE_SYM grant_ident TO_SYM grant_list + | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { 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 + | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident TO_SYM grant_list opt_require_clause opt_grant_options { if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT, @@ -17317,6 +17391,16 @@ grant_option: | resource_option {} ; +begin_stmt_mariadb: + BEGIN_MARIADB_SYM + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_BEGIN; + lex->start_transaction_opt= 0; + } + opt_work {} + ; + compound_statement: sp_proc_stmt_compound_ok { @@ -17667,7 +17751,7 @@ udf_tail: sf_return_type: - RETURN_SYM + RETURN_ORACLE_SYM { LEX *lex= Lex; lex->init_last_field(&lex->sphead->m_return_field_def, @@ -17838,7 +17922,8 @@ xid: ; begin_or_start: - BEGIN_SYM {} + BEGIN_MARIADB_SYM {} + | BEGIN_ORACLE_SYM {} | START_SYM {} ; diff --git a/sql/structs.h b/sql/structs.h index 9ff52bccb40..c9b973d351a 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -691,26 +691,41 @@ public: struct Lex_for_loop_bounds_st { public: - class sp_assignment_lex *m_index; - class sp_assignment_lex *m_upper_bound; + class sp_assignment_lex *m_index; // The first iteration value (or cursor) + class sp_assignment_lex *m_target_bound; // The last iteration value int8 m_direction; bool m_implicit_cursor; - bool is_for_loop_cursor() const { return m_upper_bound == NULL; } + bool is_for_loop_cursor() const { return m_target_bound == NULL; } +}; + + +class Lex_for_loop_bounds_intrange: public Lex_for_loop_bounds_st +{ +public: + Lex_for_loop_bounds_intrange(int8 direction, + class sp_assignment_lex *left_expr, + class sp_assignment_lex *right_expr) + { + m_direction= direction; + m_index= direction > 0 ? left_expr : right_expr; + m_target_bound= direction > 0 ? right_expr : left_expr; + m_implicit_cursor= false; + } }; struct Lex_for_loop_st { public: - class sp_variable *m_index; - class sp_variable *m_upper_bound; + class sp_variable *m_index; // The first iteration value (or cursor) + class sp_variable *m_target_bound; // The last iteration value int m_cursor_offset; int8 m_direction; bool m_implicit_cursor; void init() { m_index= 0; - m_upper_bound= 0; + m_target_bound= 0; m_direction= 0; m_implicit_cursor= false; } @@ -718,7 +733,7 @@ public: { *this= other; } - bool is_for_loop_cursor() const { return m_upper_bound == NULL; } + bool is_for_loop_cursor() const { return m_target_bound == NULL; } bool is_for_loop_explicit_cursor() const { return is_for_loop_cursor() && !m_implicit_cursor; diff --git a/sql/upgrade_conf_file.cc b/sql/upgrade_conf_file.cc new file mode 100644 index 00000000000..4e167f0263f --- /dev/null +++ b/sql/upgrade_conf_file.cc @@ -0,0 +1,177 @@ +/* + 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ + + +/* + Variables that were present in older releases, but are now removed. + to get the list of variables that are present in current release + execute + + SELECT LOWER(variable_name) from INFORMATION_SCHEMA.GLOBAL_VARIABLES ORDER BY 1 + + Compare the list between releases to figure out which variables have gone. + + Note : the list below only includes the default-compiled server and none of the + loadable plugins. +*/ +#include <windows.h> +#include <initializer_list> +#include <stdlib.h> +#include <stdio.h> +#include <algorithm> + +static const char *removed_variables[] = +{ +"aria_recover", +"debug_crc_break", +"engine_condition_pushdown", +"have_csv", +"have_innodb", +"have_ndbcluster", +"have_partitioning", +"innodb_adaptive_flushing_method", +"innodb_adaptive_hash_index_partitions", +"innodb_additional_mem_pool_size", +"innodb_api_bk_commit_interval", +"innodb_api_disable_rowlock", +"innodb_api_enable_binlog", +"innodb_api_enable_mdl", +"innodb_api_trx_level", +"innodb_blocking_buffer_pool_restore", +"innodb_buffer_pool_populate", +"innodb_buffer_pool_restore_at_startup", +"innodb_buffer_pool_shm_checksum", +"innodb_buffer_pool_shm_key", +"innodb_checkpoint_age_target", +"innodb_cleaner_eviction_factor", +"innodb_cleaner_flush_chunk_size", +"innodb_cleaner_free_list_lwm", +"innodb_cleaner_lru_chunk_size", +"innodb_cleaner_lsn_age_factor", +"innodb_cleaner_max_flush_time", +"innodb_cleaner_max_lru_time", +"innodb_corrupt_table_action", +"innodb_dict_size_limit", +"innodb_doublewrite_file", +"innodb_empty_free_list_algorithm", +"innodb_fake_changes", +"innodb_fast_checksum", +"innodb_file_format", +"innodb_file_format_check", +"innodb_file_format_max", +"innodb_flush_neighbor_pages", +"innodb_foreground_preflush", +"innodb_ibuf_accel_rate", +"innodb_ibuf_active_contract", +"innodb_ibuf_max_size", +"innodb_import_table_from_xtrabackup", +"innodb_instrument_semaphores", +"innodb_kill_idle_transaction", +"innodb_large_prefix", +"innodb_lazy_drop_table", +"innodb_locking_fake_changes", +"innodb_log_arch_dir", +"innodb_log_arch_expire_sec", +"innodb_log_archive", +"innodb_log_block_size", +"innodb_log_checksum_algorithm", +"innodb_max_bitmap_file_size", +"innodb_max_changed_pages", +"innodb_merge_sort_block_size", +"innodb_mirrored_log_groups", +"innodb_mtflush_threads", +"innodb_persistent_stats_root_page", +"innodb_print_lock_wait_timeout_info", +"innodb_purge_run_now", +"innodb_purge_stop_now", +"innodb_read_ahead", +"innodb_recovery_stats", +"innodb_recovery_update_relay_log", +"innodb_show_locks_held", +"innodb_show_verbose_locks", +"innodb_stats_auto_update", +"innodb_stats_update_need_lock", +"innodb_support_xa", +"innodb_thread_concurrency_timer_based", +"innodb_track_changed_pages", +"innodb_track_redo_log_now", +"innodb_use_fallocate", +"innodb_use_global_flush_log_at_trx_commit", +"innodb_use_mtflush", +"innodb_use_stacktrace", +"innodb_use_sys_malloc", +"innodb_use_sys_stats_table", +"innodb_use_trim", +"log", +"log_slow_queries", +"rpl_recovery_rank", +"sql_big_tables", +"sql_low_priority_updates", +"sql_max_join_size" +}; + + +static int cmp_strings(const void* a, const void *b) +{ + return strcmp((const char *)a, *(const char **)b); +} + +/** + Convert file from a previous version, by removing +*/ +int upgrade_config_file(const char *myini_path) +{ +#define MY_INI_SECTION_SIZE 32*1024 +3 + static char section_data[MY_INI_SECTION_SIZE]; + for (const char *section_name : { "mysqld","server","mariadb" }) + { + DWORD size = GetPrivateProfileSection(section_name, section_data, MY_INI_SECTION_SIZE, myini_path); + if (size == MY_INI_SECTION_SIZE - 2) + { + return -1; + } + + for (char *keyval = section_data; *keyval; keyval += strlen(keyval) + 1) + { + char varname[256]; + char *key_end = strchr(keyval, '='); + if (!key_end) + key_end = keyval+ strlen(keyval); + + if (key_end - keyval > sizeof(varname)) + continue; + // copy and normalize (convert dash to underscore) to variable names + for (char *p = keyval, *q = varname;; p++,q++) + { + if (p == key_end) + { + *q = 0; + break; + } + *q = (*p == '-') ? '_' : *p; + } + const char *v = (const char *)bsearch(varname, removed_variables, sizeof(removed_variables) / sizeof(removed_variables[0]), + sizeof(char *), cmp_strings); + + if (v) + { + fprintf(stdout, "Removing variable '%s' from config file\n", varname); + // delete variable + *key_end = 0; + WritePrivateProfileString(section_name, keyval, 0, myini_path); + } + } + } + return 0; +} |