diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-02-14 14:29:55 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-02-15 19:46:58 +0400 |
commit | 62c0ac2da66f8e26d5bbf79f3a7dac56cad34f5e (patch) | |
tree | 236c9941fda1fc889ccc9f684c418bf1720f9a17 /sql | |
parent | 568dd5293ca7ef34f74d5d0529288edba6b7281e (diff) | |
download | mariadb-git-62c0ac2da66f8e26d5bbf79f3a7dac56cad34f5e.tar.gz |
A cleanup for MDEV-13916 Enforce check constraint on JSON type
1. Renaming Type_handler_json to Type_handler_json_longtext
There will be other JSON handlers soon, e.g. Type_handler_json_varchar.
2. Making the code more symmetric for data types:
- Adding a new virtual method
Type_handler::Column_definition_validate_check_constraint()
- Moving JSON-specific code from sql_yacc.yy to
Type_handler_json_longtext::Column_definition_validate_check_constraint()
3. Adding new files sql_type_json.cc and sql_type_json.h
and moving Type_handler+JSON related code into these files.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sql/field.cc | 12 | ||||
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/sql_lex.cc | 18 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_type.cc | 12 | ||||
-rw-r--r-- | sql/sql_type.h | 15 | ||||
-rw-r--r-- | sql/sql_type_json.cc | 55 | ||||
-rw-r--r-- | sql/sql_type_json.h | 38 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 7 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 7 |
11 files changed, 125 insertions, 45 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 0befcd25204..18b7cc3176d 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -132,7 +132,7 @@ SET (SQL_SOURCE rpl_gtid.cc rpl_parallel.cc semisync.cc semisync_master.cc semisync_slave.cc semisync_master_ack_receiver.cc - sql_type.cc + sql_type.cc sql_type_json.cc item_windowfunc.cc sql_window.cc sql_cte.cc item_vers.cc diff --git a/sql/field.cc b/sql/field.cc index 89b04c4d795..5289798cebf 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10501,6 +10501,13 @@ bool Column_definition::fix_attributes_temporal_with_time(uint int_part_length) } +bool Column_definition::validate_check_constraint(THD *thd) +{ + return check_constraint && + check_expression(check_constraint, &field_name, VCOL_CHECK_FIELD); +} + + bool Column_definition::check(THD *thd) { DBUG_ENTER("Column_definition::check"); @@ -10515,9 +10522,8 @@ bool Column_definition::check(THD *thd) DBUG_RETURN(TRUE); } - if (check_constraint && - check_expression(check_constraint, &field_name, VCOL_CHECK_FIELD)) - DBUG_RETURN(1); + if (type_handler()->Column_definition_validate_check_constraint(thd, this)) + DBUG_RETURN(TRUE); if (default_value) { diff --git a/sql/field.h b/sql/field.h index 25d9f0e0ca4..30098afe953 100644 --- a/sql/field.h +++ b/sql/field.h @@ -4675,6 +4675,7 @@ public: bool fix_attributes_bit(); bool check(THD *thd); + bool validate_check_constraint(THD *thd); bool stored_in_db() const { return !vcol_info || vcol_info->stored_in_db; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index f5e37446b58..df4d8d7b94c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9587,21 +9587,3 @@ bool LEX::sp_proc_stmt_statement_finalize(THD *thd, bool no_lookahead) lip->get_tok_start()); return LEX::sp_proc_stmt_statement_finalize_buf(thd, qbuf); } - - -/** - Create JSON_VALID(field_name) expression -*/ - -Virtual_column_info *make_json_valid_expr(THD *thd, LEX_CSTRING *field_name) -{ - Lex_ident_sys_st str; - Item *field, *expr; - str.set_valid_utf8(field_name); - if (unlikely(!(field= thd->lex->create_item_ident_field(thd, NullS, NullS, - &str)))) - return 0; - if (unlikely(!(expr= new (thd->mem_root) Item_func_json_valid(thd, field)))) - return 0; - return add_virtual_expression(thd, expr); -} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fc451b21816..3f3fef8a414 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -148,7 +148,7 @@ public: bool copy_or_convert(THD *thd, const Lex_ident_cli_st *str, CHARSET_INFO *cs); bool is_null() const { return str == NULL; } bool to_size_number(ulonglong *to) const; - void set_valid_utf8(LEX_CSTRING *name) + void set_valid_utf8(const LEX_CSTRING *name) { DBUG_ASSERT(Well_formed_prefix(system_charset_info, name->str, name->length).length() == name->length); @@ -4640,6 +4640,5 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, void sp_create_assignment_lex(THD *thd, bool no_lookahead); bool sp_create_assignment_instr(THD *thd, bool no_lookahead); -Virtual_column_info *make_json_valid_expr(THD *thd, LEX_CSTRING *field_name); #endif /* MYSQL_SERVER */ #endif /* SQL_LEX_INCLUDED */ diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 1812294ed46..4906eee064d 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -66,7 +66,6 @@ Type_handler_tiny_blob type_handler_tiny_blob; Type_handler_medium_blob type_handler_medium_blob; Type_handler_long_blob type_handler_long_blob; Type_handler_blob type_handler_blob; -Type_handler_json type_handler_json; static Type_handler_blob_compressed type_handler_blob_compressed; Type_handler_interval_DDhhmmssff type_handler_interval_DDhhmmssff; @@ -2328,6 +2327,17 @@ Field *Type_handler_set::make_conversion_table_field(TABLE *table, ((const Field_enum*) target)->typelib, target->charset()); } + +/*************************************************************************/ + +bool Type_handler:: + Column_definition_validate_check_constraint(THD *thd, + Column_definition * c) const +{ + return c->validate_check_constraint(thd); +} + + /*************************************************************************/ bool Type_handler_null:: Column_definition_fix_attributes(Column_definition *def) const diff --git a/sql/sql_type.h b/sql/sql_type.h index 7216b24835d..23a3f7fccb7 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -78,6 +78,7 @@ struct Schema_specification_st; struct TABLE; struct SORT_FIELD_ATTR; class Vers_history_point; +class Virtual_column_info; #define my_charset_numeric my_charset_latin1 @@ -3280,7 +3281,6 @@ public: return true; } virtual bool is_scalar_type() const { return true; } - virtual bool is_json_type() const { return false; } virtual bool can_return_int() const { return true; } virtual bool can_return_decimal() const { return true; } virtual bool can_return_real() const { return true; } @@ -3338,6 +3338,10 @@ public: // Automatic upgrade, e.g. for ALTER TABLE t1 FORCE virtual void Column_definition_implicit_upgrade(Column_definition *c) const { } + // Validate CHECK constraint after the parser + virtual bool Column_definition_validate_check_constraint(THD *thd, + Column_definition *c) + const; // Fix attributes after the parser virtual bool Column_definition_fix_attributes(Column_definition *c) const= 0; /* @@ -5895,14 +5899,6 @@ public: }; -class Type_handler_json: public Type_handler_long_blob -{ -public: - virtual ~Type_handler_json() {} - virtual bool is_json_type() const { return true; } -}; - - class Type_handler_blob: public Type_handler_blob_common { static const Name m_name_blob; @@ -6231,7 +6227,6 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_hex_hybrid type_handler_hex_hybrid; extern MYSQL_PLUGIN_IMPORT Type_handler_tiny_blob type_handler_tiny_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_medium_blob type_handler_medium_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_long_blob type_handler_long_blob; -extern MYSQL_PLUGIN_IMPORT Type_handler_json type_handler_json; extern MYSQL_PLUGIN_IMPORT Type_handler_blob type_handler_blob; extern MYSQL_PLUGIN_IMPORT Type_handler_bool type_handler_bool; diff --git a/sql/sql_type_json.cc b/sql/sql_type_json.cc new file mode 100644 index 00000000000..f53a247d816 --- /dev/null +++ b/sql/sql_type_json.cc @@ -0,0 +1,55 @@ +/* + Copyright (c) 2019, MariaDB + + 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 the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "sql_type_json.h" +#include "sql_class.h" + + +Type_handler_json_longtext type_handler_json_longtext; + + +/** + Create JSON_VALID(field_name) expression +*/ + +Virtual_column_info * +Type_handler_json_longtext::make_json_valid_expr(THD *thd, + const LEX_CSTRING *field_name) + const +{ + Lex_ident_sys_st str; + Item *field, *expr; + str.set_valid_utf8(field_name); + if (unlikely(!(field= thd->lex->create_item_ident_field(thd, NullS, NullS, + &str)))) + return 0; + if (unlikely(!(expr= new (thd->mem_root) Item_func_json_valid(thd, field)))) + return 0; + return add_virtual_expression(thd, expr); +} + + +bool Type_handler_json_longtext:: + Column_definition_validate_check_constraint(THD *thd, + Column_definition * c) const +{ + if (!c->check_constraint && + !(c->check_constraint= make_json_valid_expr(thd, &c->field_name))) + return true; + return Type_handler::Column_definition_validate_check_constraint(thd, c); +} diff --git a/sql/sql_type_json.h b/sql/sql_type_json.h new file mode 100644 index 00000000000..6c4ee8cb2eb --- /dev/null +++ b/sql/sql_type_json.h @@ -0,0 +1,38 @@ +#ifndef SQL_TYPE_JSON_INCLUDED +#define SQL_TYPE_JSON_INCLUDED +/* + Copyright (c) 2019, MariaDB + + 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 the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "mariadb.h" +#include "sql_type.h" + +class Type_handler_json_longtext: public Type_handler_long_blob +{ + Virtual_column_info *make_json_valid_expr(THD *thd, + const LEX_CSTRING *field_name) + const; +public: + virtual ~Type_handler_json_longtext() {} + bool Column_definition_validate_check_constraint(THD *thd, + Column_definition *c) const; +}; + +extern MYSQL_PLUGIN_IMPORT + Type_handler_json_longtext type_handler_json_longtext; + +#endif // SQL_TYPE_JSON_INCLUDED diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0a2961b8154..00566c463e8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -68,6 +68,7 @@ #include "sql_lex.h" #include "sql_sequence.h" #include "my_base.h" +#include "sql_type_json.h" /* this is to get the bison compilation windows warnings out */ #ifdef _MSC_VER @@ -6689,10 +6690,6 @@ field_spec: $$= $<create_field>2; $$->check_constraint= $4; - if (!$4 && lex->last_field->type_handler()->is_json_type() && - !($$->check_constraint= make_json_valid_expr(thd, - &$$->field_name))) - MYSQL_YYABORT; if (unlikely($$->check(thd))) MYSQL_YYABORT; @@ -7086,7 +7083,7 @@ field_type_lob: | JSON_SYM { Lex->charset= &my_charset_utf8mb4_bin; - $$.set(&type_handler_json); + $$.set(&type_handler_json_longtext); } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 3bfb8347b13..025241f8e93 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -68,6 +68,7 @@ #include "sql_lex.h" #include "sql_sequence.h" #include "my_base.h" +#include "sql_type_json.h" /* this is to get the bison compilation windows warnings out */ #ifdef _MSC_VER @@ -6627,10 +6628,6 @@ field_spec: $$= $<create_field>2; $$->check_constraint= $4; - if (!$4 && lex->last_field->type_handler()->is_json_type() && - !($$->check_constraint= make_json_valid_expr(thd, - &$$->field_name))) - MYSQL_YYABORT; if (unlikely($$->check(thd))) MYSQL_YYABORT; @@ -7076,7 +7073,7 @@ field_type_lob: | JSON_SYM { Lex->charset= &my_charset_utf8mb4_bin; - $$.set(&type_handler_json); + $$.set(&type_handler_json_longtext); } ; |