Commit graph

3248 commits

Author SHA1 Message Date
Alexander Barkov
07e4853c23 MDEV-17563 Different results using table or view when comparing values of time type
MDEV-17625 Different warnings when comparing a garbage to DATETIME vs TIME

- Splitting processes of data type conversion (to TIME/DATE,DATETIME)
  and warning generation.
  Warning are now only get collected during conversion (in an "int" variable),
  and are pushed in the very end of conversion (not in parallel).
  Warnings generated by the low level routines str_to_xxx() and number_to_xxx()
  can now be changed at the end, when TIME_FUZZY_DATES is applied,
  from "Invalid value" to "Truncated invalid value".

  Now "Illegal value" is issued only when the low level routine returned
  an error and TIME_FUZZY_DATES was not set. Otherwise, if the low level
  routine returned "false" (success), or if NULL was converted to a zero
  datetime by TIME_FUZZY_DATES, then "Truncated illegal value"
  is issued. This gives better warnings.

- Methods Type_handler::Item_get_date() and
  Type_handler::Item_func_hybrid_field_type_get_date() now only
  convert and collect warning information, but do not push warnings.

- Changing the return data type for Type_handler::Item_get_date()
  and Type_handler::Item_func_hybrid_field_type_get_date() from
  "bool" to "void". The conversion result (success vs error) can be
  checked by testing ltime->time_type. MYSQL_TIME_{NONE|ERROR}
  mean mean error, other values mean success.

- Adding new wrapper methods Type_handler::Item_get_date_with_warn() and
  Type_handler::Item_func_hybrid_field_type_get_date_with_warn()
  to do conversion followed by raising warnings, and changing
  the code to call new Type_handler::***_with_warn() methods.

- Adding a helper class Temporal::Status, a wrapper
  for MYSQL_TIME_STATUS with automatic initialization.

- Adding a helper class Temporal::Warn, to collect warnings
  but without actually raising them. Moving a part of ErrConv
  into a separate class ErrBuff, and deriving both Temporal::Warn
  and ErrConv from ErrBuff. The ErrBuff part of Temporal::Warn
  is used to collect textual representation of the input data.

- Adding a helper class Temporal::Warn_push. It's used
  to collect warning information during conversion, and
  automatically pushes warnings to the diagnostics area
  on its destructor time (in case of non-zero warning).

- Moving more code from various functions inside class Temporal.

- Adding more Temporal_hybrid constructors and
  protected Temporal methods make_from_xxx(),
  which convert and only collect warning information, but do not
  actually raise warnings.

- Now the low level functions  str_to_datetime() and str_to_time()
  always set status->warning if the return value is "true" (error).

- Now the low level functions number_to_time() and number_to_datetime()
  set the "*was_cut" argument if the return value is "true" (error).

- Adding a few DBUG_ASSERTs to make sure that str_to_xxx() and
  number_to_xxx() always set warnings on error.

- Adding new warning flags MYSQL_TIME_WARN_EDOM and MYSQL_TIME_WARN_ZERO_DATE
  for the code symmetry. Before this change there was a special
  code path for (rc==true && was_cut==0) which was treated by
  Field_temporal::store_invalid_with_warning as "zero date violation".
  Now was_cut==0 always means that there are no any error/warnings/notes
  to be raised, not matter what rc is.

- Using new Temporal_hybrid constructors in combination with
  Temporal::Warn_push inside str_to_datetime_with_warn(),
  double_to_datetime_with_warn(), int_to_datetime_with_warn(),
  Field::get_date(), Item::get_date_from_string(), and a few other places.

- Removing methods Dec_ptr::to_datetime_with_warn(),
  Year::to_time_with_warn(), my_decimal::to_datetime_with_warn(),
  Dec_ptr::to_datetime_with_warn().
  Fixing Sec6::to_time() and Sec6::to_datetime() to
  convert and only collect warnings, without raising warnings.
  Now warning raising functionality resides in Temporal::Warn_push.

- Adding classes Longlong_hybrid_null and Double_null, to
  return both value and the "IS NULL" flag. Adding methods
  Item::to_double_null(), to_longlong_hybrid_null(),
  Item_func_hybrid_field_type::to_longlong_hybrid_null_op(),
  Item_func_hybrid_field_type::to_double_null_op().
  Removing separate classes VInt and VInt_op, as they
  have been replaced by a single class Longlong_hybrid_null.

- Adding a helper method Temporal::type_name_by_timestamp_type(),
  moving a part of make_truncated_value_warning() into it,
  and reusing in Temporal::Warn::push_conversion_warnings().

- Removing Item::make_zero_date() and
  Item_func_hybrid_field_type::make_zero_mysql_time().
  They provided duplicate functionality.
  Now this code resides in Temporal::make_fuzzy_date().
  The latter is now called for all Item types when data type
  conversion (to DATE/TIME/DATETIME) is involved, including
  Item_field and Item_direct_view_ref.
  This fixes MDEV-17563: Item_direct_view_ref now correctly converts
  NULL to a zero date when TIME_FUZZY_DATES says so.
2018-11-08 09:31:46 +04:00
Marko Mäkelä
d88c136b9f Merge 10.3 into 10.4 2018-10-17 19:11:42 +03:00
Alexander Barkov
4de0d920be MDEV-17411 Wrong WHERE optimization with simple CASE and searched CASE 2018-10-11 13:39:53 +04:00
Alexander Barkov
5646c43159 MDEV-17216 Assertion `!dt->fraction_remainder(decimals())' failed in Field_temporal_with_date::store_TIME_with_warning
The problem happened because {{Field_xxx::store(longlong nr, bool unsigned_val)}} erroneously passed {{unsigned_flag}} to the {{usec}} parameter of this constructor:
{code:cpp}
Datetime(int *warn, longlong sec, ulong usec, date_conv_mode_t flags)
{code}

1. Changing Time and Datetime constructors to accept data as Sec6 rather than as
longlong/double/my_decimal, so it's not possible to do such mistakes
in the future. Additional good effect of these changes:
- This reduced some amount of similar code (minus ~35 lines).
- The code now does not rely on the fact that "unsigned_flag" is
   not important inside Datetime().
  The constructor always gets all three parts: sign, integer part,
  fractional part. The simple the better.

2. Fixing Field_xxx::store() to use the new Datetime constructor format.
   This change actually fixes the problem.

3. Adding "explicit" keyword to all Sec6 constructors,
to avoid automatic hidden conversion from double/my_decimal to Sec6,
as well as from longlong/ulonglong through double to Sec6.

4. Change#1 caused (as a dependency) changes in a few places
   with code like this:

  bool neg= nr < 0 && !unsigned_val;
  ulonglong value= m_neg ? (ulonglong) -nr : (ulonglong) nr;

These fragments relied on a non-standard behavior with
the operator "minus" applied to the lowest possible negative
signed long long value. This can lead to different results
depending on the platform and compilation flags.
We have fixed such bugs a few times already.
So instead of modifying the old wrong code to a new wrong code,
replacing all such fragments to use Longlong_hybrid,
which correctly handles this special case with -LONGLONG_MIN
in its method abs().
This also reduced the amount of similar code
(1 or 2 new lines instead 3 old lines in all 6 such fragments).

5. Removing ErrConvInteger(longlong nr, bool unsigned_flag= false)
   and adding ErrConvInteger(Longlong_hybrid) instead, to encourage
   use of safe Longlong_hybrid instead of unsafe pairs nr+neg.

6. Removing unused ErrConvInteger from Item_cache_temporal::get_date()
2018-10-09 12:02:35 +04:00
Alexander Barkov
b639fe2be1 MDEV-17351 Wrong results for GREATEST,TIMESTAMP,ADDTIME with an out-of-range TIME-alike argument
Problems:

Functions LEAST() and GREATEST() in TIME context, as well as functions
TIMESTAMP(a,b) and ADDTIME(a,b), returned confusing results when the
input TIME-alike value in a number or in a string was out of the TIME
supported range.

In case of TIMESTAMP(a,b) and ADDTIME(a,b), the second argument
value could get extra unexpected digits. For example, in:
    ADDTIME('2001-01-01 00:00:00', 10000000)  or
    ADDTIME('2001-01-01 00:00:00', '1000:00:00')
the second argument was converted to '838:59:59.999999'
with six fractional digits, which contradicted "decimals"
previously set to 0 in fix_length_and_dec().
These unexpected fractional digits led to confusing function results.

Changes:
1. GREATEST(), LEAST()

   - fixing Item_func_min_max::get_time_native()
   to respect "decimals" set by fix_length_and_dec().
   If a value of some numeric or string time-alike argument
   goes outside of the TIME range and gets limited to '838:59:59.999999',
   it's now right-truncated to the correct fractional precision.

   - fixing, Type_handler_temporal_result::Item_func_min_max_fix_attributes()
   to take into account arguments' time_precision() or datetime_precision(),
   rather than rely on "decimals" calculated by the generic implementation
   in Type_handler::Item_func_min_max_fix_attributes(). This makes
   GREATEST() and LEAST() return better data types, with the same
   fractional precision with what TIMESTAMP(a,b) and ADDTIME(a,b) return
   for the same arguments, and with DATE(a) and TIMESTAMP(a).

2. Item_func_add_time and Item_func_timestamp

   It was semantically wrong to apply the limit of the TIME data type
   to the argument "b", which plays the role of "INTERVAL DAY TO SECOND" here.
   Changing the code to fetch the argument "b" as INTERVAL rather than as TIME.

   The low level routine calc_time_diff() now gets the interval
   value without limiting to '838:59:59.999999', so in these examples:
     ADDTIME('2001-01-01 00:00:00', 10000000)
     ADDTIME('2001-01-01 00:00:00', '1000:00:00')
   calc_time_diff() gets '1000:00:00' as is.  The SQL function result
   now gets limited to the supported result data type range
   (datetime or time) inside calc_time_diff(), which now calculates
   the return value using the real fractional digits that
   came directly from the arguments (without the effect of limiting
   to the TIME range), so the result does not have any unexpected
   fractional digits any more.

   Detailed changes in TIMESTAMP() and ADDTIME():

   - Adding a new class Interval_DDhhmmssff. It's similar to Time, but:
     * does not try to parse datetime format, as it's not needed for
       functions TIMESTAMP() and ADDTIME().
     * does not cut values to '838:59:59.999999'

     The maximum supported Interval_DDhhmmssff's hard limit is
     'UINT_MAX32:59:59.999999'. The maximum used soft limit is:
     - '87649415:59:59.999999'   (in 'hh:mm:ss.ff' format)
     - '3652058 23:59:59.999999' (in 'DD hh:mm:ss.ff' format)
     which is a difference between:
     - TIMESTAMP'0001-01-01 00:00:00' and
     - TIMESTAMP'9999-12-31 23:59:59.999999'
     (the minimum datetime that supports arithmetic, and the
     maximum possible datetime value).

   - Fixing get_date() methods in the classes related to functions
     ADDTIME(a,b) and TIMESTAMP(a,b) to use the new class Interval_DDhhmmssff
     for fetching data from the second argument, instead of get_date().

   - Fixing fix_length_and_dec() methods in the classes related
     to functions ADDTIME(a,b) and TIMESTAMP(a,b) to use
     Interval_DDhhmmssff::fsp(item) instead of item->time_precision()
     to get the fractional precision of the second argument correctly.

   - Splitting the low level function str_to_time() into smaller pieces
     to reuse the code. Adding a new function str_to_DDhhmmssff(), to
     parse "INTERVAL DAY TO SECOND" values.

   After these changes, functions TIMESTAMP() and ADDTIME()
   return much more predictable results, in terms of fractional
   digits, and in terms of the overall result.

   The full ranges of DATETIME and TIME values are now covered by TIMESTAMP()
   and ADDTIME(), so the following can now be calculated:

    SELECT ADDTIME(TIMESTAMP'0001-01-01 00:00:00', '87649415:59:59.999999');
    -> '9999-12-31 23:59:59.999999'

    SELECT TIMESTAMP(DATE'0001-01-01', '87649415:59:59.999999')
    -> '9999-12-31 23:59:59.999999'

    SELECT ADDTIME(TIME'-838:59:59.999999', '1677:59:59.999998');
    -> '838:59:59.999999'
2018-10-08 13:38:01 +04:00
Marko Mäkelä
444c380ceb Merge 10.3 into 10.4 2018-10-05 08:09:49 +03:00
Sergei Golubchik
57e0da50bb Merge branch '10.2' into 10.3 2018-09-28 16:37:06 +02:00
Alexander Barkov
ad8e02ac45 MDEV-17317 Add THD* parameter into Item::get_date() and stricter data type control to "fuzzydate" 2018-09-28 14:01:17 +04:00
Sergei Golubchik
5ae8fce50b Merge branch '10.1' into 10.2 2018-09-24 11:46:08 +02:00
Sergei Golubchik
1fc5a6f30c Merge branch '10.0' into 10.1 2018-09-23 12:58:11 +02:00
Alexander Barkov
80bcb05b24 Merge remote-tracking branch 'origin/5.5' into 10.0 2018-09-21 08:37:42 +04:00
Alexander Barkov
0c6455aa46 MDEV-17249 MAKETIME(-1e50,0,0) returns a wrong result 2018-09-20 16:02:58 +04:00
Alexander Barkov
8524bb6872 MDEV-14032 SEC_TO_TIME executes side effect two times
- Adding a helper class Sec6 to store (neg,seconds,microseconds)
- Adding a helper class VSec6 (Sec6  with a flag for "IS NULL")
- Wrapping related functions as methods of Sec6;
  * number_to_datetime()
  * number_to_time()
  * my_decimal2seconds()
  * Item::get_seconds()
  * A big piece of code in Item_func_sec_to_time::get_date()

- Using the new classes in places where second-to-temporal
  conversion takes place:
  * Field_timestamp::store(double)
  * Field_timestamp::store(longlong)
  * Field_timestamp_with_dec::store_decimal(my_decimal)
  * Field_temporal_with_date::store(double)
  * Field_temporal_with_date::store(longlong)
  * Field_time::store(double)
  * Field_time::store(longlong)
  * Field_time::store_decimal(my_decimal)
  * Field_temporal_with_date::store_decimal(my_decimal)
  * get_interval_value()
  * Item_func_sec_to_time::get_date()
  * Item_func_from_unixtime::get_date()
  * Item_func_maketime::get_date()
  This change simplifies these methods and functions a lot.

- Warnings are now sent at VSec6 initialization time, when the source
  data is available in its original data type representation.

  If Sec6::to_time() or Sec6::to_datetime() truncate data again during
  conversion to MYSQL_TIME, they send warnings, but only if no warnings
  were sent during VSec6 initialization. This helps prevents double warnings.

  The call for val_str() in Item_func_sec_to_time::get_date() is not
  needed any more, so it's removed. This change actually fixes the problem.

  As a good effect, FROM_UNIXTIME() and MAKETIME() now also send warnings
  in case if the seconds arguments is out of range. Previously these
  functions returned NULL silently.

- Splitting the code in the global function make_truncated_value_warning()
  into a number of methods THD::raise_warning_xxxx().
  This was needed to reuse the logic that chooses between:
  * ER_TRUNCATED_WRONG_VALUE
  * ER_WRONG_VALUE
  * ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
  for non-temporal data types (Sec6).

- Removing:
  * Item::get_seconds()
  * number_to_time_with_warn()
  as this code now resides inside methods of Sec6.

- Cleanup (changes that are not directly related to the fix):
  * Removing calls for field_name_or_null() and passing NULL instead
    in Item_func_hybrid_field_type::get_date_from_{int|real}_op,
    because Item_func_hybrid_field_type::field_name_or_null()
    always returns NULL
  * Replacing a number of calls for make_truncated_value_warning()
    to calls for THD::raise_warning_xxx(). In these places
    we know that the execution went through a certain
    branch of make_truncated_value_warning(),
    (e.g. the exact error code is known, or field name is always NULL,
     or field name is always not-NULL). So calls for the entire
    make_truncated_value_warning() after splitting are not necessary.
2018-08-09 06:31:05 +04:00
Monty
5d59a7b6a7 Fixed compile error on windows 2018-08-07 16:15:27 +03:00
Alexander Barkov
cb7b5fbf1c MDEV-16910 Add class VDec
Adding classes VDec and VDec2_lazy, according to the task description.
This patch removes around 250 duplicate code lines.
2018-08-07 10:48:42 +04:00
Alexander Barkov
2bbee0e1ec MDEV-16861 Split Item::update_null_value() into a new virtual method in Type_handler 2018-07-31 10:09:53 +04:00
Oleksandr Byelkin
de745ecf29 MDEV-11953: support of brackets in UNION/EXCEPT/INTERSECT operations 2018-07-04 19:13:55 +02:00
Alexander Barkov
e61568ee93 Merge remote-tracking branch 'origin/10.3' into 10.4 2018-07-03 14:02:05 +04:00
Alexander Barkov
e213b20e07 MDEV-16592 Change Item::with_sum_func from a member to a virtual method 2018-06-27 14:48:03 +04:00
Oleksandr Byelkin
083279f783 Merge commit '6b8802e8dd5467556a024d807a1df23940b00895' into bb-10.3-fix_len_dec 2018-06-19 14:51:50 +02:00
Oleksandr Byelkin
6b8802e8dd MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
fix_length_and_dec now return result (error/OK)
2018-06-15 10:31:30 +02:00
Alexander Barkov
c20cd68e60 MDEV-14630 Replace {STRING|INT|REAL|DECIMAL|DATE}_ITEM to CONST_ITEM 2018-06-06 14:09:06 +04:00
Alexander Barkov
f4dfc609cf MDEV-16388 Replace member Item::fixed to virtual method is_fixed() 2018-06-05 11:56:19 +04:00
Alexander Barkov
ab297744b7 Merge remote-tracking branch 'origin/10.3' into 10.4 2018-06-05 10:50:08 +04:00
Alexander Barkov
106f0b5798 MDEV-16385 ROW SP variable is allowed in unexpected context
The problem described in the bug report happened because the code
did not test check_cols(1) after fix_fields() in a few places.

Additionally, fix_fields() could be called multiple times for SP variables,
because they are all fixed at a early stage in append_for_log().

Solution:
1. Adding a few helper methods
   - fix_fields_if_needed()
   - fix_fields_if_needed_for_scalar()
   - fix_fields_if_needed_for_bool()
   - fix_fields_if_needed_for_order_by()
  and using it in many cases instead of fix_fields() where
  the "fixed" status is not definitely known to be "false".

2. Adding DBUG_ASSERT(!fixed) into Item_splocal*::fix_fields()
   to catch double execution.

3. Adding tests.

As a good side effect, the patch removes a lot of duplicate code (~60 lines):

   if (!item->fixed &&
       item->fix_fields(..) &&
       item->check_cols(1))
     return true;
2018-06-05 10:25:39 +04:00
Sergei Golubchik
c9061d1102 mysys: rename ME_xxx flags to match plugin api 2018-06-04 12:32:23 +02:00
Sergey Vojtovich
bc469a0bdf Cleanup isinf() portability checks
Original problem reported by Wlad: re-compilation of 10.3 on top of 10.2
build would cache undefined HAVE_ISINF from 10.2, whereas it is expected
to be 1 in 10.3.

std::isinf() seem to be available on all supported platforms.
2018-05-26 13:17:22 +04:00
Sergei Golubchik
c9717dc019 Merge branch '10.2' into 10.3 2018-05-11 13:15:10 +02:00
Sergei Golubchik
9b1824dcd2 Merge branch '10.1' into 10.2 2018-05-10 13:01:42 +02:00
Monty
30ebc3ee9e Add likely/unlikely to speed up execution
Added to:
- if (error)
- Lex
- sql_yacc.yy and sql_yacc_ora.yy
- In header files to alloc() calls
- Added thd argument to thd_net_is_killed()
2018-05-07 00:07:32 +03:00
Sergei Golubchik
9989c26bc9 Merge branch '10.0' into 10.1 2018-05-05 14:01:59 +02:00
Monty
7d6b55b99a Added version of lex_string_eq that compares with const char *
Change all my_stcasecmp() calls that uses lexical keywords to use
lex_string_eq. This is faster as we only call strcasecmp() for
strings of different lengths.

Removed not used function lex_string_syseq()
2018-04-30 14:24:48 +03:00
Sergei Golubchik
c4499a0391 Merge branch '5.5' into 10.0 2018-04-29 00:38:10 +02:00
Igor Babaev
eb057dce20 MDEV-15035 Wrong results when calling a stored procedure
multiple times with different arguments.

If the ON expression of an outer join is an OR formula with one
of the disjunct being a constant formula then the expression
cannot be null-rejected if the constant formula is true. Otherwise
it can be null-rejected and if so the outer join can be converted
into inner join. This optimization was added in the patch for
mdev-4817. Yet the code had a defect: if the query was used in
a stored procedure with parameters and the constant item contained
some of them then the value of this constant item depended on the
values of the parameters. With some parameters it may be true,
for others not. The validity of conversion to inner join is checked
only once and it happens only for the first call of procedure.
So if the  parameters in the first call allowed the conversion it
was done and next calls used the transformed query though there
could be calls whose parameters made the conversion invalid.

Fixed by cheking whether the constant disjunct in the ON expression
originally contained an SP parameter. If so the expression is not
considered as null-rejected. For this check a new item's attribute
was intruduced: Item::with_param. It is calculated for each item
by fix fields() functions.
Also moved the call of optimize_constant_subqueries() in
JOIN::optimize after the call of simplify_joins(). The reason
for this is that after the optimization introduced by the patch
for mdev-4817 simplify_joins() can use the results of execution
of non-expensive constant subqueries and this is not valid.
2018-04-25 09:22:06 -07:00
Marko Mäkelä
7396dfcca7 Merge 10.2 into 10.3 2018-04-24 20:59:57 +03:00
Marko Mäkelä
39a4985520 Remove most 'register' use in C++
Modern compilers (such as GCC 8) emit warnings that the
'register' keyword is deprecated and not valid C++17.

Let us remove most use of the 'register' keyword.
Code in 'extra/' is not touched.
2018-04-24 12:48:27 +03:00
Oleksandr Byelkin
14f84d2071 MDEV-13232: Assertion `(&(&share->intern_lock)->m_mutex)->count > 0 && pthread_equal(pthread_self(), (&(&share->intern_lock)->m_mutex)->thread)' failed in _ma_state_info_write
Limit length of result of "negative" operation to something reasonable
2018-04-23 12:48:13 +02:00
Alexander Barkov
a1a966fc0e Cleanup: renaming methods make_field(Send_field*) to make_send_field(..)
Renaming methods:
- Field::make_field(Send_field*) to make_send_field(..)
- Item::make_field(THD *,Send_field *) to make_send_field(..)
- Item::init_make_field(Send_field *, enum_field_type) to init_make_send_field(..)

These names looked similar to other functions that are used
for a very different purpose (creating Field instances):
- Public function "Field * make_field(..)"
- Method "Field *Column_defitinion::make_field(..)"

The rename makes it's easier to search the code using "grep".
2018-04-05 21:27:33 +04:00
Alexander Barkov
e263530bea MDEV-15597 Add class Load_data_outvar and avoid using Item::STRING_ITEM for Item_user_var_as_out_param detection 2018-03-20 13:02:44 +04:00
Alexander Barkov
9472f0f4a4 Adding "const" qualifier into a few methods and parameters in the LOAD code
Methods:
- Item_user_var_as_out_param::print_for_load()
- sql_exchange::escaped_given(void)

Parameters:
- sql_exchange in write_execute_load_query_log_event()
- sql_exchange in mysql_load()
- sql_exchange in Load_log_event::Load_log_event()

Also, removing cast to "char*" in a few places in
Load_log_event::Load_log_event()
2018-03-15 23:29:48 +04:00
Alexander Barkov
583eb96c24 MDEV-11952 Oracle-style packages: stage#5
- CREATE PACKAGE [BODY] statements are now
  entirely written to mysql.proc with type='PACKAGE' and type='PACKAGE BODY'.
- CREATE PACKAGE BODY now supports IF NOT EXISTS
- DROP PACKAGE BODY now supports IF EXISTS
- CREATE OR REPLACE PACKAGE [BODY] is now supported
- CREATE PACKAGE [BODY] now support the DEFINER clause:

    CREATE DEFINER user@host PACKAGE pkg ... END;
    CREATE DEFINER user@host PACKAGE BODY pkg ... END;

- CREATE PACKAGE [BODY] now supports SQL SECURITY and COMMENT clauses, e.g.:

    CREATE PACKAGE p1 SQL SECURITY INVOKER COMMENT "comment" AS ... END;

- Package routines are now created from the package CREATE PACKAGE BODY
  statement and don't produce individual records in mysql.proc.

- CREATE PACKAGE BODY now supports package-wide variables.
  Package variables can be read and set inside package routines.
  Package variables are stored in a separate sp_rcontext,
  which is cached in THD on the first packate routine call.

- CREATE PACKAGE BODY now supports the initialization section.

- All public routines (i.e. declared in CREATE PACKAGE)
  must have implementations in CREATE PACKAGE BODY

- Only public package routines are available outside of the package

- {CREATE|DROP} PACKAGE [BODY] now respects CREATE ROUTINE and ALTER ROUTINE
  privileges

- "GRANT EXECUTE ON PACKAGE BODY pkg" is now supported

- SHOW CREATE PACKAGE [BODY] is now supported

- SHOW PACKAGE [BODY] STATUS is now supported

- CREATE and DROP for PACKAGE [BODY] now works for non-current databases

- mysqldump now supports packages

- "SHOW {PROCEDURE|FUNCTION) CODE pkg.routine" now works for package routines

- "SHOW PACKAGE BODY CODE pkg" now works (the package initialization section)

- A new package body level MDL was added

- Recursive calls for package procedures are now possible

- Routine forward declarations in CREATE PACKATE BODY are now supported.

- Package body variables now work as SP OUT parameters

- Package body variables now work as SELECT INTO targets

- Package body variables now support ROW, %ROWTYPE, %TYPE
2018-02-25 21:08:19 +04:00
Sergei Golubchik
2732fcc608 Merge branch 'bb-10.2-ext' into 10.3 2018-02-23 08:43:34 +01:00
Alexander Barkov
aef530bb69 MDEV-15340 Wrong result HOUR(case_expression_with_time_and_datetime)
The problem was that Item_func_hybrid_field_type::get_date() did not
convert the result to the correct data type, so MYSQL_TIME::time_type
of the get_date() result could be not in sync with field_type().

Changes:
1. Adding two new classes Datetime and Date to store MYSQL_TIMESTAMP_DATETIME
   and MYSQL_TIMESTAMP_DATE values respectively
   (in addition to earlier added class Time, for MYSQL_TIMESTAMP_TIME values).
2. Adding Item_func_hybrid_field_type::time_op().
   It performs the operation using TIME representation,
   and always returns a MYSQL_TIME value with time_type=MYSQL_TIMESTAMP_TIME.
   Implementing time_op() for all affected children classes.
3. Fixing all implementations of date_op() to perform the operation
   using strictly DATETIME representation. Now they always return a MYSQL_TIME
   value with time_type=MYSQL_TIMESTAMP_{DATE|DATETIME},
   according to the result data type.
4. Removing assignment of ltime.time_type to mysql_timestamp_type()
   from all val_xxx_from_date_op(), because now date_op() makes sure
   to return a proper MYSQL_TIME value with a good time_type (and other member)
5. Adding Item_func_hybrid_field_type::val_xxx_from_time_op().
6. Overriding Type_handler_time_common::Item_func_hybrid_field_type_val_xxx()
   to call val_xxx_from_time_op() instead of val_xxx_from_date_op().
7. Modified Item_func::get_arg0_date() to return strictly a TIME value
   if TIME_TIME_ONLY is passed, or return strictly a DATETIME value otherwise.
   If args[0] returned a value of a different temporal type,
   (for example a TIME value when TIME_TIME_ONLY was not passed,
    or a DATETIME value when TIME_TIME_ONLY was passed), the conversion
   is automatically applied.
   Earlier, get_arg0_date() did not guarantee a result in
   accordance to TIME_TIME_ONLY flag.
2018-02-19 23:41:01 +04:00
Marko Mäkelä
cc3b5d1fe7 Merge bb-10.2-ext into 10.3 2018-02-15 11:48:30 +02:00
Marko Mäkelä
b006d2ead4 Merge bb-10.2-ext into 10.3 2018-02-15 10:22:03 +02:00
Alexander Barkov
c17a06abf8 MDEV-15310 Range optimizer does not work well for "WHERE temporal_column NOT IN (const_list)"
There were two problems related to the bug report:
1. Item_datetime::get_date() was not implemented.
   So execution went through val_int() followed
   by int-to-datetime or int-to-time conversion.
   This was the reason why the optimizer did not
   work well on data with fractional seconds.
2. Item_datetime::set() did not have a TIME specific code
   to mix months and days to hours after unpack_time().
   This is why the optimizer did not work well with negative
   TIME values, as well as huge time values.

Changes:

1. Overriding Item_datetime::get_date(), to return ltime.
   This fixes the problem N1.
2. Cleanup: Moving pack_time() and unpack_time() from
   sql-common/my_time.c and include/my_time.h to
   sql/sql_time.cc and sql/sql_time.h, as they are not needed
   on the client side.
3. Adding a new "enum_mysql_timestamp_type ts_type" parameter
   to unpack_time() and moving the TIME specific code to mix
   months and days with hours inside unpack_time().
   Adding a new "ts_type" parameter to Item_datetime::set(),
   to pass it from the caller down to unpack_time().
   So now the TIME specific code is automatically called
   from Item_datetime::set(). This fixes the problem N2.
   This change also helped to get rid of duplicate TIME specific code
   from other three places, where mixing month/days to hours
   was done immediately after unpack_time().
   Moving the DATE specific code to zero hhmmssff
   from Item_func_min_max::get_date_native to inside unpack_time(),
   for symmetry.
4. Removing the virtual method in_vector::result_type(),
   adding in_vector::type_handler() instead.
   This helps to get result_type(), field_type(),
   mysql_timestamp_type() of an in_vector easier.
   Passing type_handler()->mysql_timestamp_type() as
   a new parameter to Item_datetime::set() inside
   in_temporal::value_to_item().
5. Cleaup: Removing separate implementations of in_datetime::get_value()
   and in_time::get_value(). Adding a single implementation
   in_temporal::get_value() instead.
   Passing type_handler()->field_type() to get_value_internal().
2018-02-14 22:58:34 +04:00
Alexander Barkov
95d075a0e5 MDEV-15293 CAST(AS TIME) returns bad results for LAST_VALUE(),NAME_CONST(),SP variable 2018-02-13 20:37:31 +04:00
Alexander Barkov
991649e3ed A cleanup for MDEV-15287: removung unused code
The patch for MDEV-15287 made the code in Item_func_min_max::get_date_native()
dead, as the TIME data type is now handled in get_time_native().
Removing the TIME related code from get_date_native().
2018-02-13 09:33:06 +04:00
Alexander Barkov
4087683e1a MDEV-15287 Bad result for LEAST/GREATEST(datetime_alike_string, time) 2018-02-12 17:55:48 +04:00
Alexander Barkov
3cad31f2a7 Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext 2018-02-08 19:06:25 +04:00