summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2020-08-04 17:24:15 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2020-08-04 17:24:15 +0200
commit48b5777ebda9bf14c60ad05298dac67933e9799f (patch)
tree2c023b5cc7811faea8a9b4ad82998e4624c29068 /sql
parentbbd70fcc43cc889e4593594ee5ca436fe1433aac (diff)
parent9a156e1a23046ba3e37bdb1e4e1ad887d3f5829b (diff)
downloadmariadb-git-48b5777ebda9bf14c60ad05298dac67933e9799f.tar.gz
Merge branch '10.4' into 10.5
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt1
-rw-r--r--sql/compat56.cc2
-rw-r--r--sql/debug_sync.cc4
-rw-r--r--sql/derror.cc2
-rw-r--r--sql/encryption.cc4
-rw-r--r--sql/event_data_objects.cc2
-rw-r--r--sql/event_db_repository.cc2
-rw-r--r--sql/event_parse_data.cc6
-rw-r--r--sql/event_queue.cc2
-rw-r--r--sql/events.cc2
-rw-r--r--sql/field.cc110
-rw-r--r--sql/field.h35
-rw-r--r--sql/filesort.cc4
-rw-r--r--sql/gcalc_slicescan.cc2
-rw-r--r--sql/gcalc_slicescan.h6
-rw-r--r--sql/gcalc_tools.cc4
-rw-r--r--sql/ha_partition.cc26
-rw-r--r--sql/ha_partition.h6
-rw-r--r--sql/handler.cc15
-rw-r--r--sql/handler.h16
-rw-r--r--sql/item.cc12
-rw-r--r--sql/item.h17
-rw-r--r--sql/item_buff.cc2
-rw-r--r--sql/item_cmpfunc.cc12
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_func.cc95
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/item_strfunc.cc6
-rw-r--r--sql/item_subselect.cc50
-rw-r--r--sql/item_subselect.h8
-rw-r--r--sql/item_sum.cc12
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/item_timefunc.cc24
-rw-r--r--sql/item_xmlfunc.cc20
-rw-r--r--sql/key.cc6
-rw-r--r--sql/lock.cc2
-rw-r--r--sql/log.cc18
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/log_event.h16
-rw-r--r--sql/log_event_old.cc2
-rw-r--r--sql/rpl_parallel.cc27
-rw-r--r--sql/sql_acl.cc65
-rw-r--r--sql/sql_admin.cc10
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_lex.cc31
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_schema.cc80
-rw-r--r--sql/sql_schema.h60
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc7
-rw-r--r--sql/sql_type.cc28
-rw-r--r--sql/sql_type.h9
-rw-r--r--sql/sql_yacc.yy48
-rw-r--r--sql/structs.h4
-rw-r--r--sql/table.cc3
57 files changed, 630 insertions, 326 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 0dc3caab507..d2180297907 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -145,6 +145,7 @@ SET (SQL_SOURCE
rpl_gtid.cc rpl_parallel.cc
semisync.cc semisync_master.cc semisync_slave.cc
semisync_master_ack_receiver.cc
+ sql_schema.cc
sql_type.cc sql_mode.cc sql_type_json.cc
sql_type_string.cc
sql_type_geom.cc
diff --git a/sql/compat56.cc b/sql/compat56.cc
index a500fcc46e1..3d8574419d3 100644
--- a/sql/compat56.cc
+++ b/sql/compat56.cc
@@ -305,7 +305,7 @@ uint my_datetime_binary_length(uint dec)
/*
On disk we store as unsigned number with DATETIMEF_INT_OFS offset,
- for HA_KETYPE_BINARY compatibilty purposes.
+ for HA_KETYPE_BINARY compatibility purposes.
*/
#define DATETIMEF_INT_OFS 0x8000000000LL
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 2fc2e00d043..d2656f36967 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -34,7 +34,7 @@
/*
Action to perform at a synchronization point.
NOTE: This structure is moved around in memory by realloc(), qsort(),
- and memmove(). Do not add objects with non-trivial constuctors
+ and memmove(). Do not add objects with non-trivial constructors
or destructors, which might prevent moving of this structure
with these functions.
*/
@@ -571,7 +571,7 @@ static void debug_sync_reset(THD *thd)
@description
Removing an action mainly means to decrement the ds_active counter.
But if the action is between other active action in the array, then
- the array needs to be shrinked. The active actions above the one to
+ the array needs to be shrunk. The active actions above the one to
be removed have to be moved down by one slot.
*/
diff --git a/sql/derror.cc b/sql/derror.cc
index 1c10bdfdd92..187d5bc20d2 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -237,7 +237,7 @@ static File open_error_msg_file(const char *file_name, const char *language,
MYF(0))) < 0)
{
/*
- Trying pre-5.4 sematics of the --language parameter.
+ Trying pre-5.4 semantics of the --language parameter.
It included the language-specific part, e.g.:
--language=/path/to/english/
*/
diff --git a/sql/encryption.cc b/sql/encryption.cc
index 9c38713fdfa..13239b91910 100644
--- a/sql/encryption.cc
+++ b/sql/encryption.cc
@@ -78,8 +78,8 @@ int initialize_encryption_plugin(st_plugin_int *plugin)
(struct st_mariadb_encryption*) plugin->plugin->info;
/*
- Copmiler on Spark doesn't like the '?' operator here as it
- belives the (uint (*)...) implies the C++ call model.
+ Compiler on Spark doesn't like the '?' operator here as it
+ believes the (uint (*)...) implies the C++ call model.
*/
if (handle->crypt_ctx_size)
encryption_handler.encryption_ctx_size_func= handle->crypt_ctx_size;
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index bd457fba4fa..91d1d871307 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -173,7 +173,7 @@ Event_creation_ctx::load_from_db(THD *thd,
/*************************************************************************/
/*
- Initiliazes dbname and name of an Event_queue_element_for_exec
+ Initializes dbname and name of an Event_queue_element_for_exec
object
SYNOPSIS
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 9e8e5f06043..9d0764cab14 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -678,7 +678,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
DBUG_PRINT("info", ("name: %.*s", (int) parse_data->name.length,
parse_data->name.str));
- DBUG_PRINT("info", ("check existance of an event with the same name"));
+ DBUG_PRINT("info", ("check existence of an event with the same name"));
if (!find_named_event(&parse_data->dbname, &parse_data->name, table))
{
if (thd->lex->create_info.or_replace())
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index e2f73cd2bb4..d2a168e538e 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -97,7 +97,7 @@ Event_parse_data::init_name(THD *thd, sp_name *spn)
ENDS or AT is in the past, we are trying to create an event that
will never be executed. If it has ON COMPLETION NOT PRESERVE
(default), then it would normally be dropped already, so on CREATE
- EVENT we give a warning, and do not create anyting. On ALTER EVENT
+ EVENT we give a warning, and do not create anything. On ALTER EVENT
we give a error, and do not change the event.
If the event has ON COMPLETION PRESERVE, then we see if the event is
@@ -362,7 +362,7 @@ wrong_value:
EVERY 5 MINUTE STARTS "2004-12-12 10:00:00" means that
the event will be executed every 5 minutes but this will
start at the date shown above. Expressions are possible :
- DATE_ADD(NOW(), INTERVAL 1 DAY) -- start tommorow at
+ DATE_ADD(NOW(), INTERVAL 1 DAY) -- start tomorrow at
same time.
RETURN VALUE
@@ -417,7 +417,7 @@ wrong_value:
EVERY 5 MINUTE ENDS "2004-12-12 10:00:00" means that
the event will be executed every 5 minutes but this will
end at the date shown above. Expressions are possible :
- DATE_ADD(NOW(), INTERVAL 1 DAY) -- end tommorow at
+ DATE_ADD(NOW(), INTERVAL 1 DAY) -- end tomorrow at
same time.
RETURN VALUE
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 71d1d2c68ee..86356e4325d 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -364,7 +364,7 @@ Event_queue::drop_matching_events(THD *thd, const LEX_CSTRING *pattern,
We don't call mysql_cond_broadcast(&COND_queue_state);
If we remove the top event:
1. The queue is empty. The scheduler will wake up at some time and
- realize that the queue is empty. If create_event() comes inbetween
+ realize that the queue is empty. If create_event() comes in between
it will signal the scheduler
2. The queue is not empty, but the next event after the previous top,
won't be executed any time sooner than the element we removed. Hence,
diff --git a/sql/events.cc b/sql/events.cc
index acf472736e8..33ddcdac3cb 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -130,7 +130,7 @@ bool Events::check_if_system_tables_error()
/**
Reconstructs interval expression from interval type and expression
- value that is in form of a value of the smalles entity:
+ value that is in form of a value of the smallest entity:
For
YEAR_MONTH - expression is in months
DAY_MINUTE - expression is in minutes
diff --git a/sql/field.cc b/sql/field.cc
index 8cd619571c4..0f4837f20f0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -42,7 +42,7 @@
#define MAX_EXPONENT 1024
/*****************************************************************************
- Instansiate templates and static variables
+ Instantiate templates and static variables
*****************************************************************************/
static const char *zero_timestamp="0000-00-00 00:00:00.000000";
@@ -88,7 +88,7 @@ bool Field::marked_for_write_or_computed() const
/*
Rules for merging different types of fields in UNION
- NOTE: to avoid 256*256 table, gap in table types numeration is skiped
+ NOTE: to avoid 256*256 table, gap in table types numeration is skipped
following #defines describe that gap and how to canculate number of fields
and index of field in this array.
*/
@@ -1552,7 +1552,7 @@ Item *Field_num::get_equal_zerofill_const_item(THD *thd, const Context &ctx,
/**
- Contruct warning parameters using thd->no_errors
+Construct warning parameters using thd->no_errors
to determine whether to generate or suppress warnings.
We can get here in a query like this:
SELECT COUNT(@@basedir);
@@ -1600,7 +1600,7 @@ Value_source::Converter_string_to_number::check_edom_and_truncation(THD *thd,
if (filter.want_warning_edom())
{
/*
- We can use err.ptr() here as ErrConvString is guranteed to put an
+ We can use err.ptr() here as ErrConvString is guaranteed to put an
end \0 here.
*/
THD *wthd= thd ? thd : current_thd;
@@ -1632,7 +1632,7 @@ Value_source::Converter_string_to_number::check_edom_and_truncation(THD *thd,
- found garbage at the end of the string.
@param type Data type name (e.g. "decimal", "integer", "double")
- @param edom Indicates that the string-to-number routine retuned
+ @param edom Indicates that the string-to-number routine returned
an error code equivalent to EDOM (value out of domain),
i.e. the string fully consisted of garbage and the
conversion routine could not get any digits from it.
@@ -1695,7 +1695,7 @@ int Field_num::check_edom_and_truncation(const char *type, bool edom,
/*
- Conver a string to an integer then check bounds.
+ Convert a string to an integer then check bounds.
SYNOPSIS
Field_num::get_int
@@ -2809,7 +2809,7 @@ int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs)
We only have to generate warnings if count_cuted_fields is set.
This is to avoid extra checks of the number when they are not needed.
Even if this flag is not set, it's OK to increment warnings, if
- it makes the code easer to read.
+ it makes the code easier to read.
*/
if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION)
@@ -2892,7 +2892,7 @@ int Field_decimal::store(const char *from_arg, size_t len, CHARSET_INFO *cs)
}
/*
- Now write the formated number
+ Now write the formatted number
First the digits of the int_% parts.
Do we have enough room to write these digits ?
@@ -3409,7 +3409,7 @@ int Field_new_decimal::store(const char *from, size_t length,
If check_decimal() failed because of EDOM-alike error,
(e.g. E_DEC_BAD_NUM), we have to initialize decimal_value to zero.
Note: if check_decimal() failed because of truncation,
- decimal_value is alreay properly initialized.
+ decimal_value is already properly initialized.
*/
my_decimal_set_zero(&decimal_value);
/*
@@ -4781,11 +4781,12 @@ int truncate_double(double *nr, uint field_length, uint dec,
{
uint order= field_length - dec;
uint step= array_elements(log_10) - 1;
- max_value= 1.0;
+ double max_value_by_dec= 1.0;
for (; order > step; order-= step)
- max_value*= log_10[step];
- max_value*= log_10[order];
- max_value-= 1.0 / log_10[dec];
+ max_value_by_dec*= log_10[step];
+ max_value_by_dec*= log_10[order];
+ max_value_by_dec-= 1.0 / log_10[dec];
+ set_if_smaller(max_value, max_value_by_dec);
/* Check for infinity so we don't get NaN in calculations */
if (!std::isinf(res))
@@ -5076,7 +5077,7 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
{
/*
We mark the flag with TIMESTAMP_FLAG to indicate to the client that
- this field will be automaticly updated on insert.
+ this field will be automatically updated on insert.
*/
flags|= TIMESTAMP_FLAG;
if (unireg_check != TIMESTAMP_DN_FIELD)
@@ -7505,7 +7506,7 @@ Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end,
with the real type. Since all allowable types have 0xF as most
significant bits of the metadata word, lengths <256 will not affect
the real type at all, while all other values will result in a
- non-existant type in the range 17-244.
+ non-existent type in the range 17-244.
@see Field_string::unpack
@@ -7706,8 +7707,7 @@ void Field_varstring::mark_unused_memory_as_defined()
#endif
-int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
- uint max_len) const
+int Field_varstring::cmp(const uchar *a_ptr, const uchar *b_ptr) const
{
uint a_length, b_length;
int diff;
@@ -7722,14 +7722,51 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
a_length= uint2korr(a_ptr);
b_length= uint2korr(b_ptr);
}
- set_if_smaller(a_length, max_len);
- set_if_smaller(b_length, max_len);
+ set_if_smaller(a_length, field_length);
+ set_if_smaller(b_length, field_length);
diff= field_charset()->strnncollsp(a_ptr + length_bytes, a_length,
b_ptr + length_bytes, b_length);
return diff;
}
+static int cmp_str_prefix(const uchar *ua, size_t alen, const uchar *ub,
+ size_t blen, size_t prefix, CHARSET_INFO *cs)
+{
+ const char *a= (char*)ua, *b= (char*)ub;
+ MY_STRCOPY_STATUS status;
+ prefix/= cs->mbmaxlen;
+ alen= cs->cset->well_formed_char_length(cs, a, a + alen, prefix, &status);
+ blen= cs->cset->well_formed_char_length(cs, b, b + blen, prefix, &status);
+ return cs->coll->strnncollsp(cs, ua, alen, ub, blen);
+}
+
+
+
+int Field_varstring::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
+ size_t prefix_len) const
+{
+ /* avoid expensive well_formed_char_length if possible */
+ if (prefix_len == table->field[field_index]->field_length)
+ return Field_varstring::cmp(a_ptr, b_ptr);
+
+ size_t a_length, b_length;
+
+ if (length_bytes == 1)
+ {
+ a_length= *a_ptr;
+ b_length= *b_ptr;
+ }
+ else
+ {
+ a_length= uint2korr(a_ptr);
+ b_length= uint2korr(b_ptr);
+ }
+ return cmp_str_prefix(a_ptr+length_bytes, a_length, b_ptr+length_bytes,
+ b_length, prefix_len, field_charset());
+}
+
+
/**
@note
varstring and blob keys are ALWAYS stored with a 2 byte length prefix
@@ -8235,8 +8272,8 @@ longlong Field_varstring_compressed::val_int(void)
}
-int Field_varstring_compressed::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
- uint max_len) const
+int Field_varstring_compressed::cmp(const uchar *a_ptr,
+ const uchar *b_ptr) const
{
String a, b;
uint a_length, b_length;
@@ -8255,13 +8292,10 @@ int Field_varstring_compressed::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
uncompress(&a, &a, a_ptr + length_bytes, a_length);
uncompress(&b, &b, b_ptr + length_bytes, b_length);
- if (a.length() > max_len)
- a.length(max_len);
- if (b.length() > max_len)
- b.length(max_len);
-
return sortcmp(&a, &b, field_charset());
}
+
+
Binlog_type_info Field_varstring_compressed::binlog_type_info() const
{
return Binlog_type_info(Field_varstring_compressed::binlog_type(),
@@ -8498,16 +8532,25 @@ int Field_blob::cmp(const uchar *a,uint32 a_length, const uchar *b,
}
-int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
- uint max_length) const
+int Field_blob::cmp(const uchar *a_ptr, const uchar *b_ptr) const
+{
+ uchar *blob1,*blob2;
+ memcpy(&blob1, a_ptr+packlength, sizeof(char*));
+ memcpy(&blob2, b_ptr+packlength, sizeof(char*));
+ size_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
+ return cmp(blob1, (uint32)a_len, blob2, (uint32)b_len);
+}
+
+
+int Field_blob::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
+ size_t prefix_len) const
{
uchar *blob1,*blob2;
memcpy(&blob1, a_ptr+packlength, sizeof(char*));
memcpy(&blob2, b_ptr+packlength, sizeof(char*));
- uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
- set_if_smaller(a_len, max_length);
- set_if_smaller(b_len, max_length);
- return Field_blob::cmp(blob1,a_len,blob2,b_len);
+ size_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
+ return cmp_str_prefix(blob1, a_len, blob2, b_len, prefix_len,
+ field_charset());
}
@@ -9690,7 +9733,8 @@ my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value)
The a and b pointer must be pointers to the field in a record
(not the table->record[0] necessarily)
*/
-int Field_bit::cmp_max(const uchar *a, const uchar *b, uint max_len) const
+int Field_bit::cmp_prefix(const uchar *a, const uchar *b,
+ size_t prefix_len) const
{
my_ptrdiff_t a_diff= a - ptr;
my_ptrdiff_t b_diff= b - ptr;
diff --git a/sql/field.h b/sql/field.h
index 72c99c37fb7..8a5e84edaa1 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -321,7 +321,7 @@ protected:
};
- // String-to-number convertion methods for the old code compatibility
+ // String-to-number conversion methods for the old code compatibility
longlong longlong_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
const char *end) const
{
@@ -402,7 +402,7 @@ public:
/*
Item context attributes.
Comparison functions pass their attributes to propagate_equal_fields().
- For exmple, for string comparison, the collation of the comparison
+ For example, for string comparison, the collation of the comparison
operation is important inside propagate_equal_fields().
*/
class Context
@@ -1273,8 +1273,13 @@ public:
const Conv_param &param)
const;
inline int cmp(const uchar *str) const { return cmp(ptr,str); }
- virtual int cmp_max(const uchar *a, const uchar *b, uint max_len) const
- { return cmp(a, b); }
+ /*
+ The following method is used for comparing prefix keys.
+ Currently it's only used in partitioning.
+ */
+ virtual int cmp_prefix(const uchar *a, const uchar *b,
+ size_t prefix_len) const
+ { return cmp(a, b); }
virtual int cmp(const uchar *,const uchar *) const=0;
virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U) const
{ return memcmp(a,b,pack_length()); }
@@ -4143,11 +4148,9 @@ public:
longlong val_int() override;
String *val_str(String *, String *) override;
my_decimal *val_decimal(my_decimal *) override;
- int cmp_max(const uchar *, const uchar *, uint max_length) const override;
- int cmp(const uchar *a,const uchar *b) const override
- {
- return cmp_max(a, b, ~0U);
- }
+ int cmp(const uchar *a,const uchar *b) const override;
+ int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len) const
+ override;
void sort_string(uchar *buff,uint length) override;
uint get_key_image(uchar *buff, uint length,
const uchar *ptr_arg, imagetype type) const override;
@@ -4222,8 +4225,7 @@ private:
{
return (field_length - 1) / mbmaxlen();
}
- int cmp_max(const uchar *a_ptr, const uchar *b_ptr, uint max_len) const
- override;
+ int cmp(const uchar *a_ptr, const uchar *b_ptr) const override;
/*
Compressed fields can't have keys as two rows may have different
@@ -4434,9 +4436,9 @@ public:
longlong val_int() override;
String *val_str(String *, String *) override;
my_decimal *val_decimal(my_decimal *) override;
- int cmp_max(const uchar *, const uchar *, uint max_length) const override;
- int cmp(const uchar *a,const uchar *b) const override
- { return cmp_max(a, b, ~0U); }
+ int cmp(const uchar *a, const uchar *b) const override;
+ int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len) const
+ override;
int cmp(const uchar *a, uint32 a_length, const uchar *b, uint32 b_length)
const;
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0U) const
@@ -4802,7 +4804,7 @@ private:
This is the reason:
- Field_bit::cmp_binary() is only implemented in the base class
(Field::cmp_binary()).
- - Field::cmp_binary() currenly use pack_length() to calculate how
+ - Field::cmp_binary() currently uses pack_length() to calculate how
long the data is.
- pack_length() includes size of the bits stored in the NULL bytes
of the record.
@@ -4874,7 +4876,8 @@ public:
}
int cmp_binary_offset(uint row_offset) override
{ return cmp_offset(row_offset); }
- int cmp_max(const uchar *a, const uchar *b, uint max_length) const override;
+ int cmp_prefix(const uchar *a, const uchar *b,
+ size_t max_length) const override;
int key_cmp(const uchar *a, const uchar *b) const override
{ return cmp_binary((uchar *) a, (uchar *) b); }
int key_cmp(const uchar *str, uint length) const override;
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 5a07b8596bd..ec82cea9775 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -975,12 +975,12 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
}
if (!quick_select)
{
- (void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */
+ (void) file->extra(HA_EXTRA_NO_CACHE); /* End caching of records */
if (!next_pos)
file->ha_rnd_end();
}
- /* Signal we should use orignal column read and write maps */
+ /* Signal we should use original column read and write maps */
sort_form->column_bitmaps_set(save_read_set, save_write_set);
if (unlikely(thd->is_error()))
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index 6d7ab7e29c3..93561f5fe97 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -1877,7 +1877,7 @@ int Gcalc_scan_iterator::add_eq_node(Gcalc_heap::Info *node, point *sp)
if (!en)
GCALC_DBUG_RETURN(1);
- /* eq_node iserted after teh equal point. */
+ /* eq_node inserted after the equal point. */
en->next= node->get_next();
node->next= en;
diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h
index 54b12962d2a..b5188f29dfd 100644
--- a/sql/gcalc_slicescan.h
+++ b/sql/gcalc_slicescan.h
@@ -362,9 +362,9 @@ enum Gcalc_scan_events
/*
- Gcalc_scan_iterator incapsulates the slisescan algorithm.
- It takes filled Gcalc_heap as an datasource. Then can be
- iterated trought the vertexes and intersection points with
+ Gcalc_scan_iterator incapsulates the slicescan algorithm.
+ It takes filled Gcalc_heap as a datasource. Then can be
+ iterated through the vertexes and intersection points with
the step() method. After the 'step()' one usually observes
the current 'slice' to do the necessary calculations, like
looking for intersections, calculating the area, whatever.
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
index 14a7c6331f3..307f063fb43 100644
--- a/sql/gcalc_tools.cc
+++ b/sql/gcalc_tools.cc
@@ -1184,14 +1184,14 @@ int Gcalc_operation_reducer::connect_threads(
{
rp0->outer_poly= prev_range->thread_start;
tb->thread_start= prev_range->thread_start;
- /* Chack if needed */
+ /* Check if needed */
ta->thread_start= prev_range->thread_start;
}
else
{
rp0->outer_poly= 0;
ta->thread_start= rp0;
- /* Chack if needed */
+ /* Check if needed */
tb->thread_start= rp0;
}
GCALC_DBUG_RETURN(0);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 307f7ff24af..0a378bde0bd 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1522,7 +1522,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
/**
- @brief Check and repair the table if neccesary
+ @brief Check and repair the table if necessary
@param thd Thread object
@@ -3049,7 +3049,7 @@ error:
/**
Read the .par file to get the partitions engines and names
- @param name Name of table file (without extention)
+ @param name Name of table file (without extension)
@return Operation status
@retval true Failure
@@ -3279,7 +3279,7 @@ static uchar *get_part_name(PART_NAME_DEF *part, size_t *length,
@return Operation status
@retval true Failure
- @retval false Sucess
+ @retval false Success
*/
bool ha_partition::insert_partition_name_in_hash(const char *name, uint part_id,
@@ -3405,7 +3405,7 @@ err:
@return Operation status
@retval true Failure
- @retval false Sucess
+ @retval false Success
*/
bool ha_partition::set_ha_share_ref(Handler_share **ha_share_arg)
@@ -4396,7 +4396,7 @@ int ha_partition::write_row(const uchar * buf)
/*
If we have failed to set the auto-increment value for this row,
it is highly likely that we will not be able to insert it into
- the correct partition. We must check and fail if neccessary.
+ the correct partition. We must check and fail if necessary.
*/
if (unlikely(error))
goto exit;
@@ -4465,7 +4465,7 @@ exit:
have the previous row record in it, while new_data will have the newest
data in it.
Keep in mind that the server can do updates based on ordering if an
- ORDER BY clause was used. Consecutive ordering is not guarenteed.
+ ORDER BY clause was used. Consecutive ordering is not guaranteed.
Called from sql_select.cc, sql_acl.cc, sql_update.cc, and sql_insert.cc.
new_data is always record[0]
@@ -4593,7 +4593,7 @@ exit:
(from either a previous rnd_xxx() or index_xxx() call).
If you keep a pointer to the last row or can access a primary key it will
make doing the deletion quite a bit easier.
- Keep in mind that the server does no guarentee consecutive deletions.
+ Keep in mind that the server does no guarantee consecutive deletions.
ORDER BY clauses can be used.
Called in sql_acl.cc and sql_udf.cc to manage internal table information.
@@ -5011,7 +5011,7 @@ int ha_partition::end_bulk_insert()
When scan is used we will scan one handler partition at a time.
When preparing for rnd_pos we will init all handler partitions.
- No extra cache handling is needed when scannning is not performed.
+ No extra cache handling is needed when scanning is not performed.
Before initialising we will call rnd_end to ensure that we clean up from
any previous incarnation of a table scan.
@@ -8714,7 +8714,7 @@ static int end_keyread_cb(handler* h, void *unused)
function after completing a query.
3) It is called when deleting the QUICK_RANGE_SELECT object if the
QUICK_RANGE_SELECT object had its own handler object. It is called
- immediatley before close of this local handler object.
+ immediately before close of this local handler object.
HA_EXTRA_KEYREAD:
HA_EXTRA_NO_KEYREAD:
These parameters are used to provide an optimisation hint to the handler.
@@ -8751,7 +8751,7 @@ static int end_keyread_cb(handler* h, void *unused)
HA_EXTRA_IGNORE_DUP_KEY:
HA_EXTRA_NO_IGNORE_DUP_KEY:
Informs the handler to we will not stop the transaction if we get an
- duplicate key errors during insert/upate.
+ duplicate key errors during insert/update.
Always called in pair, triggered by INSERT IGNORE and other similar
SQL constructs.
Not used by MyISAM.
@@ -10251,7 +10251,7 @@ bool ha_partition::prepare_inplace_alter_table(TABLE *altered_table,
/*
Changing to similar partitioning, only update metadata.
- Non allowed changes would be catched in prep_alter_part_table().
+ Non allowed changes would be caought in prep_alter_part_table().
*/
if (ha_alter_info->alter_info->partition_flags == ALTER_PARTITION_INFO)
{
@@ -10287,7 +10287,7 @@ bool ha_partition::inplace_alter_table(TABLE *altered_table,
/*
Changing to similar partitioning, only update metadata.
- Non allowed changes would be catched in prep_alter_part_table().
+ Non allowed changes would be caught in prep_alter_part_table().
*/
if (ha_alter_info->alter_info->partition_flags == ALTER_PARTITION_INFO)
{
@@ -10335,7 +10335,7 @@ bool ha_partition::commit_inplace_alter_table(TABLE *altered_table,
/*
Changing to similar partitioning, only update metadata.
- Non allowed changes would be catched in prep_alter_part_table().
+ Non allowed changes would be caught in prep_alter_part_table().
*/
if (ha_alter_info->alter_info->partition_flags == ALTER_PARTITION_INFO)
{
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 120d5cb2b30..4556c5f482e 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -515,7 +515,7 @@ public:
-------------------------------------------------------------------------
MODULE create/delete handler object
-------------------------------------------------------------------------
- Object create/delete methode. The normal called when a table object
+ Object create/delete method. Normally called when a table object
exists. There is also a method to create the handler object with only
partition information. This is used from mysql_create_table when the
table is to be created and the engine type is deduced to be the
@@ -832,7 +832,7 @@ public:
/**
@breif
- Positions an index cursor to the index specified in the hanlde. Fetches the
+ Positions an index cursor to the index specified in the handle. Fetches the
row if available. If the key value is null, begin at first key of the
index.
*/
@@ -1132,7 +1132,7 @@ public:
HA_REC_NOT_IN_SEQ:
This flag is set for handlers that cannot guarantee that the rows are
- returned accroding to incremental positions (0, 1, 2, 3...).
+ returned according to incremental positions (0, 1, 2, 3...).
This also means that rnd_next() should return HA_ERR_RECORD_DELETED
if it finds a deleted row.
(MyISAM (not fixed length row), HEAP, InnoDB)
diff --git a/sql/handler.cc b/sql/handler.cc
index 58f1c60edf9..64d13d1601f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -804,7 +804,7 @@ int ha_end()
DBUG_ENTER("ha_end");
/*
- This should be eventualy based on the graceful shutdown flag.
+ This should be eventually based on the graceful shutdown flag.
So if flag is equal to HA_PANIC_CLOSE, the deallocate
the errors.
*/
@@ -1536,8 +1536,8 @@ int ha_commit_trans(THD *thd, bool all)
THD_TRANS *trans= all ? &thd->transaction->all : &thd->transaction->stmt;
/*
"real" is a nick name for a transaction for which a commit will
- make persistent changes. E.g. a 'stmt' transaction inside a 'all'
- transation is not 'real': even though it's possible to commit it,
+ make persistent changes. E.g. a 'stmt' transaction inside an 'all'
+ transaction is not 'real': even though it's possible to commit it,
the changes are not durable as they might be rolled back if the
enclosing 'all' transaction is rolled back.
*/
@@ -2829,7 +2829,7 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root)
/*
TODO: Implement a more efficient way to have more than one index open for
- the same table instance. The ha_open call is not cachable for clone.
+ the same table instance. The ha_open call is not cacheable for clone.
This is not critical as the engines already have the table open
and should be able to use the original instance of the table.
@@ -3731,7 +3731,7 @@ int handler::update_auto_increment()
index_init() or rnd_init() and in any column_bitmaps_signal() call after
this.
- The handler is allowd to do changes to the bitmap after a index_init or
+ The handler is allowed to do changes to the bitmap after a index_init or
rnd_init() call is made as after this, MySQL will not use the bitmap
for any program logic checking.
*/
@@ -3794,7 +3794,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
{ // Autoincrement at key-start
error= ha_index_last(table->record[1]);
/*
- MySQL implicitely assumes such method does locking (as MySQL decides to
+ MySQL implicitly assumes such method does locking (as MySQL decides to
use nr+increment without checking again with the handler, in
handler::update_auto_increment()), so reserves to infinite.
*/
@@ -6812,7 +6812,7 @@ int handler::check_duplicate_long_entry_key(const uchar *new_rec, uint key_no)
DBUG_ASSERT(fnc->arguments()[0]->type() == Item::FIELD_ITEM);
t_field= static_cast<Item_field *>(fnc->arguments()[0])->field;
uint length= (uint)fnc->arguments()[1]->val_int();
- if (t_field->cmp_max(t_field->ptr, t_field->ptr + diff, length))
+ if (t_field->cmp_prefix(t_field->ptr, t_field->ptr + diff, length))
is_same= false;
}
}
@@ -8306,6 +8306,7 @@ bool Table_period_info::check_field(const Create_field* f,
{
my_error(ER_PERIOD_FIELD_WRONG_ATTRIBUTES, MYF(0),
f->field_name.str, "GENERATED ALWAYS AS");
+ res= true;
}
return res;
diff --git a/sql/handler.h b/sql/handler.h
index d55a83c9b93..ada5fbf40d4 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -240,7 +240,7 @@ enum chf_create_flags {
this flag must implement start_read_removal() and end_read_removal().
The handler may return "fake" rows constructed from the key of the row
asked for. This is used to optimize UPDATE and DELETE by reducing the
- numer of roundtrips between handler and storage engine.
+ number of roundtrips between handler and storage engine.
Example:
UPDATE a=1 WHERE pk IN (<keys>)
@@ -582,7 +582,7 @@ enum enum_binlog_command {
/* Bits in used_fields */
#define HA_CREATE_USED_AUTO (1UL << 0)
-#define HA_CREATE_USED_RAID (1UL << 1) //RAID is no longer availble
+#define HA_CREATE_USED_RAID (1UL << 1) //RAID is no longer available
#define HA_CREATE_USED_UNION (1UL << 2)
#define HA_CREATE_USED_INSERT_METHOD (1UL << 3)
#define HA_CREATE_USED_MIN_ROWS (1UL << 4)
@@ -1242,7 +1242,7 @@ struct handler_iterator {
/*
Pointer to buffer for the iterator to use.
Should be allocated by function which created the iterator and
- destroied by freed by above "destroy" call
+ destroyed by freed by above "destroy" call
*/
void *buffer;
};
@@ -1455,7 +1455,7 @@ struct handlerton
"cookie".
The flush and call of commit_checkpoint_notify_ha() need not happen
- immediately - it can be scheduled and performed asynchroneously (ie. as
+ immediately - it can be scheduled and performed asynchronously (ie. as
part of next prepare(), or sync every second, or whatever), but should
not be postponed indefinitely. It is however also permissible to do it
immediately, before returning from commit_checkpoint_request().
@@ -1551,7 +1551,7 @@ struct handlerton
file extention. This is implied by the open_table_error()
and the default discovery implementation.
- Second element - data file extention. This is implied
+ Second element - data file extension. This is implied
assumed by REPAIR TABLE ... USE_FRM implementation.
*/
const char **tablefile_extensions; // by default - empty list
@@ -2297,7 +2297,7 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
CONVERT TO CHARACTER SET DEFAULT
to
CONVERT TO CHARACTER SET <character-set-of-the-current-database>
- TODO: Should't we postpone resolution of DEFAULT until the
+ TODO: Shouldn't we postpone resolution of DEFAULT until the
character set of the table owner database is loaded from its db.opt?
*/
DBUG_ASSERT(cs);
@@ -3093,7 +3093,7 @@ public:
ha_statistics stats;
/** MultiRangeRead-related members: */
- range_seq_t mrr_iter; /* Interator to traverse the range sequence */
+ range_seq_t mrr_iter; /* Iterator to traverse the range sequence */
RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
@@ -4188,7 +4188,7 @@ public:
This method offers the storage engine, the possibility to store a reference
to a table name which is going to be used with query cache.
The method is called each time a statement is written to the cache and can
- be used to verify if a specific statement is cachable. It also offers
+ be used to verify if a specific statement is cacheable. It also offers
the possibility to register a generic (but static) call back function which
is called each time a statement is matched against the query cache.
diff --git a/sql/item.cc b/sql/item.cc
index 3ea1a493db2..f534a2c182b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5074,7 +5074,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
@note
We have to mark all items between current_sel (including) and
- last_select (excluding) as dependend (select before last_select should
+ last_select (excluding) as dependent (select before last_select should
be marked with actual table mask used by resolved item, all other with
OUTER_REF_TABLE_BIT) and also write dependence information to Item of
resolved identifier.
@@ -5448,7 +5448,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
bool upward_lookup= FALSE;
TABLE_LIST *table_list;
- /* Calulate the TABLE_LIST for the table */
+ /* Calculate the TABLE_LIST for the table */
table_list= (cached_table ? cached_table :
field_found && (*from_field) != view_ref_found ?
(*from_field)->table->pos_in_table_list : 0);
@@ -6184,7 +6184,7 @@ Item *Item_field::propagate_equal_fields(THD *thd,
but failed to create a valid DATE literal from the given string literal.
Do not do constant propagation in such cases and unlink
- "this" from the found Item_equal (as this equality not usefull).
+ "this" from the found Item_equal (as this equality not useful).
*/
item_equal= NULL;
return this;
@@ -7906,7 +7906,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
/*
Due to cache, find_field_in_tables() can return field which
doesn't belong to provided outer_context. In this case we have
- to find proper field context in order to fix field correcly.
+ to find proper field context in order to fix field correctly.
*/
do
{
@@ -8091,9 +8091,9 @@ Item* Item_ref::transform(THD *thd, Item_transformer transformer, uchar *arg)
callback functions.
First the function applies the analyzer to the Item_ref object. Then
- if the analizer succeeeds we first applies the compile method to the
+ if the analyzer succeeds we first apply the compile method to the
object the Item_ref object is referencing. If this returns a new
- item the old item is substituted for a new one. After this the
+ item the old item is substituted for a new one. After this the
transformer is applied to the Item_ref object itself.
The compile function is not called if the analyzer returns NULL
in the parameter arg_p.
diff --git a/sql/item.h b/sql/item.h
index 150d9cd215e..c4fbf8f9c0a 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -164,7 +164,7 @@ void dummy_error_processor(THD *thd, void *data);
void view_error_processor(THD *thd, void *data);
/*
- Instances of Name_resolution_context store the information necesary for
+ Instances of Name_resolution_context store the information necessary for
name resolution of Items and other context analysis of a query made in
fix_fields().
@@ -344,7 +344,7 @@ public:
Monotonicity is defined only for Item* trees that represent table
partitioning expressions (i.e. have no subselects/user vars/PS parameters
etc etc). An Item* tree is assumed to have the same monotonicity properties
- as its correspoinding function F:
+ as its corresponding function F:
[signed] longlong F(field1, field2, ...) {
put values of field_i into table record buffer;
@@ -1153,7 +1153,7 @@ public:
/*
real_type() is the type of base item. This is same as type() for
most items, except Item_ref() and Item_cache_wrapper() where it
- shows the type for the underlaying item.
+ shows the type for the underlying item.
*/
virtual enum Type real_type() const { return type(); }
@@ -1299,7 +1299,7 @@ public:
The caller can modify the returned String, if it's not marked
"const" (with the String::mark_as_const() method). That means that
if the item returns its own internal buffer (e.g. tmp_value), it
- *must* be marked "const" [1]. So normally it's preferrable to
+ *must* be marked "const" [1]. So normally it's preferable to
return the result value in the String, that was passed as an
argument. But, for example, SUBSTR() returns a String that simply
points into the buffer of SUBSTR()'s args[0]->val_str(). Such a
@@ -1775,7 +1775,7 @@ public:
@param cond_ptr[OUT] Store a replacement item here if the condition
can be simplified, e.g.:
WHERE part1 OR part2 OR part3
- with one of the partN evalutating to SEL_TREE::ALWAYS.
+ with one of the partN evaluating to SEL_TREE::ALWAYS.
*/
virtual SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
/*
@@ -2369,8 +2369,9 @@ public:
virtual bool is_outer_field() const { DBUG_ASSERT(is_fixed()); return FALSE; }
/**
- Checks if this item or any of its decendents contains a subquery. This is a
- replacement of the former Item::has_subquery() and Item::with_subselect.
+ Checks if this item or any of its descendents contains a subquery.
+ This is a replacement of the former Item::has_subquery() and
+ Item::with_subselect.
*/
virtual bool with_subquery() const { DBUG_ASSERT(is_fixed()); return false; }
@@ -6061,7 +6062,7 @@ public:
This is the method that updates the cached value.
It must be explicitly called by the user of this class to store the value
- of the orginal item in the cache.
+ of the original item in the cache.
*/
virtual void copy() = 0;
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 81949bcdae0..9c96fdb1a9a 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -192,7 +192,7 @@ bool Cached_item_field::cmp(void)
/*
If value is not null and value changed (from null to not null or
- becasue of value change), then copy the new value to buffer.
+ because of value change), then copy the new value to buffer.
*/
if (! null_value && (tmp || (tmp= (field->cmp(buff) != 0))))
field->get_image(buff,length,field->charset());
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 8203af5c7dc..c753b963fd4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1404,7 +1404,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
@note
Item_in_optimizer should work as pass-through for
- subqueries that were processed by ALL/ANY->MIN/MAX rewrite
- - subqueries taht were originally EXISTS subqueries (and were coverted by
+ - subqueries that were originally EXISTS subqueries (and were coinverted by
the EXISTS->IN rewrite)
When Item_in_optimizer is not not working as a pass-through, it
@@ -1991,8 +1991,8 @@ longlong Item_func_interval::val_int()
interval_range *range= intervals + mid;
my_bool cmp_result;
/*
- The values in the range intervall may have different types,
- Only do a decimal comparision of the first argument is a decimal
+ The values in the range interval may have different types,
+ Only do a decimal comparison if the first argument is a decimal
and we are comparing against a decimal
*/
if (dec && range->type == DECIMAL_RESULT)
@@ -2634,7 +2634,7 @@ Item_func_nullif::fix_length_and_dec()
Some examples of what NULLIF can end up with after argument
substitution (we don't mention args[1] in some cases for simplicity):
- 1. l_expr is not an aggragate function:
+ 1. l_expr is not an aggregate function:
a. No conversion happened.
args[0] and args[2] were not replaced to something else
@@ -2758,7 +2758,7 @@ Item_func_nullif::fix_length_and_dec()
In this case we remember and reuse m_arg0 during EXECUTE time as args[2].
QQ: How to make sure that m_args0 does not point
- to something temporary which will be destoyed between PREPARE and EXECUTE.
+ to something temporary which will be destroyed between PREPARE and EXECUTE.
The condition below should probably be more strict and somehow check that:
- change_item_tree() was called for the new args[0]
- m_args0 is referenced from inside args[0], e.g. as a function argument,
@@ -7301,7 +7301,7 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
and not ot2.col.
eliminate_item_equal() also has code that deals with equality substitution
- in presense of SJM nests.
+ in presence of SJM nests.
*/
TABLE_LIST *emb_nest;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index b943bfc90da..23d04a57580 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -178,7 +178,7 @@ protected:
/*
Return the full select tree for "field_item" and "value":
- a single SEL_TREE if the field is not in a multiple equality, or
- - a conjuction of all SEL_TREEs for all fields from
+ - a conjunction of all SEL_TREEs for all fields from
the same multiple equality with "field_item".
*/
SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 813927df32b..dc1de8a8e9f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -525,7 +525,7 @@ Item *Item_func::transform(THD *thd, Item_transformer transformer, uchar *argume
callback functions.
First the function applies the analyzer to the root node of
- the Item_func object. Then if the analizer succeeeds (returns TRUE)
+ the Item_func object. Then if the analyzer succeeds (returns TRUE)
the function recursively applies the compile method to each argument
of the Item_func node.
If the call of the method for an argument item returns a new item
@@ -1493,13 +1493,14 @@ double Item_func_div::real_op()
my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
{
int err;
+ my_decimal tmp;
VDec2_lazy val(args[0], args[1]);
if ((null_value= val.has_null()))
return 0;
if ((err= check_decimal_overflow(my_decimal_div(E_DEC_FATAL_ERROR &
~E_DEC_OVERFLOW &
~E_DEC_DIV_ZERO,
- decimal_value,
+ &tmp,
val.m_a.ptr(), val.m_b.ptr(),
prec_increment))) > 3)
{
@@ -1508,6 +1509,7 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
null_value= 1;
return 0;
}
+ tmp.round_to(decimal_value, decimals, HALF_UP);
return decimal_value;
}
@@ -1564,7 +1566,7 @@ bool Item_func_div::fix_length_and_dec()
DBUG_ENTER("Item_func_div::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
prec_increment= current_thd->variables.div_precincrement;
- maybe_null= 1; // devision by zero
+ maybe_null= 1; // division by zero
const Type_aggregator *aggregator= &type_handler_data->m_type_aggregator_for_div;
DBUG_EXECUTE_IF("num_op", aggregator= &type_handler_data->m_type_aggregator_non_commutative_test;);
@@ -2516,6 +2518,20 @@ void Item_func_round::fix_arg_datetime()
}
+bool Item_func_round::test_if_length_can_increase()
+{
+ if (truncate)
+ return false;
+ if (args[1]->const_item() && !args[1]->is_expensive())
+ {
+ // Length can increase in some cases: e.g. ROUND(9,-1) -> 10.
+ Longlong_hybrid val1= args[1]->to_longlong_hybrid();
+ return !args[1]->null_value && val1.neg();
+ }
+ return true; // ROUND(x,n), where n is not a constant.
+}
+
+
/**
Calculate data type and attributes for INT-alike input.
@@ -2534,52 +2550,41 @@ void Item_func_round::fix_arg_datetime()
simple cases.
*/
void Item_func_round::fix_arg_int(const Type_handler *preferred,
- const Type_std_attributes *preferred_attrs)
+ const Type_std_attributes *preferred_attrs,
+ bool use_decimal_on_length_increase)
{
DBUG_ASSERT(args[0]->decimals == 0);
- if (args[1]->const_item())
+
+ Type_std_attributes::set(preferred_attrs);
+ if (!test_if_length_can_increase())
{
- Longlong_hybrid val1= args[1]->to_longlong_hybrid();
- if (args[1]->null_value)
- fix_length_and_dec_double(NOT_FIXED_DEC);
- else if ((!val1.to_uint(DECIMAL_MAX_SCALE) && truncate) ||
- args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)
- {
- // Here we can keep INT_RESULT
- // Length can increase in some cases: ROUND(9,-1) -> 10
- int length_can_increase= MY_TEST(!truncate && val1.neg());
- if (preferred)
- {
- Type_std_attributes::set(preferred_attrs);
- if (!length_can_increase)
- {
- // Preserve the exact data type and attributes
- set_handler(preferred);
- }
- else
- {
- max_length++;
- set_handler(type_handler_long_or_longlong());
- }
- }
- else
- {
- /*
- This branch is currently used for hex hybrid only.
- It's known to be unsigned. So sign length is 0.
- */
- DBUG_ASSERT(args[0]->unsigned_flag); // no needs to add sign length
- max_length= args[0]->decimal_precision() + length_can_increase;
- unsigned_flag= true;
- decimals= 0;
- set_handler(type_handler_long_or_longlong());
- }
- }
+ // Preserve the exact data type and attributes
+ set_handler(preferred);
+ }
+ else
+ {
+ max_length++;
+ if (use_decimal_on_length_increase)
+ set_handler(&type_handler_newdecimal);
else
- fix_length_and_dec_decimal(val1.to_uint(DECIMAL_MAX_SCALE));
+ set_handler(type_handler_long_or_longlong());
}
+}
+
+
+void Item_func_round::fix_arg_hex_hybrid()
+{
+ DBUG_ASSERT(args[0]->decimals == 0);
+ DBUG_ASSERT(args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS);
+ DBUG_ASSERT(args[0]->unsigned_flag); // no needs to add sign length
+ bool length_can_increase= test_if_length_can_increase();
+ max_length= args[0]->decimal_precision() + MY_TEST(length_can_increase);
+ unsigned_flag= true;
+ decimals= 0;
+ if (length_can_increase && args[0]->max_length >= 8)
+ set_handler(&type_handler_newdecimal);
else
- fix_length_and_dec_double(args[0]->decimals);
+ set_handler(type_handler_long_or_longlong());
}
@@ -4812,7 +4817,7 @@ bool Item_func_set_user_var::register_field_in_bitmap(void *arg)
@param type type of new value
@param cs charset info for new value
@param dv derivation for new value
- @param unsigned_arg indiates if a value of type INT_RESULT is unsigned
+ @param unsigned_arg indicates if a value of type INT_RESULT is unsigned
@note Sets error and fatal error if allocation fails.
@@ -6750,7 +6755,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
/*
Here we check privileges of the stored routine only during view
creation, in order to validate the view. A runtime check is
- perfomed in Item_func_sp::execute(), and this method is not
+ performed in Item_func_sp::execute(), and this method is not
called during context analysis. Notice, that during view
creation we do not infer into stored routine bodies and do not
check privileges of its statements, which would probably be a
diff --git a/sql/item_func.h b/sql/item_func.h
index 07ee913b07d..f39caa46ffd 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1897,6 +1897,7 @@ class Item_func_round :public Item_func_hybrid_field_type
bool truncate;
void fix_length_and_dec_decimal(uint decimals_to_set);
void fix_length_and_dec_double(uint decimals_to_set);
+ bool test_if_length_can_increase();
public:
Item_func_round(THD *thd, Item *a, Item *b, bool trunc_arg)
:Item_func_hybrid_field_type(thd, a, b), truncate(trunc_arg) {}
@@ -1918,7 +1919,9 @@ public:
}
void fix_arg_decimal();
void fix_arg_int(const Type_handler *preferred,
- const Type_std_attributes *preferred_attributes);
+ const Type_std_attributes *preferred_attributes,
+ bool use_decimal_on_length_increase);
+ void fix_arg_hex_hybrid();
void fix_arg_double();
void fix_arg_time();
void fix_arg_datetime();
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 7f853a73c71..176a6e6efc9 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -984,7 +984,7 @@ String *Item_func_concat_ws::val_str(String *str)
goto null; // Must be a blob
}
else if (res2 == &tmp_value)
- { // This can happend only 1 time
+ { // This can happen only 1 time
if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
goto null;
res= &tmp_value;
@@ -1134,7 +1134,7 @@ bool Item_func_reverse::fix_length_and_dec()
}
/**
- Replace all occurences of string2 in string1 with string3.
+ Replace all occurrences of string2 in string1 with string3.
Don't reallocate val_str() if not needed.
@@ -3979,7 +3979,7 @@ bool Item_func_export_set::fix_length_and_dec()
using in a SQL statement.
Adds a \\ before all characters that needs to be escaped in a SQL string.
- We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
+ We also escape '^Z' (END-OF-FILE in windows) to avoid problems when
running commands from a file in windows.
This function is very useful when you want to generate SQL statements.
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 16fa06f4cda..9525019888d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1171,12 +1171,12 @@ void Item_singlerow_subselect::reset()
/**
@todo
- - We cant change name of Item_field or Item_ref, because it will
- prevent it's correct resolving, but we should save name of
+ - We can't change name of Item_field or Item_ref, because it will
+ prevent its correct resolving, but we should save name of
removed item => we do not make optimization if top item of
list is field or reference.
- switch off this optimization for prepare statement,
- because we do not rollback this changes.
+ because we do not rollback these changes.
Make rollback for it, or special name resolving mode in 5.0.
@param join Join object of the subquery (i.e. 'child' join).
@@ -1199,8 +1199,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
select_lex->item_list.elements == 1 &&
!select_lex->item_list.head()->with_sum_func() &&
/*
- We cant change name of Item_field or Item_ref, because it will
- prevent it's correct resolving, but we should save name of
+ We can't change name of Item_field or Item_ref, because it will
+ prevent its correct resolving, but we should save name of
removed item => we do not make optimization if top item of
list is field or reference.
TODO: solve above problem
@@ -1698,7 +1698,7 @@ longlong Item_exists_subselect::val_int()
Return the result of EXISTS as a string value
Converts the true/false result into a string value.
- Note that currently this cannot be NULL, so if the query exection fails
+ Note that currently this cannot be NULL, so if the query execution fails
it will return 0.
@param decimal_value[out] buffer to hold the resulting string value
@@ -1721,7 +1721,7 @@ String *Item_exists_subselect::val_str(String *str)
Return the result of EXISTS as a decimal value
Converts the true/false result into a decimal value.
- Note that currently this cannot be NULL, so if the query exection fails
+ Note that currently this cannot be NULL, so if the query execution fails
it will return 0.
@param decimal_value[out] Buffer to hold the resulting decimal value
@@ -2419,7 +2419,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
is_not_null_test(v3))
where is_not_null_test registers NULLs values but reject rows.
- in case when we do not need correct NULL, we have simplier construction:
+ in case when we do not need correct NULL, we have simpler construction:
EXISTS (SELECT ... WHERE where and
(l1 = v1) and
(l2 = v2) and
@@ -2822,6 +2822,8 @@ bool Item_exists_subselect::select_prepare_to_be_in()
Check if 'func' is an equality in form "inner_table.column = outer_expr"
@param func Expression to check
+ @param allow_subselect If true, the outer_expr part can have a subquery
+ If false, it cannot.
@param local_field OUT Return "inner_table.column" here
@param outer_expr OUT Return outer_expr here
@@ -2829,6 +2831,7 @@ bool Item_exists_subselect::select_prepare_to_be_in()
*/
static bool check_equality_for_exist2in(Item_func *func,
+ bool allow_subselect,
Item_ident **local_field,
Item **outer_exp)
{
@@ -2839,7 +2842,8 @@ static bool check_equality_for_exist2in(Item_func *func,
args= func->arguments();
if (args[0]->real_type() == Item::FIELD_ITEM &&
args[0]->all_used_tables() != OUTER_REF_TABLE_BIT &&
- args[1]->all_used_tables() == OUTER_REF_TABLE_BIT)
+ args[1]->all_used_tables() == OUTER_REF_TABLE_BIT &&
+ (allow_subselect || !args[1]->with_subquery()))
{
/* It is Item_field or Item_direct_view_ref) */
DBUG_ASSERT(args[0]->type() == Item::FIELD_ITEM ||
@@ -2850,7 +2854,8 @@ static bool check_equality_for_exist2in(Item_func *func,
}
else if (args[1]->real_type() == Item::FIELD_ITEM &&
args[1]->all_used_tables() != OUTER_REF_TABLE_BIT &&
- args[0]->all_used_tables() == OUTER_REF_TABLE_BIT)
+ args[0]->all_used_tables() == OUTER_REF_TABLE_BIT &&
+ (allow_subselect || !args[0]->with_subquery()))
{
/* It is Item_field or Item_direct_view_ref) */
DBUG_ASSERT(args[1]->type() == Item::FIELD_ITEM ||
@@ -2879,6 +2884,13 @@ typedef struct st_eq_field_outer
outer1=inner_tbl1.col1 AND ... AND outer2=inner_tbl1.col2 AND remainder_cond
+ if there is just one outer_expr=inner_expr pair, then outer_expr can have a
+ subselect in it. If there are many such pairs, then none of outer_expr can
+ have a subselect in it. If we allow this, the query will fail with an error:
+
+ This version of MariaDB doesn't yet support 'SUBQUERY in ROW in left
+ expression of IN/ALL/ANY'
+
@param conds Condition to be checked
@parm result Array to collect EQ_FIELD_OUTER elements describing
inner-vs-outer equalities the function has found.
@@ -2896,14 +2908,17 @@ static bool find_inner_outer_equalities(Item **conds,
{
List_iterator<Item> li(*((Item_cond*)*conds)->argument_list());
Item *item;
+ bool allow_subselect= true;
while ((item= li++))
{
if (item->type() == Item::FUNC_ITEM &&
check_equality_for_exist2in((Item_func *)item,
+ allow_subselect,
&element.local_field,
&element.outer_exp))
{
found= TRUE;
+ allow_subselect= false;
element.eq_ref= li.ref();
if (result.append(element))
goto alloc_err;
@@ -2912,6 +2927,7 @@ static bool find_inner_outer_equalities(Item **conds,
}
else if ((*conds)->type() == Item::FUNC_ITEM &&
check_equality_for_exist2in((Item_func *)*conds,
+ true,
&element.local_field,
&element.outer_exp))
{
@@ -3278,7 +3294,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join)
/*
In some optimisation cases we will not need this Item_in_optimizer
object, but we can't know it here, but here we need address correct
- reference on left expresion.
+ reference on left expression.
note: we won't need Item_in_optimizer when handling degenerate cases
like "... IN (SELECT 1)"
@@ -3310,7 +3326,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join)
and all that items do not make permanent changes in current item arena
which allow to us call them with changed arena (if we do not know nature
of Item, we have to call fix_fields() for it only with original arena to
- avoid memory leack)
+ avoid memory leak)
*/
if (left_expr->cols() == 1)
trans_res= single_value_transformer(join);
@@ -3473,7 +3489,7 @@ bool Item_in_subselect::setup_mat_engine()
/*
The select_engine (that executes transformed IN=>EXISTS subselects) is
- pre-created at parse time, and is stored in statment memory (preserved
+ pre-created at parse time, and is stored in statement memory (preserved
across PS executions).
*/
DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE);
@@ -3941,7 +3957,7 @@ int subselect_single_select_engine::exec()
For at least one of the pushed predicates the following is true:
We should not apply optimizations based on the condition that was
pushed down into the subquery. Those optimizations are ref[_or_null]
- acceses. Change them to be full table scans.
+ accesses. Change them to be full table scans.
*/
JOIN_TAB *tab;
for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
@@ -6177,7 +6193,7 @@ int subselect_partial_match_engine::exec()
if (has_covering_null_row)
{
/*
- If there is a NULL-only row that coveres all columns the result of IN
+ If there is a NULL-only row that covers all columns the result of IN
is UNKNOWN.
*/
item_in->value= 0;
@@ -6373,7 +6389,7 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
for (uint i= (non_null_key ? 1 : 0); i < merge_keys_count; i++)
{
/*
- Check if the first and only indexed column contains NULL in the curent
+ Check if the first and only indexed column contains NULL in the current
row, and add the row number to the corresponding key.
*/
if (merge_keys[i]->get_field(0)->is_null())
@@ -6585,7 +6601,7 @@ bool subselect_rowid_merge_engine::partial_match()
}
/*
- If all nullable columns contain only NULLs, then there is a guranteed
+ If all nullable columns contain only NULLs, then there is a guaranteed
partial match, and we don't need to search for a matching row.
*/
if (has_covering_null_columns)
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index b4b278083fc..b5823dfb194 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -571,7 +571,7 @@ public:
bool jtbm_const_row_found;
/*
- TRUE<=>this is a flattenable semi-join, false overwise.
+ TRUE<=>this is a flattenable semi-join, false otherwise.
*/
bool is_flattenable_semijoin;
@@ -1006,7 +1006,7 @@ class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
bool check_null;
/*
- The "having" clause. This clause (further reffered to as "artificial
+ The "having" clause. This clause (further referred to as "artificial
having") was inserted by subquery transformation code. It contains
Item(s) that have a side-effect: they record whether the subquery has
produced a row with NULL certain components. We need to use it for cases
@@ -1027,7 +1027,7 @@ class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
However, subqueries like the above are currently not handled by index
lookup-based subquery engines, the engine applicability check misses
them: it doesn't switch the engine for case of artificial having and
- [eq_]ref access (only for artifical having + ref_or_null or no having).
+ [eq_]ref access (only for artificial having + ref_or_null or no having).
The above example subquery is handled as a full-blown SELECT with eq_ref
access to one table.
@@ -1098,7 +1098,7 @@ public:
*/
JOIN *materialize_join;
/*
- A conjunction of all the equality condtions between all pairs of expressions
+ A conjunction of all the equality conditions between all pairs of expressions
that are arguments of an IN predicate. We need these to post-filter some
IN results because index lookups sometimes match values that are actually
not equal to the search key in SQL terms.
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 5573cc132f0..4a94169c6f8 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -705,7 +705,7 @@ int Aggregator_distinct::composite_key_cmp(void* arg, uchar* key1, uchar* key2)
C_MODE_START
-/* Declarations for auxilary C-callbacks */
+/* Declarations for auxiliary C-callbacks */
int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
{
@@ -737,7 +737,7 @@ C_MODE_END
@param thd Thread descriptor
@return status
@retval FALSE success
- @retval TRUE faliure
+ @retval TRUE failure
Prepares Aggregator_distinct to process the incoming stream.
Creates the temporary table and the Unique class if needed.
@@ -1942,7 +1942,7 @@ void Item_sum_count::cleanup()
/*
- Avgerage
+ Average
*/
void Item_sum_avg::fix_length_and_dec_decimal()
@@ -2208,7 +2208,7 @@ bool Item_sum_variance::fix_length_and_dec()
/*
According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
aggregate function; paragraph 7h of Syntax Rules), "the declared
- type of the result is an implementation-defined aproximate numeric
+ type of the result is an implementation-defined approximate numeric
type.
*/
if (args[0]->type_handler()->Item_sum_variance_fix_length_and_dec(this))
@@ -2283,7 +2283,7 @@ double Item_sum_variance::val_real()
is one or zero. If it's zero, i.e. a population variance, then we only
set nullness when the count is zero.
- Another way to read it is that 'sample' is the numerical threshhold, at and
+ Another way to read it is that 'sample' is the numerical threshold, at and
below which a 'count' number of items is called NULL.
*/
DBUG_ASSERT((sample == 0) || (sample == 1));
@@ -4336,7 +4336,7 @@ bool Item_func_group_concat::setup(THD *thd)
{
/*
Force the create_tmp_table() to convert BIT columns to INT
- as we cannot compare two table records containg BIT fields
+ as we cannot compare two table records containing BIT fields
stored in the the tree used for distinct/order by.
Moreover we don't even save in the tree record null bits
where BIT fields store parts of their data.
diff --git a/sql/item_sum.h b/sql/item_sum.h
index dc520ce2578..7dd4d0bd391 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -251,7 +251,7 @@ class Window_spec;
The field 'aggr_level' is to contain the nest level of the subquery
where the set function is aggregated.
- The field 'max_arg_level' is for the maximun of the nest levels of the
+ The field 'max_arg_level' is for the maximum of the nest levels of the
unbound column references occurred in the set function. A column reference
is unbound within a set function if it is not bound by any subquery
used as a subexpression in this function. A column reference is bound by
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 7bc34ee688c..052b11f8b04 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -471,7 +471,7 @@ err:
/**
- Create a formated date/time value in a string.
+ Create a formatted date/time value in a string.
*/
static bool make_date_time(String *format, MYSQL_TIME *l_time,
@@ -1048,7 +1048,7 @@ uint week_mode(uint mode)
a date at start of january) In this case one can get 53 for the
first week of next year. This flag ensures that the week is
relevant for the given year. Note that this flag is only
- releveant if WEEK_JANUARY is not set.
+ relevant if WEEK_JANUARY is not set.
If set Week is in range 1-53.
@@ -1350,7 +1350,7 @@ bool get_interval_value(THD *thd, Item *args,
if (!(res= args->val_str_ascii(&str_value)))
return (1);
- /* record negative intervalls in interval->neg */
+ /* record negative intervals in interval->neg */
str=res->ptr();
cs= res->charset();
const char *end=str+res->length();
@@ -1493,7 +1493,7 @@ bool Item_func_from_days::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzz
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole CURDATE function.
*/
void Item_func_curdate_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1504,7 +1504,7 @@ void Item_func_curdate_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME representation for UTC
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
*/
void Item_func_curdate_utc::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1582,7 +1582,7 @@ static void set_sec_part(ulong sec_part, MYSQL_TIME *ltime, Item *item)
}
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole CURTIME function.
*/
void Item_func_curtime_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1596,7 +1596,7 @@ void Item_func_curtime_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME representation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
*/
void Item_func_curtime_utc::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1650,7 +1650,7 @@ int Item_func_now_local::save_in_field(Field *field, bool no_conversions)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole NOW function.
*/
void Item_func_now_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1662,7 +1662,7 @@ void Item_func_now_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME representation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
*/
void Item_func_now_utc::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1692,7 +1692,7 @@ bool Item_func_now::get_date(THD *thd, MYSQL_TIME *res,
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole SYSDATE function.
*/
void Item_func_sysdate_local::store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)
@@ -1982,7 +1982,7 @@ bool Item_func_convert_tz::get_date(THD *thd, MYSQL_TIME *ltime,
uint not_used;
my_time_tmp= from_tz->TIME_to_gmt_sec(ltime, &not_used);
ulong sec_part= ltime->second_part;
- /* my_time_tmp is guranteed to be in the allowed range */
+ /* my_time_tmp is guaranteed to be in the allowed range */
if (my_time_tmp)
to_tz->gmt_sec_to_TIME(ltime, my_time_tmp);
/* we rely on the fact that no timezone conversion can change sec_part */
@@ -2500,7 +2500,7 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
uint32 char_length;
/*
We always force character set conversion if cast_cs
- is a multi-byte character set. It garantees that the
+ is a multi-byte character set. It guarantees that the
result of CAST is a well-formed string.
For single-byte character sets we allow just to copy
from the argument. A single-byte character sets string
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 4e7757f71db..6e863b1ffef 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -62,7 +62,7 @@ typedef struct my_xml_node_st
} MY_XML_NODE;
-/* Lexical analizer token */
+/* Lexical analyzer token */
typedef struct my_xpath_lex_st
{
int term; /* token type, see MY_XPATH_LEX_XXXXX below */
@@ -1074,7 +1074,7 @@ static Item* nametestfunc(MY_XPATH *xpath,
/*
- Tokens consisting of one character, for faster lexical analizer.
+ Tokens consisting of one character, for faster lexical analyzer.
*/
static char simpletok[128]=
{
@@ -1394,7 +1394,7 @@ my_xpath_function(const char *beg, const char *end)
}
-/* Initialize a lex analizer token */
+/* Initialize a lex analyzer token */
static void
my_xpath_lex_init(MY_XPATH_LEX *lex,
const char *str, const char *strend)
@@ -1425,7 +1425,7 @@ my_xdigit(int c)
SYNOPSYS
Scan the next token from the input.
lex->term is set to the scanned token type.
- lex->beg and lex->end are set to the beginnig
+ lex->beg and lex->end are set to the beginning
and to the end of the token.
RETURN
N/A
@@ -1451,7 +1451,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
(const uchar*) end)) > 0 &&
((ctype & (_MY_L | _MY_U)) || *beg == '_'))
{
- // scan untill the end of the idenfitier
+ // scan until the end of the identifier
for (beg+= length;
(length= xpath->cs->ctype(&ctype,
(const uchar*) beg,
@@ -1580,7 +1580,7 @@ static int my_xpath_parse_AxisName(MY_XPATH *xpath)
** Grammar rules, according to http://www.w3.org/TR/xpath
** Implemented using recursive descendant method.
** All the following grammar processing functions accept
-** a signle "xpath" argument and return 1 on success and 0 on error.
+** a single "xpath" argument and return 1 on success and 0 on error.
** They also modify "xpath" argument by creating new items.
*/
@@ -2476,7 +2476,7 @@ public:
as it is in conflict with abbreviated step.
1 + .123 does not work,
1 + 0.123 does.
- Perhaps it is better to move this code into lex analizer.
+ Perhaps it is better to move this code into lex analyzer.
RETURN
1 - success
@@ -2831,7 +2831,7 @@ append_node(String *str, MY_XML_NODE *node)
SYNOPSYS
A call-back function executed when XML parser
- is entering a tag or an attribue.
+ is entering a tag or an attribute.
Appends the new node into data->pxml.
Increments data->level.
@@ -2867,7 +2867,7 @@ int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len)
SYNOPSYS
A call-back function executed when XML parser
- is entering into a tag or an attribue textual value.
+ is entering into a tag or an attribute textual value.
The value is appended into data->pxml.
RETURN
@@ -2895,7 +2895,7 @@ int xml_value(MY_XML_PARSER *st,const char *attr, size_t len)
SYNOPSYS
A call-back function executed when XML parser
- is leaving a tag or an attribue.
+ is leaving a tag or an attribute.
Decrements data->level.
RETURN
diff --git a/sql/key.cc b/sql/key.cc
index 0f2af60f9e3..8701d7b8053 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -229,7 +229,7 @@ void key_restore(uchar *to_record, const uchar *from_key, KEY *key_info,
{
/*
This in fact never happens, as we have only partial BLOB
- keys yet anyway, so it's difficult to find any sence to
+ keys yet anyway, so it's difficult to find any sense to
restore the part of a record.
Maybe this branch is to be removed, but now we
have to ignore GCov compaining.
@@ -611,8 +611,8 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec)
max length. The exceptions are the BLOB and VARCHAR field types
that take the max length into account.
*/
- if ((result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
- key_part->length)))
+ if ((result= field->cmp_prefix(field->ptr+first_diff, field->ptr+sec_diff,
+ key_part->length)))
DBUG_RETURN(result);
next_loop:
key_part++;
diff --git a/sql/lock.cc b/sql/lock.cc
index b7bf4eb4f63..ff215795604 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1166,7 +1166,7 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
{
DBUG_ENTER("make_global_read_lock_block_commit");
/*
- If we didn't succeed lock_global_read_lock(), or if we already suceeded
+ If we didn't succeed lock_global_read_lock(), or if we already succeeded
make_global_read_lock_block_commit(), do nothing.
*/
diff --git a/sql/log.cc b/sql/log.cc
index 0bfe7d7ee8b..2a887a68606 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -167,7 +167,7 @@ void setup_log_handling()
/**
purge logs, master and slave sides both, related error code
- convertor.
+ converter.
Called from @c purge_error_message(), @c MYSQL_BIN_LOG::reset_logs()
@param res an internal to purging routines error code
@@ -386,7 +386,7 @@ public:
never zero.
This is done while calling the constructor binlog_cache_mngr.
- We cannot set informaton in the constructor binlog_cache_data
+ We cannot set information in the constructor binlog_cache_data
because the space for binlog_cache_mngr is allocated through
a placement new.
@@ -3161,7 +3161,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
mysql_mutex_lock(&LOCK_log);
if (is_open())
- { // Safety agains reopen
+ { // Safety against reopen
char buff[80], *end;
char query_time_buff[22+7], lock_time_buff[22+7];
size_t buff_len;
@@ -3460,7 +3460,7 @@ void MYSQL_BIN_LOG::cleanup()
/*
Free data for global binlog state.
- We can't do that automaticly as we need to do this before
+ We can't do that automatically as we need to do this before
safemalloc is shut down
*/
if (!is_relay_log)
@@ -4234,7 +4234,7 @@ err:
/**
- Delete all logs refered to in the index file.
+ Delete all logs referred to in the index file.
The new index file will only contain this file.
@@ -5771,7 +5771,7 @@ binlog_cache_mngr *THD::binlog_setup_trx_data()
- Start a statement transaction to allow us to truncate the cache.
- - Save the currrent binlog position so that we can roll back the
+ - Save the current binlog position so that we can roll back the
statement by truncating the cache.
We only update the saved position if the old one was undefined,
@@ -7064,7 +7064,7 @@ static const char* get_first_binlog(char* buf_arg)
}
if (normalize_binlog_name(buf_arg, fname, false))
{
- errmsg= "cound not normalize the first file name in the binlog index";
+ errmsg= "could not normalize the first file name in the binlog index";
goto end;
}
end:
@@ -10063,7 +10063,7 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
than compare all found against each other to find the one pointing to the
most recent binlog.
- Note also that we need to first release LOCK_xid_list, then aquire
+ Note also that we need to first release LOCK_xid_list, then acquire
LOCK_log, then re-aquire LOCK_xid_list. If we were to take LOCK_log while
holding LOCK_xid_list, we might deadlock with other threads that take the
locks in the opposite order.
@@ -10205,7 +10205,7 @@ TC_LOG_BINLOG::commit_checkpoint_notify(void *cookie)
necessary stuff.
In the future, this thread could also be used to do log rotation in the
- background, which could elimiate all stalls around binlog rotations.
+ background, which could eliminate all stalls around binlog rotations.
*/
pthread_handler_t
binlog_background_thread(void *arg __attribute__((unused)))
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d5ec2060c02..d66ece96eba 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2735,7 +2735,7 @@ Intvar_log_event::Intvar_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- /* The Post-Header is empty. The Varible Data part begins immediately. */
+ /* The Post-Header is empty. The Variable Data part begins immediately. */
buf+= description_event->common_header_len +
description_event->post_header_len[INTVAR_EVENT-1];
type= buf[I_TYPE_OFFSET];
@@ -3284,7 +3284,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
DBUG_VOID_RETURN;
}
- /* if my_bitmap_init fails, catched in is_valid() */
+ /* if my_bitmap_init fails, caught in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
m_width,
diff --git a/sql/log_event.h b/sql/log_event.h
index b515036c5e8..5e110dbd3fd 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -461,7 +461,7 @@ class String;
/**
@def LOG_EVENT_ARTIFICIAL_F
- Artificial events are created arbitarily and not written to binary
+ Artificial events are created arbitrarily and not written to binary
log
These events should not update the master log position when slave
@@ -975,13 +975,13 @@ private:
};
/**
- the struct aggregates two paramenters that identify an event
+ the struct aggregates two parameters that identify an event
uniquely in scope of communication of a particular master and slave couple.
I.e there can not be 2 events from the same staying connected master which
have the same coordinates.
@note
Such identifier is not yet unique generally as the event originating master
- is resetable. Also the crashed master can be replaced with some other.
+ is resettable. Also the crashed master can be replaced with some other.
*/
typedef struct event_coordinates
{
@@ -2798,7 +2798,7 @@ public:
uint8 number_of_event_types;
/*
The list of post-headers' lengths followed
- by the checksum alg decription byte
+ by the checksum alg description byte
*/
uint8 *post_header_len;
class master_version_split: public Version {
@@ -3324,7 +3324,7 @@ public:
*/
bool is_deferred() { return deferred; }
/*
- In case of the deffered applying the variable instance is flagged
+ In case of the deferred applying the variable instance is flagged
and the parsing time query id is stored to be used at applying time.
*/
void set_deferred(query_id_t qid) { deferred= true; query_id= qid; }
@@ -5520,7 +5520,7 @@ private:
/**
@class Incident_log_event
- Class representing an incident, an occurance out of the ordinary,
+ Class representing an incident, an occurence out of the ordinary,
that happened on the master.
The event is used to inform the slave that something out of the
@@ -5564,7 +5564,7 @@ public:
m_message.str= NULL; /* Just as a precaution */
m_message.length= 0;
set_direct_logging();
- /* Replicate the incident irregardless of @@skip_replication. */
+ /* Replicate the incident regardless of @@skip_replication. */
flags&= ~LOG_EVENT_SKIP_REPLICATION_F;
DBUG_VOID_RETURN;
}
@@ -5586,7 +5586,7 @@ public:
strmake(m_message.str, msg->str, msg->length);
m_message.length= msg->length;
set_direct_logging();
- /* Replicate the incident irregardless of @@skip_replication. */
+ /* Replicate the incident regardless of @@skip_replication. */
flags&= ~LOG_EVENT_SKIP_REPLICATION_F;
DBUG_VOID_RETURN;
}
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index c6ccfc5a2c0..f02f74ca093 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1229,7 +1229,7 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len,
DBUG_VOID_RETURN;
}
- /* if my_bitmap_init fails, catched in is_valid() */
+ /* if my_bitmap_init fails, caught in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
m_width,
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index c12573f817f..72347d93ad1 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -396,13 +396,14 @@ do_gco_wait(rpl_group_info *rgi, group_commit_orderer *gco,
}
-static void
+static bool
do_ftwrl_wait(rpl_group_info *rgi,
bool *did_enter_cond, PSI_stage_info *old_stage)
{
THD *thd= rgi->thd;
rpl_parallel_entry *entry= rgi->parallel_entry;
uint64 sub_id= rgi->gtid_sub_id;
+ bool aborted= false;
DBUG_ENTER("do_ftwrl_wait");
mysql_mutex_assert_owner(&entry->LOCK_parallel_entry);
@@ -425,7 +426,10 @@ do_ftwrl_wait(rpl_group_info *rgi,
do
{
if (entry->force_abort || rgi->worker_error)
+ {
+ aborted= true;
break;
+ }
if (unlikely(thd->check_killed()))
{
slave_output_error_info(rgi, thd);
@@ -444,7 +448,7 @@ do_ftwrl_wait(rpl_group_info *rgi,
if (sub_id > entry->largest_started_sub_id)
entry->largest_started_sub_id= sub_id;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(aborted);
}
@@ -530,7 +534,22 @@ rpl_unpause_after_ftwrl(THD *thd)
mysql_mutex_lock(&e->LOCK_parallel_entry);
rpt->pause_for_ftwrl = false;
mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
- e->pause_sub_id= (uint64)ULONGLONG_MAX;
+ /*
+ Do not change pause_sub_id if force_abort is set.
+ force_abort is set in case of STOP SLAVE.
+
+ Reason: If pause_sub_id is not changed and force_abort_is set,
+ any parallel slave thread waiting in do_ftwrl_wait() will
+ on wakeup return from do_ftwrl_wait() with 1. This will set
+ skip_event_group to 1 in handle_rpl_parallel_thread() and the
+ parallel thread will abort at once.
+
+ If pause_sub_id is changed, the code in handle_rpl_parallel_thread()
+ would continue to execute the transaction in the queue, which would
+ cause some transactions to be lost.
+ */
+ if (!e->force_abort)
+ e->pause_sub_id= (uint64)ULONGLONG_MAX;
mysql_cond_broadcast(&e->COND_parallel_entry);
mysql_mutex_unlock(&e->LOCK_parallel_entry);
}
@@ -1224,7 +1243,7 @@ handle_rpl_parallel_thread(void *arg)
rgi->worker_error= 1;
}
if (likely(!skip_event_group))
- do_ftwrl_wait(rgi, &did_enter_cond, &old_stage);
+ skip_event_group= do_ftwrl_wait(rgi, &did_enter_cond, &old_stage);
/*
Register ourself to wait for the previous commit, if we need to do
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 9cc35d0707f..161ffc66641 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -4516,7 +4516,11 @@ static int replace_user_table(THD *thd, const User_table &user_table,
{
if (revoke_grant)
{
- my_error(ER_NONEXISTING_GRANT, MYF(0), combo->user.str, combo->host.str);
+ if (combo->host.length)
+ my_error(ER_NONEXISTING_GRANT, MYF(0), combo->user.str,
+ combo->host.str);
+ else
+ my_error(ER_INVALID_ROLE, MYF(0), combo->user.str);
goto end;
}
/*
@@ -6044,6 +6048,8 @@ static void propagate_role_grants(ACL_ROLE *role,
enum PRIVS_TO_MERGE::what what,
const char *db= 0, const char *name= 0)
{
+ if (!role)
+ return;
mysql_mutex_assert_owner(&acl_cache->lock);
PRIVS_TO_MERGE data= { what, db, name };
@@ -8229,6 +8235,21 @@ err:
}
+static void check_grant_column_int(GRANT_TABLE *grant_table, const char *name,
+ uint length, privilege_t *want_access)
+{
+ if (grant_table)
+ {
+ *want_access&= ~grant_table->privs;
+ if (*want_access & grant_table->cols)
+ {
+ GRANT_COLUMN *grant_column= column_hash_search(grant_table, name, length);
+ if (grant_column)
+ *want_access&= ~grant_column->rights;
+ }
+ }
+}
+
/*
Check column rights in given security context
@@ -8251,9 +8272,6 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name,
const char *name, size_t length, Security_context *sctx)
{
- GRANT_TABLE *grant_table;
- GRANT_TABLE *grant_table_role;
- GRANT_COLUMN *grant_column;
privilege_t want_access(grant->want_privilege & ~grant->privilege);
DBUG_ENTER("check_grant_column");
DBUG_PRINT("enter", ("table: %s want_access: %llx",
@@ -8279,45 +8297,20 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
grant->version= grant_version; /* purecov: inspected */
}
- grant_table= grant->grant_table_user;
- grant_table_role= grant->grant_table_role;
-
- if (!grant_table && !grant_table_role)
- goto err;
+ check_grant_column_int(grant->grant_table_user, name, (uint)length,
+ &want_access);
+ check_grant_column_int(grant->grant_table_role, name, (uint)length,
+ &want_access);
- if (grant_table)
- {
- grant_column= column_hash_search(grant_table, name, length);
- if (grant_column)
- {
- want_access&= ~grant_column->rights;
- }
- }
- if (grant_table_role)
- {
- grant_column= column_hash_search(grant_table_role, name, length);
- if (grant_column)
- {
- want_access&= ~grant_column->rights;
- }
- }
+ mysql_rwlock_unlock(&LOCK_grant);
if (!want_access)
- {
- mysql_rwlock_unlock(&LOCK_grant);
DBUG_RETURN(0);
- }
-err:
- mysql_rwlock_unlock(&LOCK_grant);
char command[128];
get_privilege_desc(command, sizeof(command), want_access);
/* TODO perhaps error should print current rolename aswell */
- my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
- command,
- sctx->priv_user,
- sctx->host_or_ip,
- name,
- table_name);
+ my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), command, sctx->priv_user,
+ sctx->host_or_ip, name, table_name);
DBUG_RETURN(1);
}
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 71939936da0..dc9b971f2ed 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -768,8 +768,18 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
compl_result_code= result_code= HA_ADMIN_INVALID;
}
+
+ /*
+ The check for ALTER_PARTITION_ADMIN implements this logic:
+ do not collect EITS STATS for this syntax:
+ ALTER TABLE ... ANALYZE PARTITION p
+ EITS statistics is global (not per-partition). Collecting global stats
+ is much more expensive processing just one partition, so the most
+ appropriate action is to just not collect EITS stats for this command.
+ */
collect_eis=
(table->table->s->table_category == TABLE_CATEGORY_USER &&
+ !(lex->alter_info.flags & ALTER_PARTITION_ADMIN) &&
(check_eits_collection_allowed(thd) ||
lex->with_persistent_for_clause));
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 45ce4be3eb5..6a313616025 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1316,7 +1316,7 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
table->s->tdc->flush(thd, true);
/* extra() call must come only after all instances above are closed */
if (function != HA_EXTRA_NOT_USED)
- (void) table->file->extra(function);
+ DBUG_RETURN(table->file->extra(function));
DBUG_RETURN(FALSE);
}
@@ -7862,8 +7862,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
FALSE ok; In this case *map will include the chosen index
TRUE error
*/
-bool setup_tables_and_check_access(THD *thd,
- Name_resolution_context *context,
+bool setup_tables_and_check_access(THD *thd, Name_resolution_context *context,
List<TABLE_LIST> *from_clause,
TABLE_LIST *tables,
List<TABLE_LIST> &leaves,
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index af0035e9003..702acb623ae 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1226,10 +1226,8 @@ extern "C" my_thread_id next_thread_id_noinline()
#endif
-const Type_handler *THD::type_handler_for_date() const
+const Type_handler *THD::type_handler_for_datetime() const
{
- if (!(variables.sql_mode & MODE_ORACLE))
- return &type_handler_newdate;
if (opt_mysql56_temporal_format)
return &type_handler_datetime2;
return &type_handler_datetime;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index ab188c18735..b56de95cdd6 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3552,7 +3552,7 @@ public:
{
return !MY_TEST(variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES);
}
- const Type_handler *type_handler_for_date() const;
+ const Type_handler *type_handler_for_datetime() const;
bool timestamp_to_TIME(MYSQL_TIME *ltime, my_time_t ts,
ulong sec_part, date_mode_t fuzzydate);
inline my_time_t query_start() { return start_time; }
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index baec470c471..a65acc2c87e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -769,6 +769,7 @@ void
st_parsing_options::reset()
{
allows_variable= TRUE;
+ lookup_keywords_after_qualifier= false;
}
@@ -2144,7 +2145,10 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd)
yylval->lex_str.str= (char*) get_ptr();
yylval->lex_str.length= 1;
c= yyGet(); // should be '.'
- next_state= MY_LEX_IDENT_START; // Next is ident (not keyword)
+ if (lex->parsing_options.lookup_keywords_after_qualifier)
+ next_state= MY_LEX_IDENT_OR_KEYWORD;
+ else
+ next_state= MY_LEX_IDENT_START; // Next is ident (not keyword)
if (!ident_map[(uchar) yyPeek()]) // Probably ` or "
next_state= MY_LEX_START;
return((int) c);
@@ -4791,7 +4795,8 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
sl->options|= SELECT_DESCRIBE;
inner_join->select_options|= SELECT_DESCRIBE;
}
- res= inner_join->optimize();
+ if ((res= inner_join->optimize()))
+ return TRUE;
if (!inner_join->cleaned)
sl->update_used_tables();
sl->update_correlated_cache();
@@ -11446,3 +11451,25 @@ bool LEX::sp_create_set_password_instr(THD *thd,
sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
return sp_create_assignment_instr(thd, no_lookahead);
}
+
+
+bool LEX::map_data_type(const Lex_ident_sys_st &schema_name,
+ Lex_field_type_st *type) const
+{
+ const Schema *schema= schema_name.str ?
+ Schema::find_by_name(schema_name) :
+ Schema::find_implied(thd);
+ if (!schema)
+ {
+ char buf[128];
+ const Name type_name= type->type_handler()->name();
+ my_snprintf(buf, sizeof(buf), "%.*s.%.*s",
+ (int) schema_name.length, schema_name.str,
+ (int) type_name.length(), type_name.ptr());
+ my_error(ER_UNKNOWN_DATA_TYPE, MYF(0), buf);
+ return true;
+ }
+ const Type_handler *mapped= schema->map_data_type(thd, type->type_handler());
+ type->set_handler(mapped);
+ return false;
+}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 92d4ec42c8f..f516219c01a 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -34,6 +34,7 @@
#include "sql_tvc.h"
#include "item.h"
#include "sql_limit.h" // Select_limit_counters
+#include "sql_schema.h"
/* Used for flags of nesting constructs */
#define SELECT_NESTING_MAP_SIZE 64
@@ -2354,6 +2355,7 @@ private:
struct st_parsing_options
{
bool allows_variable;
+ bool lookup_keywords_after_qualifier;
st_parsing_options() { reset(); }
void reset();
@@ -4671,6 +4673,9 @@ public:
bool set_cast_type_udt(Lex_cast_type_st *type,
const LEX_CSTRING &name);
+ bool map_data_type(const Lex_ident_sys_st &schema,
+ Lex_field_type_st *type) const;
+
void mark_first_table_as_inserting();
bool add_table_foreign_key(const LEX_CSTRING *name,
diff --git a/sql/sql_schema.cc b/sql/sql_schema.cc
new file mode 100644
index 00000000000..0bf4a63c2f8
--- /dev/null
+++ b/sql/sql_schema.cc
@@ -0,0 +1,80 @@
+/*
+ Copyright (c) 2020, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include "mariadb.h"
+#include "sql_type.h"
+#include "sql_schema.h"
+#include "sql_class.h"
+
+class Schema_oracle: public Schema
+{
+public:
+ Schema_oracle(const LEX_CSTRING &name)
+ :Schema(name)
+ { }
+ const Type_handler *map_data_type(THD *thd, const Type_handler *src)
+ const
+ {
+ if (src == &type_handler_newdate)
+ return thd->type_handler_for_datetime();
+ return src;
+ }
+};
+
+
+class Schema_maxdb: public Schema
+{
+public:
+ Schema_maxdb(const LEX_CSTRING &name)
+ :Schema(name)
+ { }
+ const Type_handler *map_data_type(THD *thd, const Type_handler *src)
+ const
+ {
+ if (src == &type_handler_timestamp ||
+ src == &type_handler_timestamp2)
+ return thd->type_handler_for_datetime();
+ return src;
+ }
+};
+
+
+Schema mariadb_schema(Lex_cstring(STRING_WITH_LEN("mariadb_schema")));
+Schema_oracle oracle_schema(Lex_cstring(STRING_WITH_LEN("oracle_schema")));
+Schema_maxdb maxdb_schema(Lex_cstring(STRING_WITH_LEN("maxdb_schema")));
+
+
+Schema *Schema::find_by_name(const LEX_CSTRING &name)
+{
+ DBUG_ASSERT(name.str);
+ if (mariadb_schema.eq_name(name))
+ return &mariadb_schema;
+ if (oracle_schema.eq_name(name))
+ return &oracle_schema;
+ if (maxdb_schema.eq_name(name))
+ return &maxdb_schema;
+ return NULL;
+}
+
+
+Schema *Schema::find_implied(THD *thd)
+{
+ if (thd->variables.sql_mode & MODE_ORACLE)
+ return &oracle_schema;
+ if (thd->variables.sql_mode & MODE_MAXDB)
+ return &maxdb_schema;
+ return &mariadb_schema;
+}
diff --git a/sql/sql_schema.h b/sql/sql_schema.h
new file mode 100644
index 00000000000..886a115cbc5
--- /dev/null
+++ b/sql/sql_schema.h
@@ -0,0 +1,60 @@
+#ifndef SQL_SCHEMA_H_INCLUDED
+#define SQL_SCHEMA_H_INCLUDED
+/*
+ Copyright (c) 2020, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include "mysqld.h"
+#include "lex_string.h"
+
+class Schema
+{
+ LEX_CSTRING m_name;
+public:
+ Schema(const LEX_CSTRING &name)
+ :m_name(name)
+ { }
+ virtual ~Schema() { }
+ const LEX_CSTRING &name() const { return m_name; }
+ virtual const Type_handler *map_data_type(THD *thd, const Type_handler *src)
+ const
+ {
+ return src;
+ }
+ /*
+ For now we have *hard-coded* compatibility schemas:
+ schema_mariadb, schema_oracle, schema_maxdb.
+ But eventually we'll turn then into real databases on disk.
+ So the code below compares names according to the filesystem
+ case sensitivity, like it is done for regular databases.
+
+ Note, this is different to information_schema, whose name
+ is always case insensitive. This is intentional!
+ The assymetry will be gone when we'll implement SQL standard
+ regular and delimited identifiers.
+ */
+ bool eq_name(const LEX_CSTRING &name) const
+ {
+ return !table_alias_charset->strnncoll(m_name.str, m_name.length,
+ name.str, name.length);
+ }
+ static Schema *find_by_name(const LEX_CSTRING &name);
+ static Schema *find_implied(THD *thd);
+};
+
+
+extern Schema mariadb_schema;
+
+#endif // SQL_SCHEMA_H_INCLUDED
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 79689c78925..b0c4db47494 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1552,7 +1552,6 @@ err:
bool JOIN::build_explain()
{
DBUG_ENTER("JOIN::build_explain");
- create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE;
/*
@@ -1594,6 +1593,7 @@ bool JOIN::build_explain()
int JOIN::optimize()
{
int res= 0;
+ create_explain_query_if_not_exists(thd->lex, thd->mem_root);
join_optimization_state init_state= optimization_state;
if (select_lex->pushdown_select)
{
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 77ebc58bc02..6dd013d929e 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2149,6 +2149,13 @@ int show_create_table_ex(THD *thd, TABLE_LIST *table_list,
append_identifier(thd, packet, &field->field_name);
packet->append(' ');
+ const Type_handler *th= field->type_handler();
+ const Schema *implied_schema= Schema::find_implied(thd);
+ if (th != implied_schema->map_data_type(thd, th))
+ {
+ packet->append(th->schema()->name(), system_charset_info);
+ packet->append(STRING_WITH_LEN("."), system_charset_info);
+ }
type.set(tmp, sizeof(tmp), system_charset_info);
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index bce65e494d3..593062646ce 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -186,6 +186,12 @@ bool Type_handler_data::init()
}
+Schema *Type_handler::schema() const
+{
+ return &mariadb_schema;
+}
+
+
const Type_handler *
Type_handler::handler_by_name(THD *thd, const LEX_CSTRING &name)
{
@@ -4134,6 +4140,19 @@ void Type_handler_temporal_with_date::Item_update_null_value(Item *item) const
(void) item->get_date(thd, &ltime, Datetime::Options(thd));
}
+bool
+Type_handler_timestamp_common::
+Column_definition_set_attributes(THD *thd,
+ Column_definition *def,
+ const Lex_field_type_st &attr,
+ CHARSET_INFO *cs,
+ column_definition_type_t type) const
+{
+ Type_handler::Column_definition_set_attributes(thd, def, attr, cs, type);
+ if (!opt_explicit_defaults_for_timestamp)
+ def->flags|= NOT_NULL_FLAG;
+ return false;
+}
void Type_handler_string_result::Item_update_null_value(Item *item) const
{
@@ -6165,7 +6184,8 @@ bool Type_handler_row::
bool Type_handler_int_result::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
- item->fix_arg_int(this, item->arguments()[0]);
+ item->fix_arg_int(this, item->arguments()[0],
+ field_type() == MYSQL_TYPE_LONGLONG);
return false;
}
@@ -6173,7 +6193,7 @@ bool Type_handler_int_result::
bool Type_handler_year::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
- item->fix_arg_int(&type_handler_ulong, item->arguments()[0]);
+ item->fix_arg_int(&type_handler_ulong, item->arguments()[0], false);
return false;
}
@@ -6181,7 +6201,7 @@ bool Type_handler_year::
bool Type_handler_hex_hybrid::
Item_func_round_fix_length_and_dec(Item_func_round *item) const
{
- item->fix_arg_int(nullptr, nullptr);
+ item->fix_arg_hex_hybrid();
return false;
}
@@ -6224,7 +6244,7 @@ bool Type_handler_date_common::
{
static const Type_std_attributes attr(Type_numeric_attributes(8, 0, true),
DTCollation_numeric());
- item->fix_arg_int(&type_handler_ulong, &attr);
+ item->fix_arg_int(&type_handler_ulong, &attr, false);
return false;
}
diff --git a/sql/sql_type.h b/sql/sql_type.h
index ed0aaaea400..02abd55680d 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -1430,6 +1430,8 @@ public:
}
};
+class Schema;
+
/**
Class Time is designed to store valid TIME values.
@@ -3507,6 +3509,7 @@ public:
static const
Type_handler *aggregate_for_result_traditional(const Type_handler *h1,
const Type_handler *h2);
+ virtual Schema *schema() const;
static void partition_field_type_not_allowed(const LEX_CSTRING &field_name);
static bool partition_field_check_result_type(Item *item,
Item_result expected_type);
@@ -6452,6 +6455,12 @@ public:
bool Item_func_min_max_get_date(THD *thd, Item_func_min_max*,
MYSQL_TIME *, date_mode_t fuzzydate)
const override;
+ bool Column_definition_set_attributes(THD *thd,
+ Column_definition *def,
+ const Lex_field_type_st &attr,
+ CHARSET_INFO *cs,
+ column_definition_type_t type)
+ const override;
};
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b42d68c26e1..b472dfd4939 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1353,6 +1353,7 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <sp_handler> sp_handler
%type <Lex_field_type> type_with_opt_collate field_type
+ qualified_field_type
field_type_numeric
field_type_string
field_type_lob
@@ -5965,10 +5966,12 @@ field_spec:
lex->init_last_field(f, &$1, NULL);
$<create_field>$= f;
+ lex->parsing_options.lookup_keywords_after_qualifier= true;
}
field_type_or_serial opt_check_constraint
{
LEX *lex=Lex;
+ lex->parsing_options.lookup_keywords_after_qualifier= false;
$$= $<create_field>2;
$$->check_constraint= $4;
@@ -5987,7 +5990,7 @@ field_spec:
;
field_type_or_serial:
- field_type
+ qualified_field_type
{
Lex->last_field->set_attributes(thd, $1, Lex->charset,
COLUMN_DEFINITION_TABLE_FIELD);
@@ -6164,6 +6167,18 @@ column_default_expr:
}
;
+qualified_field_type:
+ field_type
+ {
+ Lex->map_data_type(Lex_ident_sys(), &($$= $1));
+ }
+ | sp_decl_ident '.' field_type
+ {
+ if (Lex->map_data_type($1, &($$= $3)))
+ MYSQL_YYABORT;
+ }
+ ;
+
field_type:
field_type_numeric
| field_type_temporal
@@ -6303,7 +6318,7 @@ field_type_temporal:
}
$$.set(&type_handler_year, $2);
}
- | DATE_SYM { $$.set(thd->type_handler_for_date()); }
+ | DATE_SYM { $$.set(&type_handler_newdate); }
| TIME_SYM opt_field_length
{
$$.set(opt_mysql56_temporal_format ?
@@ -6313,31 +6328,14 @@ field_type_temporal:
}
| TIMESTAMP opt_field_length
{
- if (thd->variables.sql_mode & MODE_MAXDB)
- $$.set(opt_mysql56_temporal_format ?
- static_cast<const Type_handler*>(&type_handler_datetime2) :
- static_cast<const Type_handler*>(&type_handler_datetime),
- $2);
- else
- {
- /*
- Unlike other types TIMESTAMP fields are NOT NULL by default.
- Unless --explicit-defaults-for-timestamp is given.
- */
- if (!opt_explicit_defaults_for_timestamp)
- Lex->last_field->flags|= NOT_NULL_FLAG;
- $$.set(opt_mysql56_temporal_format ?
- static_cast<const Type_handler*>(&type_handler_timestamp2):
- static_cast<const Type_handler*>(&type_handler_timestamp),
- $2);
- }
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_timestamp2):
+ static_cast<const Type_handler*>(&type_handler_timestamp),
+ $2);
}
| DATETIME opt_field_length
{
- $$.set(opt_mysql56_temporal_format ?
- static_cast<const Type_handler*>(&type_handler_datetime2) :
- static_cast<const Type_handler*>(&type_handler_datetime),
- $2);
+ $$.set(thd->type_handler_for_datetime(), $2);
}
;
@@ -6642,7 +6640,7 @@ with_or_without_system:
type_with_opt_collate:
field_type opt_collate
{
- $$= $1;
+ Lex->map_data_type(Lex_ident_sys(), &($$= $1));
if ($2)
{
diff --git a/sql/structs.h b/sql/structs.h
index 0993c453e16..27acb9e200e 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -629,6 +629,10 @@ public:
{
set(handler, 0, 0);
}
+ void set_handler(const Type_handler *handler)
+ {
+ m_handler= handler;
+ }
const Type_handler *type_handler() const { return m_handler; }
};
diff --git a/sql/table.cc b/sql/table.cc
index e4ed862f41b..6f0aa8d3418 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8800,7 +8800,8 @@ bool TABLE::check_period_overlaps(const KEY &key,
if (f->is_null_in_record(lhs) || f->is_null_in_record(rhs))
return false;
uint kp_len= key.key_part[part_nr].length;
- if (f->cmp_max(f->ptr_in_record(lhs), f->ptr_in_record(rhs), kp_len) != 0)
+ if (f->cmp_prefix(f->ptr_in_record(lhs), f->ptr_in_record(rhs),
+ kp_len) != 0)
return false;
}