1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Commit Graph

442 Commits

Author SHA1 Message Date
forkfun
b8dbc264f0 Merge branch '13.0' into 'main' 2026-08-03 13:42:39 +02:00
forkfun
1a4bb1bbfd Merge branch '12.3' into '13.0' 2026-07-30 16:15:40 +02:00
forkfun
33240f3c96 Merge branch '11.8' into '12.3' 2026-07-30 11:41:55 +02:00
forkfun
eaca80bf32 Merge branch '11.4' into '11.8' 2026-07-29 12:27:46 +02:00
forkfun
08eeb6a417 Merge branch '10.11' into '11.4' 2026-07-28 13:14:38 +02:00
forkfun
a6c9db7cc2 MDEV-39380 Assertion `arg2_int >= 0' failed in Item_func_additive_op::result_precision
A 0xHHHH / b'..' literal keeps its hex_hybrid type through COALESCE/IF/CASE/...,
but was evaluated, sized and stored as a string, so it behaved differently from
a bare literal (10+COALESCE(0x31) gave 11, not 59).

Type_handler_hex_hybrid now implements the numeric side to match the bare
literal: val_int/val_real/val_decimal read bytes as a hybrid, Item_decimal_precision
returns the integer precision, Item_save_in_field stores like the bare literal.
The traditional type merge keeps the hybrid through a typeless NULL (as for BIT),
and Item_hybrid_func_fix_attributes attributes it binary/unsigned.
2026-07-23 13:38:02 +02:00
PranavKTiwari
40f93613dd MDEV-36896 Assertion 'marked_for_read()' failed in virtual my_time_t Field_timestamp0::get_timestamp(const uchar*, ulong*) const.
Problem:
SELECT on a table with a TIMESTAMP column and a virtual column
expression containing a field reference crashes with assertion
marked_for_read() in Field_timestamp0::get_timestamp.

Cause:
convert_item_for_comparison() physically evaluates the subject item
via Datetime dt(thd, subject, ...) to attempt a TIMESTAMP vs DATETIME
optimization. During vcol_fix_expr() at open_table() time,
used_tables_cache is not yet propagated up the item tree, causing
const_item() to return true incorrectly for a non-constant expression
containing a field reference. The evaluation then reads Field_timestamp0
before read bitmaps are initialized, violating marked_for_read().

Fix:
Add find_field_processor() to the Item base class, overridden in
Item_field to return true. Guard convert_item_for_comparison() with
a walk() check to skip physical evaluation if the subject subtree
contains any field reference.
2026-07-22 12:10:44 +05:30
Daniel Black
ecf1555da7 MDEV-40147 MSAN: use-of-uninitialized-value in my_time_compare
Field::get_date and Item::get_date can return true and not
have their ltime pointer structure initialized.

This was the case with Field_vers_trx_id::get_date.

Type_handler_time_common::stored_field_cmp_to_item rather
than doing a my_time_compare on uninitialized values can
return a non-equality (!=0) value for when the fetching of
Field or Item fails and avoid the call to my_time_compare.

Added checks for other invalid results before being
passed to my_time_compare.

Add nonnull as an attribute on my_time_compare and the
unpack_time function it used. Also pack_time since related
and it obviously requires a non-null argument.

Reviewed by: Alexey Midenkov
2026-07-20 17:04:39 +10:00
Kristian Nielsen
039def0efd Merge 13.0 to main
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-16 15:03:05 +02:00
Kristian Nielsen
37964c65fa Merge 12.3 to 13.0
This patch to mysqldump is only merged partially:

  commit 666ff1db36
  Author: Monty <monty@mariadb.org>
  Date:   Fri May 15 16:39:35 2026 +0300

      MDEV-39519 Change mariadb-dump to use SHOW REPLICA STATUS instead of SHOW SLAVE STATUS

The functionality for --dump-slave cannot be merged as the underlying
functionality was removed in this commit:

  commit 21c940d599
  Author: ParadoxV5 <paradox.ver5@gmail.com>
  Date:   Thu Dec 4 21:22:20 2025 -0700

      MDEV-37146 mariadb-dump: Replace SHOW SLAVE STATUS usage with information_schema.SLAVE_STATUS

Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-16 12:24:32 +02:00
Kristian Nielsen
fcc5fc8916 Merge 11.8 to 12.3
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 16:53:03 +02:00
Kristian Nielsen
420e28ce28 Merge 11.4 to 11.8
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 15:15:10 +02:00
Kristian Nielsen
85ec122c15 Merge 10.11 to 11.4
Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
2026-06-15 12:50:45 +02:00
Dave Gosselin
96ca4d3d5a MDEV-38158: Incorrect query result
When setup_copy_fields() needs to copy a non-aggregate function value,
it doesn't construct an Item_copy directly.  Instead, it calls
Type_handler::create_item_copy, which is a kind of factory.  The base
Type_handler::create_item_copy returns Item_copy_string.  Some type
handlers override it, like timestamp and fixed binary.  However, the
numeric type handlers (e.g., float, double, int, decimal) did not, so
they fell through to that base and got Item_copy_string.

A SELECT that aggregates will copy each non aggregate function value
into a temporary table through an Item_copy object, whose concrete
type is chosen by the create_item_copy method on the value's type
handler.  For numeric types that method returned Item_copy_string,
which stores the value as text.  A FLOAT keeps only FLT_DIG
significant digits as text, too few to reproduce its 24 bit mantissa,
so the copied value differed from the original.  With one row per
group, CAST(c1 AS FLOAT) - MIN(CAST(c1 AS FLOAT)) returned a large
number instead of zero.

Add Item_copy_real with Item_copy_float and Item_copy_double variants
that keep the value as a double, the same way Item_cache_real does, and
let the float and double type handlers create them.  This mirrors the
existing copy items for timestamp and fixed binary types.
2026-06-11 12:44:40 -04:00
Sergei Petrunia
a06be0288f MDEV-39768: Optimizer trace should use utf8mb4
JSON is utf8mb4. Change INFORMATION_SCHEMA.OPTIMIZER_TRACE.TRACE from
using utf8mb3 to mb4.

In order to do that:
- Add m_charset into Show::Type (NULL means "use the default")
- Make Type_handler_varchar::make_schema_field() check that field
  and use the specified charset/collation.
- Add a constructor to Show::Longtext that allows to specify the charset
- Make optimizer_trace use my_charset_utf8mb4_general_ci.
- In fill_optimizer_trace_info(), indicate that the trace we've
  collected is utf8mb4
2026-05-28 17:27:57 +03:00
Marko Mäkelä
e13d89949c Merge 12.3 into main 2026-05-05 13:14:42 +03:00
Raghunandan Bhat
e53c120d69 MDEV-36792: UBSAN load of null pointer and Assertion b == &type_handler_row || b == &type_handler_null in Arg_comparator::set_cmp_func when using ROW()
Problem:
  When a stored function returning `ROW` type is used as a `ROW` field
  and comapred against a non-ROW field, server crashes trying to
  aggregate types for comaprison in-
  `Type_collection_row::aggregate_for_comparison`.
  for example:
  CREATE FUNCTION f() RETURNS ROW TYPE OF t RETURN 1;
  SELECT ROW(f(),1)=ROW(1,1) AS eq;

Fix:
  Convert assertions in `Type_collection_row::aggregate_for_comparison`
  into a condition and return `NULL` if an invalid type combination is
  detected.
2026-04-27 14:38:22 +05:30
Alexander Barkov
90f8178f33 MDEV-10152 Add support for TYPE .. IS REF CURSOR
Adding support for the strict cursor data types:

Example 1a:
  TYPE rec0_t IS RECORD (a INT, VARCHAR(10));
  TYPE cur0_t IS REF CURSOR RETURN rec0_t;

Example 1b:
  TYPE rec0_t IS RECORD (a t1.a%TYPE, b t1.b%TYPE);
  TYPE cur0_t IS REF CURSOR RETURN rec0_t;

Example 1c:
  TYPE rec0_t IS RECORD (a INT, VARCHAR(10));
  r0 rec0_t;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

Example 1d:
  TYPE rec0_t IS RECORD (a t1.a%TYPE, b t1.b%TYPE);
  r0 rec0_t;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

Example2a:
  TYPE cur0_t IS REF CURSOR RETURN t1%ROWTYPE; -- t1 is a table

Example 2b:
  r0 t1%ROWTYPE;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

Example3a:
  CURSOR cursor_sample IS SELECT a,b FROM t1;
  TYPE cur0_t IS REF CURSOR RETURN cursor_sample%ROWTYPE;

Example3b:
  CURSOR cursor_sample IS SELECT a,b FROM t1;
  r0 cursor_sample%ROWTYPE;
  TYPE cur0_t IS REF CURSOR RETURN r0%TYPE;

If a cursor variable is declared with a RETURN clause then:
1. At OPEN type the data type of the SELECT list row is compared
  for compatibility with the cursor RETURN data type.
  The SELECT list row must be assignable to the RETURN type row.
  If case if assignability is not meet, an error is raised
  Assignability means:
  - The arity of the SELECT list must be equal to the arity
    of the RETURN clause
  - Every n-th field of the SELECT list must be assignable to the
    n-th field of the RETURN Clause

2. At FETCH time, the data is fetched in two steps:
  a. On the first step the data is fetched into a virtual table
     with the row type described in the RETURN clause
  b. On the second step the data is copied from the virtual table
     to the target fetch list. Data type conversion can happen
     on this step.

Change details:

Adding new methods:
- sp_cursor::check_assignability_to
- Virtual_tmp_table::check_assignability_from
- Virtual_tmp_table::sp_set_from_select_list
- Virtual_tmp_table::sp_save_in_vtable
- Virtual_tmp_table::sp_save_in_target_list
- LEX::check_ref_cursor_components
- LEX::make_sp_instr_copy_struct_for_last_context_variables
- LEX::declare_type_ref_cursor
- sp_cursor::Select_fetch_into_spvars::send_data_with_return_type

Adding new members:
- sp_instr_copen_by_ref::m_cursor_name
- Select_fetch_into_spvars::m_return_type
- Select_materialize::m_cursor_name
- Select_materialize::m_return_type

Adding new virtual methods:
- Item::resolve_spvar_cursor_rowtype
- Type_handler::Spvar_definition_resolve_type_refs
- Server_side_cursor::check_assignability_to
- Overriding Select_materialize::prepare to raise an error when the cursor
  returned data type is not compatible with the RETURN clause

Making these methods virtual:
- Field::check_assignability_from

Adding new classes:
- sp_type_def_ref
- RowTypeBuffer

Adding new constructors to:
- Spvar_definition

Adding new helper methods (e.g. to reuse the code)
- Field::store_field_maybe_null
- ChanBuffer::append_ulonglong
- sp_pcontext::set_type_for_last_context_variables

Minor changes:
- Making TABLE::export_structure const
- Overriding Item_splocal::type_extra_attributes. It was forgotten in earlier changes.

Adding new error messages
- ER_CANNOT_CAST_ON_IDENT1_ASSIGNMENT_FOR_OPERATION
- ER_CANNOT_CAST_ON_IDENT2_ASSIGNMENT_FOR_OPERATION
2026-04-06 15:16:38 +04:00
Alexander Barkov
bfcb303c05 MDEV-38871 Variable declarations accept unexpected data type attributes (lengh,dec,srid)
Some data types:
- RECORD
- assoc arrays
- SYS_REFCURSOR

erroneously accepted non-relevant attributes:
- length
- scale
- character set / collation
- REF_SYSTEM_ID

Fixing to raise an error.

Details:

- Overriding get_column_attributes() in Type_handler_row,
  Type_handler_sys_refcursor, Type_handler_assoc_array.

- Moving a piece of the old code into a new method
  Type_handler::check_data_type_attributes(), to reuse it
  for testing attributes for both plugin types and TYPE-def types.

- Reusing check_data_type_attributes() in methods
  * LEX::set_field_type_udt_or_typedef()
  * LEX::set_field_type_udt()

- Adding opt_binary into the rule field_type_all_with_typedefs,
  into the grammar branch for the plugin types, as XMLTYPE needs it.
2026-04-06 15:00:16 +04:00
Alexander Barkov
e581d1b5e0 MDEV-38436 Remove Type_handler::Column_definition_fix_attributes()
The method Type_handler::Column_definition_fix_attributes() was an
addition for Type_handler::Column_definition_set_attributes().

The code in virtual implementations of Column_definition_fix_attributes()
has now been joined to corresponding virtual implementations of
Column_definition_set_attributes().

After this change everything is done in Column_definition_set_attributes().

This makes the code clearer. Previous implementation was rather confusing.
For example, for temporal data types:
(1) After Column_definition_set_attributes():
  - Column_definition::length meant the fractional precision
  - Column_definition::decimals was set to 0
(2) After Column_definition_fix_attributes():
  - Column_definition::length means the full character length
  - Column_definition::decimals means the fractional precision

Now everything gets set to (2) right in Column_definition_set_attributes().
2026-04-06 15:00:16 +04:00
Alexander Barkov
97d2b7198c MDEV-38161 Refactor Type_extra_attributes: change void* for generic attributes to a better type
The first key point of this commit is changing Type_extra_attributes in the way
that the pointer to a generic attribute is now "Type_generic_attributes*" -
a pointer to a new class with vitrual method type_handler().

Before this change the pointer to a generic attribute was
"void *m_attr_const_void_ptr", which was error prone, as allowed
to pass a pointer to a wrong structure without control.

Another key point is that the SET/ENUM data type related structures
are now attributed by the changed class Type_typelib_attributes,
which now looks as follows:

  class Type_typelib_attributes: public Sql_alloc,
                                 public Type_generic_attributes,
                                 public TYPELIB

(with virtual method type_handler()), instead of being attributed by
TYPELIB directly.

Details:

- Using Column_definition's method typelib() where the member m_typelib
  was used directly. The related lines change anyway, because the member
  is renamed m_typelib_attr.

- Adding a new class Type_generic_attributes.
  Deriving the following classes from it:
  * Type_typelib_attributes
  * sp_type_def

- sp_type_def does not derive from Type_handler_hybrid_field_type any more,
  because the method type_handler() is now implemented virtually.

- Removing Type_extra_attributes::m_attr_const_void_ptr and
  adding Type_extra_attributes::m_attr_const_generic_attributes_ptr instead -
  a pointer to the new class Type_generic_attributes.
  Renaming methods to set and read it according to the new data type name.

- Type_typelib_attributes now derives from TYPELIB instead of having
  a pointer to TYPELIB.

- Adding a new class Type_typelib_ptr_attributes. It's a replacement for
  the old implementation of Type_typelib_attributes.

  Instead of deriving from Type_typelib_attributes, Field_enum now derives
  from Type_typelib_ptr_attributes. The latter can store/read itself into/from
  Type_extra_attributes. It's a bridge between the new Type_typelib_attributes
  and Type_extra_attributes.

- Changing parameter data type in a few methods in Field_enum from
  a pointer to TYPELIB to a pointer to Type_typelib_attributes.

- Removing typelib related methods from Type_extra_attributes.
  Moving this functionality into Type_typelib_ptr_attributes and
  Column_definition_attributes.
  This turns Type_extra_attributes into a data structure independent
  from any data type specific structures/methods.

- Adding methods:
   Column_definition_attributes::typelib_attr() - Column_definition derives it
   Column_definition_attributes::typelib()      - Column_definition derives it
   Type_typelib_ptr_attributes::typelib_attr()  - Field_enum derives it
   Type_typelib_ptr_attributes::typelib()       - Field_enum derives it

- Renaming the member Create_field::save_interval into
  Create_field::save_typelib_attr.
  Changing its data type from a pointer to TYPELIB into a pointer
  to Type_typelib_attributes pointer.

- Removing the method Type_typelib_attributes::store().
  Adding Type_typelib_ptr_attributes::save_in_type_extra_attributes() instead.
  The new method name makes the code more readable.
2026-04-06 15:00:16 +04:00
Marko Mäkelä
55b3dced05 Merge 11.8 into 12.3 2026-04-02 09:15:17 +03:00
Marko Mäkelä
1a144f713a Merge 11.4 into 11.8 2026-04-01 15:03:59 +03:00
Marko Mäkelä
7c5cac0d51 Merge 10.11 into 11.4 2026-04-01 10:49:05 +03:00
Marko Mäkelä
29be734aaf Merge 10.6 into 10.11 2026-03-31 11:48:18 +03:00
Marko Mäkelä
cb32aa9aa8 MDEV-16926 fixup: GCC 16 -Wmaybe-uninitialized
Year::year_precision(): Make static, so that VYear::VYear
and VYear_op::VYear_op() will avoid invoking this function with
an unnecessary "this" pointer to an uninitialized object.
2026-03-31 11:13:39 +03:00
Sergei Golubchik
3e97105975 13.0 deprecations
removed:

* DES encryption
* --secure-auth
* --old
* spider table options: bfz, btt, cmd, ctp, cwg, isa, ilm, ios, smd, stc, stl

extended under old-mode:

* YEAR(2), still available when old-mode=2_DIGIT_YEAR

un-deprecated:

* keep_files_on_create, originally (MDEV-23570) the idea was to make it
TRUE and deprecate. It cannot be removed when FALSE, but TRUE breaks
mariabackup.aria_backup where a table is altered from Aria to InnoDB
during a backup, so both t.MAD/t.MAI and t.ibd gets into a backup.
2026-02-16 21:55:18 +01:00
Alexander Barkov
607d72577a MDEV-38249 Refactoring: Change Item_save_in_value() not to return SQL NULL
Fixing the return type of Type_handler::Item_save_in_value() from
bool to void.

Adding a new method st_value::is_null().

This makes the code less confusing.
2026-02-09 15:28:04 +04:00
Sergei Golubchik
d653fcb564 Merge branch '11.8' into 12.2 2026-02-03 14:53:15 +01:00
Sergei Golubchik
9bfea48ce1 Merge branch '11.4' into 11.8 2026-01-31 14:08:54 +01:00
Sergei Golubchik
40f7084661 Merge branch '10.11' into 11.4 2026-01-28 21:52:18 +01:00
Alexander Barkov
a84b8ec5b1 MDEV-38626 Unexpected Data too long error on subselect as a multiplication argument
Item_singerow_subselect::fix_length_and_dec() incorrectly calculated
its Item::max_length when the underlying expression was Item_int.

The reason of the problem:
Item_int has an optimized max_length to make CONCAT(1) create a VARCHAR(1)
column rather than a VARCHAR(2) column. Its max_length does not include one
extra character for the sign in case the value is positive but the value
is not marked as Item::unsigned==true.

So copying max_length from the underlying Item_int (with value==9)
in cases like this:
  SELECT CONCAT((SELECT 9 FROM t0));
was not correct.

Implementing a new virtual method
  Type_handler::Item_type_std_attributes_generic(const Item *item)

- The default implementation just copies attributes from "item" as is.

- In case of Type_handler_int_result it evaluates max_length
  using item->decimal_precision() rather than item->max_length.
  This works correctly for both "optimized" items like Item_int and
  non-"optimized" Items whose max_length includes +1 for the sign
  in case of signed expressions.
2026-01-22 12:47:52 +04:00
Sergei Golubchik
27c98794bb Merge branch '11.8' into 12.2 2026-01-08 12:02:45 +01:00
Sergei Golubchik
c1fcedf443 Merge branch '11.4' into 11.8 2026-01-05 20:34:44 +01:00
Marko Mäkelä
678ff03ee7 Merge 10.11 into 11.4 2026-01-02 11:53:09 +02:00
Marko Mäkelä
8fab129382 Merge 10.6 into 10.11 2026-01-02 11:06:05 +02:00
Sergei Golubchik
0cd55ca5a5 MDEV-38242 crash when first COM_STMT_EXECUTE doesn't send types
all params are initialized to use Type_handler_null.
NULL params do not have a value to read from the packet buffer,
so their Item_param_set_param_func() should do nothing.

Type_handler_null inherits from Type_handler_string_result,
that is, Type_handler_null *must* override parent's
Item_param_set_param_func().
2025-12-26 16:42:34 +01:00
Oleksandr Byelkin
c976b527db Merge branch '11.8' into bb-12.1-release 2025-10-08 09:05:38 +02:00
Aleksey Midenkov
ff33f49d9a Merge 11.4 into 11.8 2025-09-29 18:25:09 +03:00
Marko Mäkelä
257f4b30ef Merge 10.11 into 11.4 2025-09-03 10:32:56 +03:00
Marko Mäkelä
b489d5f813 Merge 10.6 into 10.11 2025-08-26 14:24:31 +03:00
Marko Mäkelä
6bf1ed55e6 MDEV-37477: decimal_digits_t trips GCC -Wconversion
In commit fa7d4abf16
when the 16-bit type alias decimal_digits_t was introduced,
some incompatible use of the 32-bit uint data type was overlooked.

Only for converting Item_result_field::max_length (uint), we will use
explicit conversion.
2025-08-22 11:22:12 +03:00
Alexander Barkov
0fbdc56ee2 MDEV-36954 Improve error handling when a function-method/procedure-method is missing in stored routines
Fixing a confusing error message:

Unknown column 'assoc_array_var' in 'unknown_method'

to a clearer:

FUNCTION/PROCEDURE assoc_array_var.unknown_method does not exist
2025-08-01 18:03:20 +02:00
Alexander Barkov
e9d541f912 Cleanup#1 for MDEV-34319: DECLARE TYPE .. TABLE OF .. INDEX BY
- Checking that the key expression is compatible with the INDEX BY data type
  for assignment in expressions:
    assoc_array_variable(key_expr)
    assoc_array_variable(key_expr).field

  in all contexts: SELECT, assignment target, INTO target.
  Raising an error in case it's not compatible.

- Disallowing non-constant expressions as a key,
  as the key is evaluated during the fix_fields() time.

- Disallowing stored functions as a key:
    assoc_array(stored_function())
    assoc_array(stored_function()).field

  The underlying MariaDB code is not ready to call a stored function
  during the fix_fields() time. This will be fixed in a separate MDEV.

- Removing the move Assoc_array_data's constructor.
  Using the usual constructor instead.

- Setting m_key.thread_specific and m_value.thread_specific to true
  in the Assoc_array_data constructor. This is needed to get assoc array
  element data counted by the @@session.memory_used status variable.

  Adding DBUG_ASSERTs to make sure the thread_specific flag never
  disappears in Assoc_array_data members.

- Removing my_free(item) from Field_assoc_array::element_by_key.
  It was a remainder from an earlier patch version.
  In the current patch version all Items behind an assoc array are
  created on a mem_root. It's wrong to use my_free() with them.

- Adding a helper method Field_assoc_array::assoc_tree_search()

- Fixing assoc_array_var.delete() to work as a procedure
  rather than a function. It does not need SELECT/DO any more.

- Fixing the crash in a few ctype_xxx tests, caused by the grammar change.

- Fixing compilation failure on Windows

- Adding a new method LEX::set_field_type_udt_or_typedef()
  and removing duplicate code from sql_yacc.yy

- Renaming the grammar rule field_type_all_with_composites to
  field_type_all_with_typedefs

- Removing the grammar rule assoc_array_index_types.
  Changing the grammar to "INDEX_SYM BY field_type".

  Removing the grammar rule field_type_all_with_record.
  Allow field_type_all_with_typedefs as an assoc array element.

  Catching wrong index and element data types has been moved to
  Type_handler_assoc_array::Column_definition_set_attributes().
  It raises an SQL error on things like:
  * assoc array of assoc arrays in TABLE OF
  * index by a non-supported types in INDEX BY

- Removing four methods:
  * sp_type_def_list::type_defs_add_record()
  * sp_type_def_list::type_defs_add_composite2()
  * sp_pcontext::type_defs_declare_record()
  * sp_type_def_list::type_defs_declare_composite2()
  Adding two methods instead:
  * sp_type_def_list::type_defs_add()
  * sp_pcontext::type_defs_add()
  This allows to get rid of the duplicate code detecting data type
  declarations with the same name in the same sp_pcontext frame.

- Adding new methods:
  * LEX::declare_type_assoc_array()
  * LEX::LEX::declare_type_record()
  They create a type specific sp_type_def_xxx and the call the generic
  sp_pcontext::type_defs_add().

- m_key_def.sp_prepare_create_field() inside
  Field_assoc_array::create_fields() is now called for all key data types
  (not only for integers)

- Removing the assignment of key_def->charset in
  Type_handler_assoc_array::sp_variable_declarations_finalize().
  The charset is now evaluated in m_key_def.sp_prepare_create_field().

- Fixing Item_assoc_array::get_key() to set the character set of the "key"
  to utf8mb3 instead of binary

- Fixing Field_assoc_array::copy_and_convert_key() to set the key length
  limit in terms of the character length as specified in
  INDEX BY VARCHAR(N), instead of octet length. This is needed to make
  keys with multi-byte characters work correctly.
  Also it now raises different errors depending on the reason of the
  key conversion failures:
  * ER_INVALID_CHARACTER_STRING
  * ER_CANNOT_CONVERT_CHARACTER

- Changing the prototype for Type_handler_composite::key_to_lex_cstring() to

   virtual LEX_CSTRING key_to_lex_cstring(THD *thd,
                                          const sp_rcontext_addr &var,
                                          Item **key,
                                          String *buffer) const;
   * Now it returns a LEX_CSTRING, instead of getting it as an out parameter.
   * Gets an sp_rcontext_addr instead of "name" and "def"
   * Gets a String buffer which can be used to be passed to val_str(),
     or for character set conversion purposes.

- Removing Field_assoc_array::m_key_def, as all required information
  is available from Field_assoc_array::m_key_field.
  In Field_assoc_array::create_fields turning m_key_def to a local variable
  key_def.

- Fixing Field_assoc_array::copy_and_convert_key() to follow MariaDB coding
  style: only constants can be passed by-reference, not-constants should
  be passed by-pointer.

- Adding DBUG_ASSERTs into Type_handler_assoc_array::get_item()
  and Type_handler_assoc_array::get_or_create_item() that the passed
  key in "name" is well formed according to the charset of INDEX BY.

- Changing the error ER_TOO_LONG_KEY to ER_WRONG_STRING_LENGTH.
  The former prints length limit in bytes, which is not applicable
  for INDEX BY values, because its limit is in characters.
  Also, the latter is more verbose.

- Fixing the problem that these wrong uses of an assoc array variable:

    BEGIN
      assoc_var;
      assoc_var(1);
    END;

  raised a weird error message:
    ERROR 1054 (42S22): Unknown column 'assoc_var' in '(null)'

  Now a more readable parse error is raised.

- Adding a "Duplicate key" warning for the cases when assigning
  between two assoc arrays rejects some records due to different
  collations in their INDEX BY key definitions.

- Disallow INDEX OF propagation from VARCHAR to TEXT.
  The underlying code cannot handle TEXT.
  Adding tests.

- Adding a helper class StringBufferKey to pass to val_str() when
  a key value is evaluated.
  Fixing all val_str() calls to val_str(&buffer), as the former is
  not desirable.

- Fixing a wrong use of args[0]->null_value in
  Item_func_assoc_array_exists::val_bool()

- Fixing a problem that using TABLE OF TEXT crashed the server.
  Thanks to Iqbal Hassan for the proposed patch.

- Changes in Qualified_ident:
  * Fixing the Qualified_ident constructors to get all parst as
    Lex_ident_cli_st, rather than the first part as Lex_ident_cli_st
    with the following parts Lex_ident_sys.
    This makes the code more symmetric.
  * Fixing the grammar in sql_yacc.yy accordinly.
  * Fixing the data type storing the possition in the client query
    from "const char *" to Lex_ident_cli.
  * Adding a new method Qualified_ident::is_sane().
    It allows to reduce the code side in sql_yacc.yy.
    Thanks to Iqbal Hassan for the idea.

- Replacing qs_append() to append_ulonglong() in:
  * Item_method_func::print()
  * Item_splocal_assoc_array_element::print()
  * Item_splocal_assoc_array_element_field::print()

  These methods do not use reserve()/alloc(), so calling qs_append()
  was wrong and caused a crash.

- Changing the output formats of these methods:
  * Item_splocal_assoc_array_element::print()
  * Item_splocal_assoc_array_element_field::print()
  not to print the key two times.
  Also moving the `@123` part (the variable offset) immediately
  after the variabl name and before the `[key]` part.

- Fixing a memory leak happened when trying to insert a duplicate
  key into an assoc array. Also adding a new "THD *" parameter to
  Field_assoc_array::insert_element(). Thanks to Iqbal Hassan for the fix.
  Adding a test into sp-assoc-array-ctype.test.

- In  Field_assoc_array::create_fields: m_element_field->field_name is now
  set for all element data types (not only for records).
  This fixed a wrong variable name in warnings. Adding tests.

- Adding tests:
  * Adding tests for assoc array elements in UNIONs.

  * Copying from an assoc array with a varchar key
    to an assoc array with a shorter varchar key.

  * A relatively big associative array.

  * Memory usage for x86_64.

  * Package variable as assoc array keys.

  * Character set conversion

  * TABLE OF TEXT

  * TABLE OF VARCHAR(>64k bytes) propagation to TABLE OF TEXT.

  * TEXT element fields in an array of records.

  * VARCHAR->TEXT propagation in elements in an array of records.

  * Some more tests
2025-08-01 18:03:20 +02:00
Iqbal Hassan
41014a4ecd MDEV-34319: DECLARE TYPE .. TABLE OF .. INDEX BY in stored routines
This patch adds support for associative arrays in stored procedures
for sql_mode=ORACLE.
The syntax follows Oracle's PL/SQL syntax for associative arrays -
TYPE assoc_array_t IS TABLE OF VARCHAR2(100) INDEX BY INTEGER;
or
TYPE assoc_array_t IS TABLE OF record_t INDEX BY VARCHAR2(100);
where record_t is a record type.

The following functions were added for associative arrays:
- COUNT - Retrieve the number of elements within the arra
- EXISTS - Check whether given key exists in the array
- FIRST - Retrieve the first key in the array
- LAST - Retrieve the last key in the array
- PRIOR - Retrieve the key before the given key
- NEXT - Retrieve the key after the given key
- DELETE - Remove the element with the given key or remove all elements
if no key is given

The arrays/elements can be initialized with the following methods:
- Constructor
i.e. array:= assoc_array_t('key1'=>1, 'key2'=>2, 'key3'=>3)
- Assignment
i.e. array(key):= record_t(1, 2)
- SELECT INTO
i.e. SELECT x INTO array(key)

TODOs:
- Nested tables are not supported yet.
i.e. TYPE assoc_array_t IS TABLE OF other_assoc_array_t INDEX BY INTEGER;
- Associative arrays comparisons are not supported yet.
2025-08-01 18:03:20 +02:00
Alexander Barkov
a91b78049a MDEV-36705 Preparations for associative arrays (MDEV-34319)
- Moving the definition of "class Type_handler_row" into a new file
  sql_type_row.h. Also moving *some* of its methods into sql_type_row.cc.
  The rest of the methods will be moved in the patch for MDEV-34319.
  Moving the definition of my_var_sp_row_field into sql_type_row.cc.

- Fixing the grammar for function_call_generic to get the first
  production as "ident_cli_func" rather than "ident_func".
  The upcoming patch needs to know the position of the function name
  within the client query.

- Adding new data types to store data types defined by "TYPE" declarations:

  * sp_type_def
  * sp_type_def_list

  sp_pcontext now derives from sp_type_def_list

- A new virtual method in Field:

  virtual Item_field *make_item_field_spvar(THD *thd,
                                            const Spvar_definition &def);
  Using it in sp_rcontext::init_var_items().

- Fixing my_var_sp to get sp_rcontext_addr in the parameter
  instead of two separate parameters (rcontext_handler + offset).

- Adding new virtual methods in my_var:

  virtual bool set_row(THD *thd, List<Item> &select_list);

  It's used when a select_list record is assigned to a
  single composite variable, such as ROW, specified in the INTO clause.
  Using it in select_dumpvar::send_data().

  virtual bool check_assignability(THD *thd,
                                   const List<Item> &select_list,
                                   bool *assign_as_row) const;

  It's used to check if the select_list is compatible with
  a single INTO variable, in select_dumpvar::prepare().

- Fixing LEX methods create_outvar() to get identifiers
  a Lex_ident_sys_st values instead of generic LEX_CSTRING values.

- Adding virtual methods in Type_handler:

  // Used in Item_func_null_predicate::check_arguments()
  virtual bool has_null_predicate() const;

  // Used in LEX::sp_variable_declarations_finalize()
  virtual bool sp_variable_declarations_finalize(THD *thd,
                                                 LEX *lex, int nvars,
                                                 const Column_definition &def)
                                                                        const;
  // Handle SELECT 1 INTO spvar;
  virtual my_var *make_outvar(THD *thd,
                              const Lex_ident_sys_st &name,
                              const sp_rcontext_addr &addr,
                              sp_head *sphead,
                              bool validate_only) const;

  // Handle SELECT 1 INTO spvar.field;
  virtual my_var *make_outvar_field(THD *thd,
                                    const Lex_ident_sys_st &name,
                                    const sp_rcontext_addr &addr,
                                    const Lex_ident_sys_st &field,
                                    sp_head *sphead,
                                    bool validate_only) const;

  // create the value in: DECLARE var rec_t DEFAULT rec_t(1,'c');
  virtual Item *make_typedef_constructor_item(THD *thd,
                                              const sp_type_def &def,
                                              List<Item> *arg_list) const;

- A new helper method:
  Row_definition_list *Row_definition_list::deep_copy(THD *thd) const;
2025-08-01 18:01:20 +02:00
Alexander Barkov
c5d8b9963a MDEV-36716 A case expression with ROW arguments in THEN crashes
The patch for SYS_REFCURSOR (MDEV-20034) overrode these methods:
- Item_func_case_searched::check_arguments()
- Item_func_if::check_arguments()

to validate WHEN-style arguments (e.g. args[0] in case of IF) for being
able to return a boolean result.

However, this unintentionally removed the test for the THEN-style arguments
that they are not expressions of the ROW data type.

This led to a crash inside Type_handler_hybrid_field_type::aggregate_for_result
on a DBUG_ASSERT that arguments are not of the ROW data type.

Fix:

The fix restores blocking ROW expressions in the not supported cases,
to avoid the DBUG_ASSERT and to raise an SQL error instead.

Blocking ROW_RESULT expressions is done per Item_func_case_expression
descendant individually, instead of blocking any ROW_RESULT arguments
at the Item_func_case_expression level.

The fix is done taking into account the upcoming patch for associative arrays
(MDEV-34319). It should be possible to pass associative array expressions into
some hybrid type functions, where ROW type expressions are not possible.

As a side effect, some lecagy ER_OPERAND_COLUMNS changed to
a newer ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION

Changes in the top affected class Item_func_case_expression:

- item_func.h:
  Overriding Item_func_case_expression::check_arguments() to return false,
  without checking any arguments. Descendant validate arguments
  in a various different ways. No needs to block all non-scalar data type at
  this level, to prevent disallowing associative arrays.

Changes in descendants:

- item_cmpfunc.cc:
  Adding a test in Item_func_case_simple::aggregate_switch_and_when_arguments()
  preventing passing ROW_RESULT expression in predicant and WHEN in a
  simple CASE:
    CASE predicant WHEN when1 THEN .. WHEN when2 THEN .. END;
  This is not supported yet. Should be preferrably fixed before MDEV-34319.

- item_cmpfunc.cc:
  Calling args[0]->type_handler()->Item_hybrid_func_fix_attributes()
  from Item_func_nullif::fix_length_and_dec().
  This prevents a ROW expression to be passed to args[0] of NULLIF().
  But will allow to pass associative arrays.

  args[1] is still only checked to be comparable with args[0].
  No needs to add additional tests for it.

- item_cmpfunc.h:
  Adding a call for Item_hybrid_func_fix_attributes() in
  Item_func_case_abbreviation2::cache_type_info().
  This prevents calling the descendant functions with
  a ROW expression in combination with an explicit NULL
  in the THEN-style arguments (but will allow to pass associative arrays):

    IFNULL(row_expression, NULL)
    IFNULL(NULL, row_expression)
    IF(switch, row_expression, NULL)
    IF(switch, NULL, row_expression)
    NVL2(switch, row_expression, NULL)
    NVL2(switch, NULL, row_expression)
  Adding a THD* argument into involved methods.

- item_cmpfunc.h:
  Overriding Item_func_case_abbreviation2_switch::check_arguments() to
  check that the first argument in IF() and NVL2() can return bool.
  Removing Item_func_if::check_arguments(), as it become redundant.

- sql_type.cc:
  Fixing sql_type.cc not to disallow items[0] with ROW_RESULT.
  This makes it call Item_hybrid_func_fix_attributes() at the end,
  which block ROW arguments into THEN-style arguments of hybrid functions.
  But this will allow to pass Type_handler_assoc_array expressions.

- sql_type.cc:
  Changing Type_handler_row::Item_hybrid_func_fix_attributes to raise the
  ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION error instead of the DBUG_ASSERT.
2025-05-05 19:44:04 +04:00
Alexander Barkov
f11504af51 MDEV-20034 Add support for the pre-defined weak SYS_REFCURSOR
This patch adds support for SYS_REFCURSOR (a weakly typed cursor)
for both sql_mode=ORACLE and sql_mode=DEFAULT.

Works as a regular stored routine variable, parameter and return value:

- can be passed as an IN parameter to stored functions and procedures
- can be passed as an INOUT and OUT parameter to stored procedures
- can be returned from a stored function

Note, strongly typed REF CURSOR will be added separately.

Note, to maintain dependencies easier, some parts of sql_class.h
and item.h were moved to new header files:

- select_results.h:
  class select_result_sink
  class select_result
  class select_result_interceptor

- sp_cursor.h:
  class sp_cursor_statistics
  class sp_cursor

- sp_rcontext_handler.h
  class Sp_rcontext_handler and its descendants

The implementation consists of the following parts:
- A new class sp_cursor_array deriving from Dynamic_array

- A new class Statement_rcontext which contains data shared
  between sub-statements of a compound statement.
  It has a member m_statement_cursors of the sp_cursor_array data type,
  as well as open cursor counter. THD inherits from Statement_rcontext.

- A new data type handler Type_handler_sys_refcursor in plugins/type_cursor/
  It is designed to store uint16 references -
  positions of the cursor in THD::m_statement_cursors.

- Type_handler_sys_refcursor suppresses some derived numeric features.
  When a SYS_REFCURSOR variable is used as an integer an error is raised.

- A new abstract class sp_instr_fetch_cursor. It's needed to share
  the common code between "OPEN cur" (for static cursors) and
  "OPER cur FOR stmt" (for SYS_REFCURSORs).

- New sp_instr classes:
  * sp_instr_copen_by_ref      - OPEN sys_ref_curor FOR stmt;
  * sp_instr_cfetch_by_ref     - FETCH sys_ref_cursor INTO targets;
  * sp_instr_cclose_by_ref     - CLOSE sys_ref_cursor;
  * sp_instr_destruct_variable - to destruct SYS_REFCURSOR variables when
                                 the execution goes out of the BEGIN..END block
                                 where SYS_REFCURSOR variables are declared.
- New methods in LEX:
  * sp_open_cursor_for_stmt   - handles "OPEN sys_ref_cursor FOR stmt".
  * sp_add_instr_fetch_cursor - "FETCH cur INTO targets" for both
                                static cursors and SYS_REFCURSORs.
  * sp_close - handles "CLOSE cur" both for static cursors and SYS_REFCURSORs.

- Changes in cursor functions to handle both static cursors and SYS_REFCURSORs:
  * Item_func_cursor_isopen
  * Item_func_cursor_found
  * Item_func_cursor_notfound
  * Item_func_cursor_rowcount

- A new system variable @@max_open_cursors - to limit the number
  of cursors (static and SYS_REFCURSORs) opened at the same time.
  Its allowed range is [0-65536], with 50 by default.

- A new virtual method Type_handler::can_return_bool() telling
  if calling item->val_bool() is allowed for Items of this data type,
  or if otherwise the "Illegal parameter for operation" error should be raised
  at fix_fields() time.

- New methods in Sp_rcontext_handler:
  * get_cursor()
  * get_cursor_by_ref()

- A new class Sp_rcontext_handler_statement to handle top level statement
  wide cursors which are shared by all substatements.

- A new virtual method expr_event_handler() in classes Item and Field.
  It's needed to close (and make available for a new OPEN)
  unused THD::m_statement_cursors elements which do not have any references
  any more. It can happen in various moments in time, e.g.
  * after evaluation parameters of an SQL routine
  * after assigning a cursor expression into a SYS_REFCURSOR variable
  * when leaving a BEGIN..END block with SYS_REFCURSOR variables
  * after setting OUT/INOUT routine actual parameters from formal
    parameters.
2025-04-19 10:59:58 +04:00
Sergey Vojtovich
feb1cf9086 Corrections to parent "fix typos" commmit 2025-03-14 12:08:56 +04:00
Vasilii Lakhin
717c12de0e Fix typos in C comments inside sql/ 2025-03-14 12:08:56 +04:00