1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-27018 IF and COALESCE lose "json" property

Hybrid functions (IF, COALESCE, etc) did not preserve the JSON property
from their arguments. The same problem was repeatable for single row subselects.

The problem happened because the method Item::is_json_type() was inconsistently
implemented across the Item hierarchy. For example, Item_hybrid_func
and Item_singlerow_subselect did not override is_json_type().

Solution:

- Removing Item::is_json_type()

- Implementing specific JSON type handlers:
  Type_handler_string_json
  Type_handler_varchar_json
  Type_handler_tiny_blob_json
  Type_handler_blob_json
  Type_handler_medium_blob_json
  Type_handler_long_blob_json

- Reusing the existing data type infrastructure to pass JSON
  type handlers across all item types, including classes Item_hybrid_func
  and Item_singlerow_subselect. Note, these two classes themselves do not
  need any changes!

- Extending the data type infrastructure so data types can inherit
  their properties (e.g. aggregation rules) from their base data types.
  E.g. VARCHAR/JSON acts as VARCHAR, LONGTEXT/JSON acts as LONGTEXT
  when mixed to a non-JSON data type. This is done by:
    - adding virtual method Type_handler::type_handler_base()
    - adding a helper class Type_handler_pair
    - refactoring Type_handler_hybrid_field_type methods
      aggregate_for_result(), aggregate_for_min_max(),
      aggregate_for_num_op() to use Type_handler_pair.

This change also fixes:

  MDEV-27361 Hybrid functions with JSON arguments do not send format metadata

Also, adding mtr tests for JSON replication. It was not covered yet.
And the current patch changes the replication code slightly.
This commit is contained in:
Alexander Barkov
2022-01-10 18:05:55 +04:00
parent 28e166d643
commit e4b302e436
33 changed files with 4015 additions and 100 deletions

View File

@ -2,7 +2,7 @@
#define SQL_TYPE_H_INCLUDED
/*
Copyright (c) 2015 MariaDB Foundation.
Copyright (c) 2015, 2020, MariaDB Corporation.
Copyright (c) 2015, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -45,6 +45,7 @@ class Item_param;
class Item_cache;
class Item_copy;
class Item_func_or_sum;
class Item_sum;
class Item_sum_hybrid;
class Item_sum_sum;
class Item_sum_avg;
@ -3764,6 +3765,14 @@ public:
incompatible data type.
*/
virtual bool is_param_long_data_type() const { return false; }
/*
The base type handler "this" is derived from.
"This" inherits aggregation rules from the base type handler.
*/
virtual const Type_handler *type_handler_base() const
{
return NULL;
}
virtual const Type_handler *type_handler_for_comparison() const= 0;
virtual const Type_handler *type_handler_for_native_format() const
{
@ -7471,6 +7480,41 @@ public:
const Type_handler *h0, const Type_handler *h1);
};
class Type_handler_pair
{
const Type_handler *m_a;
const Type_handler *m_b;
public:
Type_handler_pair(const Type_handler *a,
const Type_handler *b)
:m_a(a), m_b(b)
{ }
const Type_handler *a() const { return m_a; }
const Type_handler *b() const { return m_b; }
/*
Change both handlers to their parent data type handlers, if available.
For example, VARCHAR/JSON -> VARCHAR.
@returns The number of handlers changed (0,1 or 2).
*/
bool to_base()
{
bool rc= false;
const Type_handler *na= m_a->type_handler_base();
const Type_handler *nb= m_b->type_handler_base();
if (na)
{
m_a= na; rc= true;
}
if (nb)
{
m_b= nb; rc= true;
}
return rc;
}
};
/*
Helper template to simplify creating builtin types with names.
Plugin types inherit from Type_handler_xxx types that do not set the name in