diff options
author | Alexander Barkov <bar@mariadb.com> | 2022-01-10 18:05:55 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2022-01-21 19:28:48 +0400 |
commit | e4b302e436c0a1e0d477a8e8e8e513112fd3ec7f (patch) | |
tree | b8c180b94094978413fb3d6b7cdec3b803812b72 /sql/field.cc | |
parent | 28e166d6435741c46e0ea789657b739f78eb0425 (diff) | |
download | mariadb-git-e4b302e436c0a1e0d477a8e8e8e513112fd3ec7f.tar.gz |
MDEV-27018 IF and COALESCE lose "json" propertybb-10.5-bar-MDEV-27018
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.
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/sql/field.cc b/sql/field.cc index 2c768527ced..8fa3bbd538c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7277,6 +7277,19 @@ bool Field_longstr::send(Protocol *protocol) } +const Type_handler *Field_string::type_handler() const +{ + if (is_var_string()) + return &type_handler_var_string; + /* + This is a temporary solution and will be fixed soon (in 10.9?). + Type_handler_string_json will provide its own Field_string_json. + */ + if (Type_handler_json_common::has_json_valid_constraint(this)) + return &type_handler_string_json; + return &type_handler_string; +} + /* Copy a string and fill with space */ int Field_string::store(const char *from, size_t length,CHARSET_INFO *cs) @@ -7776,6 +7789,20 @@ en_fieldtype Field_string::tmp_engine_column_type(bool use_packed_rows) const const uint Field_varstring::MAX_SIZE= UINT_MAX16; + +const Type_handler *Field_varstring::type_handler() const +{ + /* + This is a temporary solution and will be fixed soon (in 10.9?). + Type_handler_varchar_json will provide its own Field_varstring_json + and Field_varstring_compressed_json + */ + if (Type_handler_json_common::has_json_valid_constraint(this)) + return &type_handler_varchar_json; + return &type_handler_varchar; +} + + /** Save the field metadata for varstring fields. @@ -8897,6 +8924,15 @@ void Field_blob::sort_string(uchar *to,uint length) */ const Type_handler *Field_blob::type_handler() const { + /* + This is a temporary solution and will be fixed soon (in 10.9?). + Type_handler_*blob_json will provide its own Field_blob_json + and Field_blob_compressed_json. + */ + if (Type_handler_json_common::has_json_valid_constraint(this)) + return Type_handler_json_common:: + json_blob_type_handler_by_length_bytes(packlength); + switch (packlength) { case 1: return &type_handler_tiny_blob; case 2: return &type_handler_blob; |