summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt4
-rw-r--r--sql/field.cc116
-rw-r--r--sql/field.h1
-rw-r--r--sql/gen_lex_token.cc8
-rw-r--r--sql/ha_partition.cc3
-rw-r--r--sql/item.cc57
-rw-r--r--sql/item.h10
-rw-r--r--sql/item_cmpfunc.cc18
-rw-r--r--sql/item_jsonfunc.cc1
-rw-r--r--sql/lex.h40
-rw-r--r--sql/mysql_upgrade_service.cc189
-rw-r--r--sql/semisync_master_ack_receiver.cc58
-rw-r--r--sql/semisync_master_ack_receiver.h147
-rw-r--r--sql/sp_head.cc28
-rw-r--r--sql/sp_pcontext.cc13
-rw-r--r--sql/sp_pcontext.h8
-rw-r--r--sql/sp_rcontext.cc27
-rw-r--r--sql/sql_class.h23
-rw-r--r--sql/sql_cursor.cc5
-rw-r--r--sql/sql_lex.cc83
-rw-r--r--sql/sql_lex.h18
-rw-r--r--sql/sql_prepare.cc12
-rw-r--r--sql/sql_select.cc14
-rw-r--r--sql/sql_type_int.h28
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/sql_yacc.yy505
-rw-r--r--sql/sql_yacc_ora.yy493
-rw-r--r--sql/structs.h29
-rw-r--r--sql/upgrade_conf_file.cc177
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, &current_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, &current_arena);
row->row_create_items(thd, &defs);
- thd->restore_active_arena(thd->spcont->callers_arena, &current_arena);
- }
+ thd->restore_active_arena(thd->spcont->callers_arena, &current_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;
+}