1. 16 Sep, 2024 13 commits
    • Oleg Smirnov's avatar
      MDEV-27277 Add a warning when max_sort_length is reached · 68ad4090
      Oleg Smirnov authored
      During a query execution some sorting and grouping operations
      on strings may be involved. System variable max_sort_length defines
      the maximum number of bytes to use when comparing strings during
      sorting/grouping. Thus, the comparable parts of strings may be less
      than their actual size, so the results of the query may be not
      sorted/grouped properly.
      To indicate that some comparisons were done on a truncated lengths,
      a new warning has been introduced with this commit.
      68ad4090
    • Alexander Barkov's avatar
      MDEV-27277 Add a warning when max_sort_length is reached · 882aa0a2
      Alexander Barkov authored
      Step#1: fixing the return type of strnxfrm() from size_t to this structure:
      
      typedef struct
      {
        size_t m_output_length;
        size_t m_source_length_used;
        uint m_warnings;
      } my_strnxfrm_ret_t;
      882aa0a2
    • Yuchen Pei's avatar
      MDEV-25008: UPDATE/DELETE: Cost-based choice IN->EXISTS vs Materialization · dee4a4a6
      Yuchen Pei authored
      Single-table UPDATE/DELETE didn't provide outer_lookup_keys value for
      subqueries. This didn't allow to make a meaningful choice between
      IN->EXISTS and Materialization strategies for subqueries.
      
      Fix this:
      * Make UPDATE/DELETE save Sql_cmd_dml::scanned_rows,
      * Then, subquery's JOIN::choose_subquery_plan() can fetch it from
      there for outer_lookup_keys
      
      Details:
      UPDATE/DELETE now calls select_lex->optimize_unflattened_subqueries()
      twice, like SELECT does (first call optimize_constant_subquries() in
      JOIN::optimize_inner(), then call optimize_unflattened_subqueries() in
      JOIN::optimize_stage2()):
      1. Call with const_only=true before any optimizations. This allows
      range optimizer and others to use the values of cheap const
      subqueries.
      2. Call it with const_only=false after range optimizer, partition
      pruning, etc. outer_lookup_keys value is provided, so it's possible to
      pick a good subquery strategy.
      
      Note: PROTECT_STATEMENT_MEMROOT requires that first SP execution
      performs subquery optimization for all subqueries, even for degenerate
      query plans like "Impossible WHERE". Due to that, we ensure that the
      call to optimize_unflattened_subqueries (with const_only=false) even
      for degenerate query plans still happens, as was the case before this
      change.
      dee4a4a6
    • Yuchen Pei's avatar
    • Alexander Barkov's avatar
      MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?] · dad24a55
      Alexander Barkov authored
      Changing the return type of the following functions:
        - CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(), NOW()
        - SYSDATE()
        - FROM_UNIXTIME()
      from DATETIME to TIMESTAMP.
      
      Note, the old function NOW() returning DATETIME is still available
      as LOCALTIMESTAMP or LOCALTIMESTAMP(), e.g.:
      
        SELECT
          LOCALTIMESTAMP,     -- DATETIME
          CURRENT_TIMESTAMP;  -- TIMESTAMP
      
      The change in the functions return data type fixes some problems
      that occurred near a DST change:
      
      - Problem #1
      
      INSERT INTO t1 (timestamp_field) VALUES (CURRENT_TIMESTAMP);
      INSERT INTO t1 (timestamp_field) VALUES (COALESCE(CURRENT_TIMESTAMP));
      
      could result into two different values inserted.
      
      - Problem #2
      
      INSERT INTO t1 (timestamp_field) VALUES (FROM_UNIXTIME(1288477526));
      INSERT INTO t1 (timestamp_field) VALUES (FROM_UNIXTIME(1288477526+3600));
      
      could result into two equal TIMESTAMP values near a DST change.
      
      Additional changes:
      
      - FROM_UNIXTIME(0) now returns SQL NULL instead of '1970-01-01 00:00:00'
        (assuming time_zone='+00:00')
      
      - UNIX_TIMESTAMP('1970-01-01 00:00:00') now returns SQL NULL instead of 0
        (assuming time_zone='+00:00'
      
      These additional changes are needed for consistency with TIMESTAMP fields,
      which cannot store '1970-01-01 00:00:00 +00:00'.
      dad24a55
    • Alexander Barkov's avatar
      MDEV-12252 ROW data type for stored function return values · 3624fb78
      Alexander Barkov authored
      Adding support for the ROW data type in the stored function RETURNS clause:
      
      - explicit ROW(..members...) for both sql_mode=DEFAULT and sql_mode=ORACLE
      
        CREATE FUNCTION f1() RETURNS ROW(a INT, b VARCHAR(32)) ...
      
      - anchored "ROW TYPE OF [db1.]table1" declarations for sql_mode=DEFAULT
      
        CREATE FUNCTION f1() RETURNS ROW TYPE OF test.t1 ...
      
      - anchored "[db1.]table1%ROWTYPE" declarations for sql_mode=ORACLE
      
        CREATE FUNCTION f1() RETURN test.t1%ROWTYPE ...
      
      Adding support for anchored scalar data types in RETURNS clause:
      
      - "TYPE OF [db1.]table1.column1" for sql_mode=DEFAULT
      
        CREATE FUNCTION f1() RETURNS TYPE OF test.t1.column1;
      
      - "[db1.]table1.column1" for sql_mode=ORACLE
      
        CREATE FUNCTION f1() RETURN test.t1.column1%TYPE;
      
      Details:
      
      - Adding a new sql_mode_t parameter to
          sp_head::create()
          sp_head::sp_head()
          sp_package::create()
          sp_package::sp_package()
        to guarantee early initialization of sp_head::m_sql_mode.
        Before this change, this member was not initialized at all during
        CREATE FUNCTION/PROCEDURE/PACKAGE statements, and was not used.
        Now it needs to be initialized to write properly the
        mysql.proc.returns column, according to the create time sql_mode.
      
      - Code refactoring to make the things simpler and functions smaller:
      
        * Adding a new method
          Field_row::row_create_fields(THD *thd, List<Spvar_definition> *list)
          to make a Virtual_tmp_table with Fields for ROW members
          from an explicit definition.
      
        * Adding a new method
          Field_row::row_create_fields(THD *thd, const Spvar_definition &def)
          to make a Virtual_tmp_table with Fields for ROW members
          from an explicit or a table anchored definition.
      
        * Adding a new method
          Item_args::add_array_of_item_field(THD *thd, const Virtual_tmp_table &vtable)
          to create and array of Item_field corresponding to all Field instances
          in a Virtual_tmp_table
      
        * Removing Item_field_row::row_create_items(). It was decomposed
          into the new methods described above.
      
        * Moving the code from the loop body in sp_rcontext::init_var_items()
          into a separate method Spvar_definition::make_item_field_row(),
          to make the code clearer (smaller functions).
          make_item_field_row() itself uses the new methods described above.
      
      - Changing the data type of sp_head::m_return_field_def
        from Column_definition to Spvar_definition.
        So now it supports not only SQL column field types,
        but also explicit ROW and anchored ROW data types,
        as well as anchored column types.
      
      - Adding a new Column_definition parameter to sp_head::create_result_field().
        Before this patch, create_result_field() took the definition only
        from m_return_field_def. Now it's also called with a local Column_definition
        variable which contains the explicit definition resolved from an
        anchored defition.
      
      - Modifying sql_yacc.yy to support the new grammar.
        Adding new helper methods:
          * sf_return_fill_definition_row()
          * sf_return_fill_definition_rowtype_of()
          * sf_return_fill_definition_type_of()
      
      - Fixing tests in:
        * Virtual_tmp_table::setup_field_pointers() in sql_select.cc
        * Send_field::normalize() in field.h
        * store_column_type()
        to prevent calling Type_handler_row::field_type(),
        which is implemented a DBUG_ASSERT(0).
        Before this patch the affected methods and functions were called only
        for scalar data types. Now ROW is also possible.
      
      - Adding a new virtual method Field::cols()
      
      - Overriding methods:
         Item_func_sp::cols()
         Item_func_sp::element_index()
         Item_func_sp::check_cols()
         Item_func_sp::bring_value()
        to support the ROW data type.
      
      - Extending the rule sp_return_type to support
        * explicit ROW and anchored ROW data types
        * anchored scalar data types
      
      - Overriding Field_row::sql_type() to print
        the data type of an explicit ROW.
      3624fb78
    • Sergei Golubchik's avatar
      post-merge changes · f5e4c461
      Sergei Golubchik authored
      * remove duplicate test file
      * move all uuidv7 tests into plugin/type_uuid/mysql-test/type_uuid/
      * remove mysys/ changes
      * auto my_random_bytes() fallback - removes duplicate code from uuid,
        and fixes all other users of my_random_bytes() that don't check
        the return value (because, perhaps, they don't need crypto-strong
        random bytes)
      * End of 11.6 -> 11.7 in tests
      * clarify the warning text
      * UUID_VERSION_MASK()/UUID_VARIANT_MASK() must not depend on the version
      * allow 4x more monotonic uuidv7 per millisecond - instead of stretching
        1000 microseconds over 12 bits, let's use extra 2 bits as a counter
      f5e4c461
    • StefanoPetrilli's avatar
      89e0944d
    • Daniel Black's avatar
      MDEV-32583 UUID() should be treated as stochastic for the purposes of forcing query materialization · 8ea4590a
      Daniel Black authored
      Port 9e800eda changing lex->safe_to_cache_query
      to lex->uncacheable(UNCACHEABLE_RAND).
      8ea4590a
    • Alexander Barkov's avatar
      cleanup: MDEV-11339 Implement native UUID4 function · c5cc46f3
      Alexander Barkov authored
      - Moving the class UUIDv1 into a separate file sql_type_uuid_v1.h
      
      - Adding a new class UUIDv4, similar to UUIDv1
      
      - Changing the way how my_random_bytes() failures are handled.
        Instead of raising an error it now raises a note.
        Reasoning: if we're in the middle of a multi-million row
        transaction and one UUIDv4 generation fails, it's not a good
        idea to throw away the entire transaction. Instead, let's
        generate bytes using a my_rnd() loop.
      
      - Adding a new test func_uuid_v4.test to demonstrate that the UUIDv4()
        returned type is "UUID NOT NULL".
      
      - Adding a new test func_uuidv4_debug.test to emulate my_random_bytes()
        failures
      
      - Adding a template Item_func_uuid_vx to share the code
        between the implementations of UUID() and UUIDv4().
      c5cc46f3
    • StefanoPetrilli's avatar
      2f288273
    • Sergei Golubchik's avatar
    • Monty's avatar
      MDEV-33144 Implement the Percona variable slow_query_log_always_write_time · 295c0ebf
      Monty authored
      This task is inspired by the Percona implementation of
      slow_query_log_always_write_time.
      
      This task implements the variable log_slow_always_query_time (name
      matching other MariaDB variables using the slow query log). The
      default value for the variable is 31536000, which makes MariaDB
      compatible with older installations.
      
      For queries with execution time longer than log_slow_always_query_time
      the variables log_slow_rate_limit and log_slow_min_examined_row_limit
      will be ignored and the query will be written to the slow query log
      if there is no other limitations (like log_slow_filter etc).
      
      Other things:
      - long_query_time internal variable renamed to log_slow_query_time.
      - More descriptive information for "log_slow_query_time".
      295c0ebf
  2. 14 Sep, 2024 27 commits