1
0
mirror of https://github.com/MariaDB/server.git synced 2025-06-03 07:02:23 +03:00

214 Commits

Author SHA1 Message Date
Alexander Barkov
056766c042 The patch for MDEV-23551 did not compile on some compilers. Fixing. 2020-08-24 14:27:32 +04:00
Alexander Barkov
04ce29354b MDEV-23551 Performance degratation in temporal literals in 10.4
Problem:

Queries like this showed performance degratation in 10.4 over 10.3:

  SELECT temporal_literal FROM t1;
  SELECT temporal_literal + 1 FROM t1;
  SELECT COUNT(*) FROM t1 WHERE temporal_column = temporal_literal;
  SELECT COUNT(*) FROM t1 WHERE temporal_column = string_literal;

Fix:

Replacing the universal member "MYSQL_TIME cached_time" in
Item_temporal_literal to data type specific containers:
- Date in Item_date_literal
- Time in Item_time_literal
- Datetime in Item_datetime_literal

This restores the performance, and make it even better in some cases.
See benchmark results in MDEV.

Also, this change makes futher separations of Date, Time, Datetime
from each other, which will make it possible not to derive them from
a too heavy (40 bytes) MYSQL_TIME, and replace them to smaller data
type specific containers.
2020-08-24 09:17:47 +04:00
Alexander Barkov
2e5d86f49e MDEV-23537 Comparison with temporal columns is slow in MariaDB
Implementing methods:
- Field::val_time_packed()
- Field::val_datetime_packed()
- Item_field::val_datetime_packed(THD *thd);
- Item_field::val_time_packed(THD *thd);
to give a faster access to temporal packed longlong representation of a Field,
which is used in temporal Arg_comparator's to DATE, TIME, DATETIME data types.

The same idea is used in MySQL-5.6+.

This improves performance.
2020-08-22 15:22:20 +04:00
Alexander Barkov
ae33ebe5b3 MDEV-23525 Wrong result of MIN(time_expr) and MAX(time_expr) with GROUP BY
Problem:

When calculatung MIN() and MAX() in a query with GROUP BY, like this:

  SELECT MIN(time_expr), MAX(time_expr) FROM t1 GROUP BY i;

the code in Item_sum_min_max::update_field() erroneosly used
string format comparison, therefore '100:20:30' was considered as
smaller than '10:20:30'.

Fix:

1. Implementing low level "native" related methods in class Time:
     Time::Time(const Native &native)           - convert native to Time
     Time::to_native(Native *to, uint decimals) - convert Time to native

   The "native" binary representation for TIME is equal to
   the binary data format of Field_timef, which is used to
   store TIME when mysql56_temporal_format is ON (default).

2. Implementing Type_handler_time_common "native" related methods:

  Type_handler_time_common::cmp_native()
  Type_handler_time_common::Item_val_native_with_conversion()
  Type_handler_time_common::Item_val_native_with_conversion_result()
  Type_handler_time_common::Item_param_val_native()

3. Implementing missing "native representation" related methods
   in Field_time and Field_timef:

  Field_time::store_native()
  Field_time::val_native()
  Field_timef::store_native()
  Field_timef::val_native()

4. Implementing missing "native" related methods in all Items
   that can have the TIME data type:

  Item_timefunc::val_native()
  Item_name_const::val_native()
  Item_time_literal::val_native()
  Item_cache_time::val_native()
  Item_handled_func::val_native()

5. Marking Type_handler_time_common as "native ready".
   So now Item_sum_min_max::update_field() calculates
   values using min_max_update_native_field(),
   which uses native binary representation rather than string representation.

   Before this change, only the TIMESTAMP data type used native
   representation to calculate MIN() and MAX().

Benchmarks (see more details in MDEV):

  This change not only fixes the wrong result, but also
  makes a "SELECT .. MAX.. GROUP BY .." query faster:

  # TIME(0)
  CREATE TABLE t1 (id INT, time_col TIME) ENGINE=HEAP;
  INSERT INTO t1 VALUES (1,'10:10:10'); -- repeat this 1m times
  SELECT id, MAX(time_col) FROM t1 GROUP BY id;

  MySQL80: 0.159 sec
  10.3:    0.108 sec
  10.4:    0.094 sec (fixed)

  # TIME(6):
  CREATE TABLE t1 (id INT, time_col TIME(6)) ENGINE=HEAP;
  INSERT INTO t1 VALUES (1,'10:10:10.999999'); -- repeat this 1m times
  SELECT id, MAX(time_col) FROM t1 GROUP BY id;

  My80: 0.154
  10.3: 0.135
  10.4: 0.093 (fixed)
2020-08-22 07:53:44 +04:00
Marko Mäkelä
101ddc5e27 Merge mariadb-10.4.14 2020-08-10 20:37:52 +03:00
Alexander Barkov
100f0c965c MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int
Type_handler_temporal_result::Item_func_min_max_fix_attributes()
in an expression GREATEST(string,date), e.g:

  SELECT GREATEST('1', CAST('2020-12-12' AS DATE));

incorrectly evaluated decimals as 6 (like for DATETIME).

Adding a separate virtual implementation:
  Type_handler_date_common::Item_func_min_max_fix_attributes()
This makes the code simpler.
2020-08-04 08:38:32 +04:00
Oleksandr Byelkin
57325e4706 Merge branch '10.3' into 10.4 2020-08-03 14:44:06 +02:00
Alexander Barkov
d63631c3fa MDEV-19632 Replication aborts with ER_SLAVE_CONVERSION_FAILED upon CREATE ... SELECT in ORACLE mode
- Adding optional qualifiers to data types:
    CREATE TABLE t1 (a schema.DATE);
  Qualifiers now work only for three pre-defined schemas:

    mariadb_schema
    oracle_schema
    maxdb_schema

  These schemas are virtual (hard-coded) for now, but may turn into real
  databases on disk in the future.

- mariadb_schema.TYPE now always resolves to a true MariaDB data
  type TYPE without sql_mode specific translations.

- oracle_schema.DATE translates to MariaDB DATETIME.

- maxdb_schema.TIMESTAMP translates to MariaDB DATETIME.

- Fixing SHOW CREATE TABLE to use a qualifier for a data type TYPE
  if the current sql_mode translates TYPE to something else.

The above changes fix the reported problem, so this script:

    SET sql_mode=ORACLE;
    CREATE TABLE t2 AS SELECT mariadb_date_column FROM t1;

is now replicated as:

    SET sql_mode=ORACLE;
    CREATE TABLE t2 (mariadb_date_column mariadb_schema.DATE);

and the slave can unambiguously treat DATE as the true MariaDB DATE
without ORACLE specific translation to DATETIME.

Similar,

    SET sql_mode=MAXDB;
    CREATE TABLE t2 AS SELECT mariadb_timestamp_column FROM t1;

is now replicated as:

    SET sql_mode=MAXDB;
    CREATE TABLE t2 (mariadb_timestamp_column mariadb_schema.TIMESTAMP);

so the slave treats TIMESTAMP as the true MariaDB TIMESTAMP
without MAXDB specific translation to DATETIME.
2020-08-01 07:43:50 +04:00
Marko Mäkelä
9216114ce7 Merge 10.3 into 10.4 2020-07-31 18:09:08 +03:00
Alexander Barkov
dc513dff91 MDEV-23351 Rounding functions return wrong data types for DATE input
Fixing ROUND(date,0), TRUNCATE(date,x), FLOOR(date), CEILING(date)
to return the `int(8) unsigned` data type.

Details:
1. Cleanup: moving virtual implementations
   - Type_handler_temporal_result::Item_func_int_val_fix_length_and_dec()
   - Type_handler_temporal_result::Item_func_round_fix_length_and_dec()
   to Type_handler_date_common. Other temporal data type handlers
   override these methods anyway. So they were only DATE specific.
   This change makes the code clearer.
2. Backporting DTCollation_numeric from 10.5, to reuse the code easier.
3. Adding the `preferred_attrs` argument to Item_func_round::fix_arg_int(). Now
   Type_handler_xxx::Item_func_round_val_fix_length_and_dec() work as follows:
   - The INT-alike and YEAR handlers copy preferred_attrs from args[0].
   - The DATE handler passes explicit attributes, to get `int(8) unsigned`.
   - The hex hybrid handler passes NULL, so fix_arg_int() calculates attributes.
4. Type_handler_date_common::Item_func_int_val_fix_length_and_dec()
   now sets the type handler and attributes to get `int(8) unsigned`.
2020-07-31 17:45:39 +04:00
Alexander Barkov
a874b6c445 MDEV-23337 Rounding functions create a wrong data type for integer input
1. Fixing ROUND(x) and TRUNCATE(x,0) with TINYINT, SMALLINT, MEDIUMINT, BIGINT
   input to preserve the exact data type of the argument when it's possible.

2. Fixing FLOOR(x) and CEILING(x) with TINYINT, SMALLINT, MEDIUMINT, BIGINT
  to preserve the exact data type of the argument.

3. Adding dedicated Type_handler_year::Item_func_round_fix_length_and_dec()
  to easier handle ROUND(x) and TRUNCATE(x,y) for the YEAR(2) and YEAR(4)
  input. They still return INT(2) UNSIGNED and INT(4) UNSIGNED correspondingly,
  as before.
2020-07-31 07:41:30 +04:00
Alexander Barkov
6d3186e326 MDEV-23323 Rounding functions return a wrong data type for a BIT, ENUM, SET argument
Implementing dedicated fixing methods:
- Type_handler_bit::Item_func_round_fix_length_and_dec()
- Type_handler_bit::Item_func_int_val_fix_length_and_dec()
- Type_handler_typelib::Item_func_round_fix_length_and_dec()

because the inherited methods did not work well.

Fixing:
- Type_handler_typelib::Item_func_int_val_fix_length_and_dec
  It did not work well, because it used args[0]->max_length to
  calculate the result data type. In case of ENUM and SET it was
  not correct, because in FLOOR() and CEILING() context
  ENUM and SET return not more than 5 digits (65535 is the biggest
  possible value).

Misc:
- Changing the API of
    Type_handler_bit::Bit_decimal_notation_int_digits(const Item *item)
  to a more generic form:
    Type_handler_bit::Bit_decimal_notation_int_digits_by_nbits(uint nbits)

- Fixing Type_handler_bit::Bit_decimal_notation_int_digits_by_nbits() to
  return the exact number of decimal digits for all nbits 1..64.
  The old implementation was approximate.
  This change gives better (more precise) data types.
2020-07-30 08:04:58 +04:00
Alexander Barkov
92499ae95c MDEV-23320 Hex hybrid constants 0xHHHH work badly in rounding functions
- Type_handler_hex_hybrid did not override
  Type_handler_string_result::Item_func_round_fix_length_and_dec(),
  so the result type of ROUND(0xFFFFFFFFFFFFFFFF) was erroneously
  calculated ad DOUBLE with a wrong length.
  Overriding Item_func_round_fix_length_and_dec(), to calculated
  the result type as INT/BIGINT.

  Also, fixing Item_func_round::fix_arg_int() to use
  args[0]->decimal_precision() instead of args[0]->max_length
  when calculating this->max_length, to get a correct result
  for hex hybrids.

- Type_handler_hex_hybrid::Item_func_int_val_fix_length_and_dec()
  called item->fix_length_and_dec_int_or_decimal(), which did not
  produce a correct result data type for hex hybrid.
  Implementing a dedicated code instead, to return INT UNSIGNED or
  BIGINT UNSIGNED depending in the number of digits in the arguments.
2020-07-29 21:45:41 +04:00
Alexander Barkov
5b3b53ce36 MDEV-23311 CEILING() and FLOOR() convert temporal input to numbers, unlike ROUND() and TRUNCATE()
Fixing functions CEILING and FLOOR to return
- TIME for TIME input
- DATETIME for DATETIME and TIMESTAMP input
2020-07-28 23:29:08 +04:00
Gagan Goel
f0ca9bc669 MDEV-20732 Correctly set the length of the FORMAT() result for float data type as argument. 2020-01-16 09:46:58 +02:00
Marko Mäkelä
4c25e75ce7 Merge 10.3 into 10.4 2019-12-27 18:20:28 +02:00
Alexander Barkov
1d9532cd8b After-merge cleanup 2019-12-27 18:22:16 +04:00
Roman Nozdrin
ad8266a5c2 MDEV-20732 MDB now correctly estimates a length of the FORMAT() result for
doubles in scientific notation with a big integer part.
2019-10-31 02:26:04 -05:00
Alexander Barkov
72c5a8d39b MDEV-20417 Assertion `(m_ptr == __null) == item->null_value' failed in VDec::VDec(Item*) 2019-08-26 23:42:06 +04:00
Alexander Barkov
235cf969d2 MDEV-20397 Support TIMESTAMP, DATETIME, TIME in ROUND() and TRUNCATE() 2019-08-22 15:09:59 +04:00
Alexander Barkov
52e276247d MDEV-19961 MIN(timestamp_column) returns a wrong result in a GROUP BY query 2019-08-19 15:11:14 +04:00
Alexander Barkov
95cdc1ca5f Merge commit '43882e764d6867c6855b1ff057758a3f08b25c55' into 10.4 2019-08-13 11:42:31 +04:00
Alexander Barkov
2dac123515 A cleanup for MDEV-20273 Add class Item_sum_min_max - removing duplicate code
Reusing the MIN()/MAX() fix_length_and_dec() related code for window functions
- FIRST_VALUE()
- LAST_VALUE()
- NTH_VALUE()
- LEAD()
- LAG
2019-08-09 09:00:17 +04:00
Alexander Barkov
d70dac2079 MDEV-20278 PERCENTILE_DISC() returns a wrong data type 2019-08-07 21:01:22 +04:00
Alexander Barkov
e978efd96b MDEV-20273 Add class Item_sum_min_max 2019-08-07 14:13:44 +04:00
Alexander Barkov
c99f9766b1 MDEV-19166 Assertion `!is_zero_datetime()' failed in Timestamp_or_zero_datetime::tv 2019-08-05 14:41:17 +04:00
Alexander Barkov
cfbd714868 MDEV-19774 Assertion `sec.se c() <= 0x7FFFFFFFL' failed in Item_func_from_unixtime::get_date 2019-06-20 09:48:34 +04:00
Oleksandr Byelkin
c07325f932 Merge branch '10.3' into 10.4 2019-05-19 20:55:37 +02:00
Alexander Barkov
d682dc2e70 MDEV-8919 Wrong result for CAST(9999999999999999999.0) 2019-05-17 08:08:11 +04:00
Alexander Barkov
c59d6395a6 A joint patch for MDEV-19284 and MDEV-19285 (INSTANT ALTER)
This patch fixes:

- MDEV-19284 INSTANT ALTER with ucs2-to-utf16 conversion produces bad data
- MDEV-19285 INSTANT ALTER from ascii_general_ci to latin1_general_ci produces corrupt data

These regressions were introduced in 10.4.3 by:
- MDEV-15564 Avoid table rebuild in ALTER TABLE on collation or charset changes

Changes:

1. Cleanup: Adding a helper method
   Field_longstr::csinfo_change_allows_instant_alter(),
   to remove some duplicate code in field.cc.

2. Cleanup: removing Type_handler::Charsets_are_compatible() and static
   function charsets_are_compatible() and
   introducing new methods in the recently added class Charset instead:
   - encoding_allows_reinterpret_as()
   - encoding_and_order_allow_reinterpret_as()

3. Bug fix: Removing the code that allowed instant conversion for
   ascii-to->8bit and ucs2-to->utf16.
   This actually fixes MDEV-19284 and MDEV-19285.

4. Bug fix: Adding a helper method Charset::collation_specific_name().
   The old corresponding code in Type_handler::Charsets_are_compatible()
   was not safe against (badly named) user-defined collations whose
   character set name can be longer than collation name.
2019-05-16 16:20:25 +04:00
Alexander Barkov
b7d22a843e MDEV-16872 Add CAST(expr AS FLOAT) 2019-05-16 10:16:32 +04:00
Alexander Barkov
462d689397 MDEV-19468 Hybrid type expressions return wrong format for FLOAT 2019-05-15 07:21:00 +04:00
Marko Mäkelä
be85d3e61b Merge 10.2 into 10.3 2019-05-14 17:18:46 +03:00
Marko Mäkelä
26a14ee130 Merge 10.1 into 10.2 2019-05-13 17:54:04 +03:00
Vicențiu Ciorbaru
cb248f8806 Merge branch '5.5' into 10.1 2019-05-11 22:19:05 +03:00
Alexander Barkov
baadbe9601 MDEV-9234 Add Type_handler::union_element_finalize() 2019-04-23 13:45:28 +04:00
Alexander Barkov
f4019f5b35 Backporting from 10.4 to 10.3: MDEV-17325 NULL-ability problems with LEAST() in combination with NO_ZERO_DATE and NO_ZERO_IN_DATE
This also fixes:
MDEV-17299 Assertion `maybe_null' failed in make_sortkey

Note, during merge of the 10.1 version of MDEV-17299,
please use the 10.3 version of the code (i.e. null merge the 10.1 version).
2019-04-20 00:11:50 +04:00
Alexander Barkov
4d12a6458e MDEV-19125 Change Send_field::type from enum_field_types to Type_handler* 2019-04-02 17:04:20 +04:00
Sergei Golubchik
f6000782fb mysql_prepare_create_table() inconsistency
sql_field->key_length was 0 for blob fields when a field was
being added, but Field_blob::character_octet_length() on
subsequent ALTER TABLE's (when the Field object in the old table
already existed). This means mysql_prepare_create_table() couldn't
reliably detect if the keyseg was a prefix.
2019-02-22 12:32:49 +01:00
Alexander Barkov
62c0ac2da6 A cleanup for MDEV-13916 Enforce check constraint on JSON type
1. Renaming Type_handler_json to Type_handler_json_longtext
   There will be other JSON handlers soon, e.g. Type_handler_json_varchar.

2. Making the code more symmetric for data types:

- Adding a new virtual method
  Type_handler::Column_definition_validate_check_constraint()
- Moving JSON-specific code from sql_yacc.yy to
  Type_handler_json_longtext::Column_definition_validate_check_constraint()

3. Adding new files sql_type_json.cc and sql_type_json.h
   and moving Type_handler+JSON related code into these files.
2019-02-15 19:46:58 +04:00
Marko Mäkelä
ea0be9e2d6 MDEV-15564 Avoid table rebuild in ALTER TABLE on collation or charset changes
Allow ALGORITHM=INSTANT (or avoid touching any data)
when changing the collation, or in some cases, the character set,
of a non-indexed CHAR or VARCHAR column. There is no penalty
for subsequent DDL or DML operations, and compatibility with
older MariaDB versions will be unaffected.

Character sets may be changed when the old encoding is compatible
with the new one. For example, changing from ASCII to anything
ASCII-based, or from 3-byte to 4-byte UTF-8 can sometimes be
performed instantly.

This is joint work with Eugene Kosov.
The test cases as well as ALTER_CONVERT_TO, charsets_are_compatible(),
Type_handler::Charsets_are_compatible() are his work.
The Field_str::is_equal(), Field_varstring::is_equal() and
the InnoDB changes were mostly rewritten by me due to conflicts
with MDEV-15563.

Limitations:

Changes of indexed columns will still require
ALGORITHM=COPY. We should allow ALGORITHM=NOCOPY and allow
the indexes to be rebuilt inside the storage engine,
without copying the entire table.

Instant column size changes (in bytes) are not supported by
all storage engines.

Instant CHAR column changes are only allowed for InnoDB
ROW_FORMAT=REDUNDANT. We could allow this for InnoDB
when the CHAR internally uses a variable-length encoding,
say, when converting from 3-byte UTF-8 to 4-byte UTF-8.

Instant VARCHAR column changes are allowed for InnoDB
ROW_FORMAT=REDUNDANT, and for others only if the size
in bytes does not change from 128..255 bytes to more
than 256 bytes.

Inside InnoDB, this slightly changes the way how MDEV-15563
works and fixes the result of the innodb.instant_alter_extend test.
We change the way how ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
is handled. All column extension, type changes and renaming
now go through a common route, except when ctx->is_instant()
is in effect, for example, instant ADD or DROP COLUMN has
been initiated. Only in that case we will go through
innobase_instant_try() and rewrite all column metadata.

get_type(field, prtype, mtype, len): Convert a SQL data type into
InnoDB column metadata.

innobase_rename_column_try(): Remove the update of SYS_COLUMNS.

innobase_rename_or_enlarge_column_try(): New function,
replacing part of innobase_rename_column_try() and all of
innobase_enlarge_column_try(). Also changes column types.

innobase_rename_or_enlarge_columns_cache(): Also change
the column type.
2019-02-14 20:17:14 +02:00
Monty
0f48949439 MDEV-13916 Enforce check constraint on JSON type
When creating a field of type JSON, it will be automatically
converted to TEXT with CHECK (json_valid(`a`)), if there wasn't any
previous check for the column.

Additional things:
- Added two bug fixes that was found while testing JSON. These bug
  fixes has also been pushed to 10.3 (with a test case), but as they
  where minimal and needed to get this task done and tested, the fixes
  are repeated here.
  - CREATE TABLE ... SELECT drops constraints for columns that
    are both in the create and select part.
  - If one has both a default expression and check constraint for a
    column, one can get the error "Expression for field `a` is refering
    to uninitialized field `a`.
- Removed some duplicate MYSQL_PLUGIN_IMPORT symbols
2019-02-13 19:40:26 +02:00
Alexander Barkov
ce6505f890 MDEV-18447 Assertion `!is_zero_datetime()' failed in Timestamp_or_zero_datetime::tv 2019-02-12 11:59:17 +04:00
Marko Mäkelä
b5763ecd01 Merge 10.3 into 10.4 2018-12-18 11:33:53 +02:00
Alexander Barkov
375256bae7 MDEV-18010 Add classes Inet4 and Inet6 2018-12-15 07:02:03 +04:00
Alexander Barkov
4752a039b5 MDEV-17995 INET6_NTOA(ucs2_input) erroneously returns NULL 2018-12-13 15:09:03 +04:00
Alexander Barkov
c353b2a8fc --echo #
--echo # MDEV-17979 Assertion `0' failed in Item::val_native upon SELECT with timestamp, NULLIF, GROUP BY
--echo #
2018-12-12 10:39:06 +04:00
Alexander Barkov
34eb98387f MDEV-13995 MAX(timestamp) returns a wrong result near DST change 2018-12-10 19:25:12 +04:00
Alexander Barkov
e5144f4bad Cleanup: Datetime() constructors accepting Longlong_hybrid/Sec6 do not need THD
Removing the unused THD* parameter.
2018-12-10 13:07:42 +04:00
Alexander Barkov
a25ce5ab4b MDEV-17928 Conversion from TIMESTAMP to VARCHAR SP variables does not work well on fractional digits 2018-12-08 19:17:29 +04:00