Fixing the data type for the "fuzzydate" parameter to
Item_func_hybrid_field_type::date_op() from uint to ulonglong,
for consistency with Item::get_date().
- Implementing stricter data type control for Item_long_func descendants
- Cleanup: renaming Type_handler::can_return_str_ascii() to can_return_text()
(a better name).
make insert NULL into a timestamp mark the field as having an
explicit value. So that the field won't be assigned the value
again in TABLE::update_default_field()
make Item_func_now_local::save_in_field(timestamp_field) not to go
through MYSQL_TIME - this conversion is lossy around DST change times.
This fixes inserting a default value into a timestamp field.
This is a joint patch fixing the following problems:
MDEV-12875 Wrong VIEW column data type for COALESCE(int_column)
MDEV-12886 Different default for INT and BIGINT column in a VIEW for a SELECT with ROLLUP
MDEV-12916 Wrong column data type for an INT field of a cursor-anchored ROW variable
All above problem happened because the global function ::create_tmp_field()
called the top-level Item::create_tmp_field(), which made some tranformation
for INT-result data types. For example, INT(11) became BIGINT(11), because 11
is a corner case and it's not known if it fits or does not fit into INT range,
so Item::create_tmp_field() converted it to BIGINT(11) for safety.
The main idea of this patch is to avoid such tranformations.
1. Fixing Item::create_tmp_field() not to have a special case for INT_RESULT.
Item::create_tmp_field() is changed not to have a special case
for INT_RESULT (which earlier made a decision based on Item's max_length).
It now calls tmp_table_field_from_field_type() for INT_RESULT,
therefore preserves the original data type (e.g. INT, YEAR) without
conversion to BIGINT.
This change is valid, because a number of recent fixes
(e.g. in Item_func_int, Item_hybrid_func, Item_int, Item_splocal)
guarantee that item->type_handler() now properly returns
type_handler_long vs type_handler_longlong. So no adjustment by length
is needed any more for Items returning INT_RESULT.
After this change, Item::create_tmp_field() calls
tmp_table_field_from_field_type() for all XXX_RESULT, except REAL_RESULT.
2. Fixing Item::create_tmp_field() not to have a special case for REAL_RESULT.
Note, the reason for a special case for REAL_RESULT is to have a special
constructor for Field_double(), forcing Field_real::not_fixed to be set
to true.
Taking into account that only Item_sum descendants actually need a special
constructor call Field_double(not_fixed=true), not too loose precision
when mixing individual rows to the aggregate result:
- renaming Item::create_tmp_field() to Item_sum::create_tmp_field().
- changing Item::create_tmp_field() just to call
tmp_table_field_from_field_type() for all XXX_RESULT types.
A special case for REAL_RESULT in Item::create_tmp_field() is now gone.
Item::create_tmp_field() is now symmetric for all XXX_RESULT types,
and now just calls tmp_table_field_from_field_type().
3. Fixing Item_func::create_field_for_create_select() not to have
a special case for STRING_RESULT.
After changes #1 and #2, the code in
Item_func::create_field_for_create_select(), testing result_type(),
becomes useless, because: now Item::create_tmp_field() and
tmp_table_field_from_field_type() do exactly the same thing for all
XXX_RESULT types for Item_func descendants:
a. It calls tmp_table_field_from_field_type for STRING_RESULT directly.
b. For other XXX_RESULT, it goes through Item::create_tmp_field(),
which calls the global function ::create_tmp_field(),
which calls item->create_tmp_field() for FUNC_ITEM,
which calls tmp_table_field_from_field_type() again.
So removing the virtual implementation of
Item_func::create_field_for_create_select().
The inherited Item::create_field_for_create_select() now perfectly
does the job, as it also calls tmp_table_field_from_field_type()
for FUNC_ITEM, independently from XXX_RESULT type.
4. Taking into account #1 and #2, as well as some recent changes,
removing virtual implementations:
- Item_hybrid_func::create_tmp_field()
- Item_hybrid_func::create_field_for_create_select()
- Item_int_func::create_tmp_field()
- Item_int_func::create_field_for_create_select()
- Item_temporal_func::create_field_for_create_select()
The derived versions from Item now perfectly work.
5. Moving a piece of code from create_tmp_field_from_item()
to a new function create_tmp_field_from_item_finalize(),
to reuse it in two places (see #6).
6. Changing the code responsible for BIT->INT/BIGIN tranformation
(which is called for the cases when the created table, e.g. HEAP,
does not fully support BIT) not to call create_tmp_field_from_item(),
because the latter now calls tmp_table_field_from_field_type() instead
of create_tmp_field() and thefore cannot do BIT transformation.
So rewriting this code using a sequence of these calls:
- item->type_handler_long_or_longlong()
- handler->make_and_init_table_field()
- create_tmp_field_from_item_finalize()
7. Miscelaneous changes:
- Moving type_handler_long_or_longlong() from "protected" to "public",
as it's now needed in the global function create_tmp_field().
8. The above changes fixed MDEV-12875, MDEV-12886, MDEV-12916.
So adding tests for these bugs.
This is a joint patch for:
MDEV-12852 Out-of-range errors when CAST(1-2 AS UNSIGNED
MDEV-12853 Out-of-range errors when CAST('-1' AS UNSIGNED
MDEV-12869 Wrong metadata for integer additive and multiplicative operators
1. Fixing all Item_func_numhybrid descendants to set the precise
data type handler (type_handler_long or type_handler_longlong)
at fix_fields() time. This fixes MDEV-12869.
2. Fixing Item_func_unsigned_typecast to set the precise data type handler
at fix_fields() time. This fixes MDEV-12852 and MDEV-12853.
This is done by:
- fixing Type_handler::Item_func_unsigned_fix_length_and_dec()
and Type_handler_string_result::Item_func_unsigned_fix_length_and_dec()
to properly detect situations when a negative epxression is converted
to UNSIGNED. In this case, length of the result is now always set to
MAX_BIGINT_WIDTH without trying to use args[0]->max_length, as very
short arguments can produce very long result in such conversion:
CAST(-1 AS UNSIGNED) -> 18446744073709551614
- adding a new virtual method "longlong Item::val_int_max() const",
to preserve the old behavior for expressions like this:
CAST(1 AS UNSIGNED)
to stay under the INT data type (instead of BIGINT) for small
positive integer literals. Using Item::unsigned_flag would not help,
because Item_int does not set unsigned_flag to "true" for positive
numbers.
3. Adding helper methods:
* Item::type_handler_long_or_longlong()
* Type_handler::type_handler_long_or_longlong()
and reusing them in a few places, to reduce code duplication.
4. Making reorganation in create_tmp_field() and
create_field_for_create_select() for Item_hybrid_func and descendants,
to reduce duplicate code. They all now have a similar behavior in
respect of creating fields. Only Item_func_user_var descendants have
a different behavior. So moving the default behvior to Item_hybrid_func,
and overriding behavior on Item_func_user_var level.
- Adding Type_handler::make_table_field() and moving pieces of the code
from Item::tmp_table_field_from_field_type() to virtual implementations
for various type handlers.
- Adding a new Type_all_attributes, to access to Item's extended
attributes, such as decimal_precision() and geometry_type().
- Adding a new class Record_addr, to pass record related information
to Type_handler methods (ptr, null_ptr and null_bit) as a single structure.
Note, later it will possibly be extended for BIT-alike field purposes,
by adding new members (bit_ptr_arg, bit_ofs_arg).
- Moving the code from Field_new_decimal::create_from_item()
to Type_handler_newdecimal::make_table_field().
- Removing Field_new_decimal() and Field_geom() helper constructor
variants that were used for temporary field creation.
- Adding Item_field::type_handler(), Field::type_handler() and
Field_blob::type_handler() to return correct type handlers for
blob variants, according to Field_blob::packlength.
- Adding Type_handler_blob_common, as a common parent for
Type_handler_tiny_blob, Type_handler_blob, Type_handler_medium_blob
and Type_handler_long_blob.
- Implementing Type_handler_blob_common::Item_hybrid_func_fix_attributes().
It's needed for cases when TEXT variants of different character sets are mixed
in LEAST, GREATEST, CASE and its abreviations (IF, IFNULL, COALESCE), e.g.:
CREATE TABLE t1 (
a TINYTEXT CHARACTER SET latin1,
b TINYTEXT CHARACTER SET utf8
);
CREATE TABLE t2 AS SELECT COALESCE(a,b) FROM t1;
Type handler aggregation returns TINYTEXT as a common data type
for the two columns. But as conversion from latin1 to utf8
happens for "a", the maximum possible length of "a" grows from 255 to 255*3.
Type_handler_blob_common::Item_hybrid_func_fix_attributes() makes sure
to update the blob type handler according to max_length.
- Adding Type_handler::blob_type_handler(uint max_octet_length).
- Adding a few m_type_aggregator_for_result.add() pairs, because
now Item_xxx::type_handler() can return pointers to type_handler_tiny_blob,
type_handler_blob, type_handler_medium_blob, type_handler_long_blob.
Before the patch only type_handler_blob was possible result of type_handler().
- Making type_handler_tiny_blob, type_handler_blob, type_handler_medium_blob,
type_handler_long_blob public.
- Removing the condition in Item_sum_avg::create_tmp_field()
checking Item_sum_avg::result_type() against DECIMAL_RESULT.
Now both REAL_RESULT and DECIMAL_RESULT are symmetrically handled
by tmp_table_field_from_field_type().
- Removing Item_geometry_func::create_field_for_create_select(),
as the inherited version perfectly works.
- Fixing Item_func_as_wkb::field_type() to return MYSQL_TYPE_LONG_BLOB
rather than MYSQL_TYPE_BLOB. It's needed to make sure that
tmp_table_field_from_field_type() creates a LONGBLOB field for AsWKB().
- Fixing Item_func_as_wkt::fix_length_and_dec() to set max_length to
UINT32_MAX rather than MAX_BLOB_WIDTH, to make sure that
tmp_table_field_from_field_type() creates a LONGTEXT field for AsWKT().
- Removing Item_func_set_user_var::create_field_for_create_select(),
as the inherited version works fine.
- Adding Item_func_get_user_var::create_field_for_create_select() to
make sure that "CREATE TABLE t1 AS SELECT @string_user variable"
always creates a field of LONGTEXT/LONGBLOB type.
- Item_func_ifnull::create_field_for_create_select()
behavior has changed. Before the patch it passed set_blob_packflag=false,
which meant to create LONGBLOB for all blob variants.
Now it takes into account max_length, which gives better column
data types for:
CREATE TABLE t2 AS SELECT IFNULL(blob_column1, blob_column2) FROM t1;
- Fixing Item_func_nullif::fix_length_and_dec() to use
set_handler(args[2]->type_handler()) instead of
set_handler_by_field_type(args[2]->field_type()).
This is needed to distinguish between BLOB variants.
- Implementing Item_blob::type_handler(), to make sure to create
proper BLOB field variant, according to max_length, for queries like:
CREATE TABLE t1 AS
SELECT some_blob_field FROM INFORMATION_SCHEMA.SOME_TABLE;
- Fixing Item_field::real_type_handler() to make sure that
the code aggregating fields for UNION gets a proper BLOB
variant type handler from fields.
- Adding a special code into Item_type_holder::make_field_by_type(),
to make sure that after aggregating field types it also properly
takes into account max_length when mixing TEXT variants of different
character sets and chooses a proper TEXT variant:
CREATE TABLE t1 (
a TINYTEXT CHARACTER SET latin1,
b TINYTEXT CHARACTER SET utf8
);
CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;
- Adding tests, for better coverage of IFNULL, NULLIF, UNION.
- The fact that tmp_table_field_from_field_type() now takes
into account BLOB variants (instead of always creating LONGBLOB),
tests results for WEIGHT_STRING() and NULLIF() and UNION
have become more precise.
- Adding a new virtual method Type_handler::Item_time_precision()
- Adding a new virtual method Type_handler::Item_datetime_precision()
- Removing Item::temporal_precision() and adding Item::time_precision()
and Item::datetime_precision() instead.
- Moving Item_func_convert_tz::fix_length_and_dec() from item_timefunc.cc
to item_timefunc.h. It's only two lines, and we're changing it anyway.
- Removing Item_temporal_typecast::fix_length_and_dec_generic(),
moving this code to
Type_handler::Item_{date|time|datetime}_typecast_fix_length_and_dec().
This allows to get rid of one more field_type() call.
Also, in the old reduction, Item_date_typecast::fix_length_and_dec()
unnecessarily called args[0]->temporal_precision(). The new reduction
does not call args[0]->datetime_precision(), as DATE does not
have fractional digits.
This patch implements MDEV-12514 according to the task descriptions.
It automatically fixes:
MDEV-12515 Wrong value when storing DATE_ADD() and ADDTIME() to a numeric field
Additionally:
a. Moves Item_func::set_attributes_temporal() to
Type_str_attributes::fix_attributes_temporal(),
which is a more proper place and name for it.
b. Continues replacing calls for:
set_handler_by_field_type(MYSQL_TYPE_XXX)
to corresponding:
set_handler(&type_handler_xxx)
which is faster.
Note, we should eventually get rid of almost all set_handler_by_field_type().
c. Makes type_handler_string, type_handler_time2, type_handler_newdate,
type_handler_datetime2 public.
(all built-in handlers will become public eventually)
d. Removing Item_temporal_func::sql_mode, as it was not used.
The problem happened because Item_ident_for_show::field_type() always
returned MYSQL_TYPE_DOUBLE and ignored the actual data type of the
referenced Field. As a result, the execution always used
Item_ident_for_show::val_real() to send the default value of the field,
so most default values for non-numeric types were displayed as '0'.
This patch:
1. Cleanup:
a. Removes Send_field::charsetnr, as it's been unused since
introduction of Item::charset_for_protocol() in MySQL-5.5.
b. Adds the "const" qualifier to Field::char_length().
This is needed for (5.a), see below.
2. Introduces a new virtual method Type_handler::charset_for_protocol(),
returning item->collation.collation for string data types, or
&my_charset_bin for non-string data types.
3. Changes Item::charset_for_protocol() from virtual to non-virtual.
It now calls type_handler()->charset_for_protocol().
As a good side effect, duplicate code in Item::charset_for_protocol() and
Item_temporal_hybrid_func::charset_for_protocol() is now gone.
4. Fixes Item_ident_for_show::field_type() to correctly return
its data type according to the data type of the referenced field.
This actually fixes the problem reported in MDEV-11672.
Now the default value is sent using a correct method, e.g.
val_str() for VARCHAR/TEXT, or val_int() for INT/BIGINT.
This required additional changes:
a. in DBUG_ASSERT in Protocol::store(const char *,size_t,CHARSET_INFO),
This method is now used by mysqld_list_fields(), which
(unlike normal SELECT queries) does not set
field_types/field_pos/field_count.
b. Item_ident_for_show::Item_ident_for_show() now set standard attributes
(collation, decimals, max_length, unsigned_flag) according to the
referenced field, to make charset_for_protocol() return the correct
value and to make mysqld_list_fields() correctly send default
values.
5. In order to share the code between Item_field::set_field() and
Item_ident_for_show::Item_ident_for_show():
a. Introduces a new method Type_std_attributes::set(const Field*)
b. To make (a) possible, moves Item::fix_char_length() from Item
to Type_std_attributes, also moves char_to_byte_length_safe()
from item.h to sql_type.h
c. Additionally, moves Item::fix_length_and_charset() and
Item::max_char_length() from Item to Type_std_attributes.
This is not directly needed for the fix and is done just for symmetry
with fix_char_length(), as these three methods are directly related
to each other.
This change is a backport from 10.0 to 5.5 for:
1. The full patch for:
MDEV-4841 Wrong character set of ADDTIME() and DATE_ADD()
9adb6e991e
2. A small fragment of:
MDEV-5298 Illegal mix of collations on timestamp
03f6778d61
which overrides Item_temporal_hybrid_func::cmp_type(),
and adds a new line into cache_temporal_4265.result.
Also fixes:
MDEV-11331 Wrong result for INSERT INTO t1 (datetime_field) VALUES (hybrid_function_of_TIME_data_type)
MDEV-11333 Expect "Impossible where condition" for WHERE timestamp_field>=DATE_ADD(TIMESTAMP'9999-01-01 00:00:00',INTERVAL 1000 YEAR)
This patch does the following:
1. Splits the function Item::save_in_field() into pieces:
- Item::save_str_in_field()
- Item::save_real_in_field()
- Item::save_decimal_in_field()
- Item::save_int_in_field()
2. Adds the missing "no_conversion" parameters to
Item::save_time_in_field() and Item::save_date_in_field(),
so this parameter is now correctly passed to
set_field_to_null_with_conversions().
This fixes the problem reported in 11333.
3. Introduces a new virtual method Type_handler::Item_save_in_field()
and uses the methods Item::save_xxx_in_field() from the implementations
of Type_handler_xxx::Item_save_in_field().
These changes additionally fix the problem reported in MDEV-11331,
as the old code erroneously handled expressions like
COALESE(datetime-expression) through the STRING_RESULT branch of
Item::save_in_field() and therefore they looked like string type expressions
for the target fields. Now such expressions are correctly handled by
Item::save_date_in_field().
otherwise we'd need to store sql_mode *per vcol*
(consider CREATE INDEX...) and how SHOW CREATE TABLE would
support that?
Additionally, get rid of vcol::expr_str, just to make sure
the string is always generated and never leaked in the
original form.
* revert part of the db7edfe that moved calculations from
fix_fields to val_str for Item_func_sysconst and descendants
* mark session state dependent functions in check_vcol_func_processor()
* re-run fix_fields for all such functions for every statement
* fix CURRENT_USER/CURRENT_ROLE not to use Name_resolution_context
(that is allocated on the stack in unpack_vcol_info_from_frm())
Note that NOW(), CURDATE(), etc use lazy initialization and do *not*
force fix_fields to be re-run. The rule is:
* lazy initialization is *not* allowed, if it changes metadata (so,
e.g. DAYNAME() cannot use it)
* lazy initialization is *preferrable* if it has side effects (e.g.
NOW() sets thd->time_zone_used=1, so it's better to do it when
the value of NOW is actually needed, not when NOW is simply prepared)
- Force usage of () around complex DEFAULT expressions
- Give error if DEFAULT expression contains invalid characters
- Don't use const_charset_conversion for stored Item_func_sysconf expressions
as the result is not constaint over different executions
- Fixed Item_func_user() to not store calculated value in str_value
MDEV-10134 Add full support for DEFAULT
- Added support for using tables with MySQL 5.7 virtual fields,
including MySQL 5.7 syntax
- Better error messages also for old cases
- CREATE ... SELECT now also updates timestamp columns
- Blob can now have default values
- Added new system variable "check_constraint_checks", to turn of
CHECK constraint checking if needed.
- Removed some engine independent tests in suite vcol to only test myisam
- Moved some tests from 'include' to 't'. Should some day be done for all tests.
- FRM version increased to 11 if one uses virtual fields or constraints
- Changed to use a bitmap to check if a field has got a value, instead of
setting HAS_EXPLICIT_VALUE bit in field flags
- Expressions can now be up to 65K in total
- Ensure we are not refering to uninitialized fields when handling virtual fields or defaults
- Changed check_vcol_func_processor() to return a bitmap of used types
- Had to change some functions that calculated cached value in fix_fields to do
this in val() or getdate() instead.
- store_now_in_TIME() now takes a THD argument
- fill_record() now updates default values
- Add a lookahead for NOT NULL, to be able to handle DEFAULT 1+1 NOT NULL
- Automatically generate a name for constraints that doesn't have a name
- Added support for ALTER TABLE DROP CONSTRAINT
- Ensure that partition functions register virtual fields used. This fixes
some bugs when using virtual fields in a partitioning function
MDEV-9408 CREATE TABLE SELECT MAX(int_column) creates different columns for table vs view
There were three almost identical pieces of the code:
- Field *Item_func::tmp_table_field();
- Field *Item_sum::create_tmp_field();
- Field *create_tmp_field_from_item();
with a difference in very small details (hence the bugs):
Only Item_func::tmp_table_field() was correct, the other two were not.
Removing the two incorrect pieces of the redundant code.
Joining these three functions/methods into a single virtual method
Item::create_tmp_field().
Additionally, moving Item::make_string_field() and
Item::tmp_table_field_from_field_type() from the public into the
protected section of the class declaration, as they are now not
needed outside of Item.
Item_func_hybrid_field_type did not return correct field_type(), cmp_type()
and result_type() in some cases, because cached_result_type and
cached_field_type were set in independent pieces of the code and
did not properly match to each other.
Fix:
- Removing Item_func_hybrid_result_type
- Deriving Item_func_hybrid_field_type directly from Item_func
- Introducing a new class Type_handler which guarantees that
field_type(), cmp_type() and result_type() are always properly synchronized
and using the new class in Item_func_hybrid_field_type.
Added mandatory thd parameter to Item (and all derivative classes) constructor.
Added thd parameter to all routines that may create items.
Also removed "current_thd" from Item::Item. This reduced number of
pthread_getspecific() calls from 290 to 177 per OLTP RO transaction.
MDEV-6789 segfault in Item_func_from_unixtime::get_date on updating table with virtual columns
* prohibit VALUES in partitioning expression
* prohibit user and system variables in virtual column expressions
* fix Item_func_date_format to cache locale (for %M/%W to return the same as MONTHNAME/DAYNAME)
* fix Item_func_from_unixtime to cache time_zone directly, not THD (and not to crash)
* added tests for other incorrectly allowed (in vcols) functions to see that they don't crash
The crash happened because Item_func_monthname was derived from
Item_func_month, so Item_func_monthname::is_null() did not work fine.
Backporting a change from 5.5: Item_func_monthname is now derived from
Item_str_func.
Other fix of maybe_null problem and revert of revno: 3608 "MDEV-3873 & MDEV-3876 & MDEV-3912 : Wrong result (extra rows) with ALL subquery from a MERGE view."
includes:
* remove some remnants of "Bug#14521864: MYSQL 5.1 TO 5.5 BUGS PARTITIONING"
* introduce LOCK_share, now LOCK_ha_data is strictly for engines
* rea_create_table() always creates .par file (even in "frm-only" mode)
* fix a 5.6 bug, temp file leak on dummy ALTER TABLE
get_datetime_value() should not double-cache its own Item_cache_temporal items,
but it *should* cache other Item_cache items, such as Item_cache_str.
sql/item.h:
shortcut, to avoid going through the switch in Item::cmp_type()
sql/item_cmpfunc.cc:
even if the item is Item_cache_str - it still needs to be converted and cached.
sql/item_timefunc.h:
all descendants of Item_temporal_func always have cmp_type==TIME_RESULT.
Even Item_date_add_interval, that might have field_type == MYSQL_TYPE_STRING.
from a MERGE view.
The problem was in the lost ability to be null for the table of a left join if it
is a view/derived table.
It hapenned because setup_table_map(), was called earlier then we merged
the view or derived.
Fixed by propagating new maybe_null flag during Item::update_used_tables().
Change in join_outer.test and join_outer_jcl6.test appeared because
IS NULL reported no used tables (i.e. constant) for argument which could not be
NULL and new maybe_null flag was propagated for IS NULL argument (Item_field)
because table the Item_field belonged to changed its maybe_null status.
sql/sql_insert.cc:
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
******
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
small cleanup
******
small cleanup