MDEV-10865 COLLATE keyword doesn't work in PREPARE query

Fixing applying the COLLATE clause to a parameter caused an error error:
  COLLATION '...' is not valid for CHARACTER SET 'binary'

Fix:

- Changing the collation derivation for a non-prepared Item_param
  to DERIVATION_IGNORABLE.

- Allowing to apply any COLLATE clause to expressions with DERIVATION_IGNORABLE.
  This includes:
    1. A non-prepared Item_param
    2. An explicit NULL
    3. Expressions derived from #1 and #2

  For example:
    SELECT ? COLLATE utf8mb_unicode_ci;
    SELECT NULL COLLATE utf8mb_unicode_ci;
    SELECT CONCAT(?) COLLATE utf8mb_unicode_ci;
    SELECT CONCAT(NULL) COLLATE utf8mb_unicode_ci

- Additional change: preserving the collation of an expression when
  the expression gets assigned to a PS parameter and evaluates to SQL NULL.
  Before this change, the collation of the parameter was erroneously set
  to &my_charset_binary.

- Additional change: removing the multiplication to mbmaxlen from the
  fix_char_length_ulonglong() argument, because the multiplication already
  happens inside fix_char_length_ulonglong().
  This fixes a too large column size created for a COLLATE clause.
This commit is contained in:
Alexander Barkov 2024-07-02 17:59:59 +04:00
parent c91ec6a5c1
commit f6989d1767
11 changed files with 626 additions and 49 deletions

View file

@ -3076,6 +3076,12 @@ public:
bool aggregate(const DTCollation &dt, uint flags= 0);
bool set(DTCollation &dt1, DTCollation &dt2, uint flags= 0)
{ set(dt1); return aggregate(dt2, flags); }
bool merge_charset_and_collation(CHARSET_INFO *cs,
const Lex_extended_collation_st &cl,
my_repertoire_t repertoire);
bool merge_collation(const Lex_extended_collation_st &cl,
my_repertoire_t repertoire,
bool allow_ignorable_with_context_collation);
const char *derivation_name() const
{
switch(derivation)