From 0a056c9b5302c24ee4eaa9cc92bd6697125f94b7 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 27 Jun 2016 19:22:09 +0200 Subject: better ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED --- sql/field.cc | 2 +- sql/item.cc | 17 +++++++++++++++++ sql/item.h | 16 ++++++++++------ sql/item_func.cc | 13 +++++++++++++ sql/item_func.h | 47 +++++++++++++++++++---------------------------- sql/item_geofunc.h | 2 +- sql/item_strfunc.h | 6 +++--- sql/item_subselect.h | 2 +- sql/item_sum.cc | 6 ++++++ sql/item_sum.h | 8 ++------ sql/item_timefunc.h | 18 +++++++++--------- sql/item_windowfunc.h | 2 +- sql/share/errmsg-utf8.txt | 4 ++-- sql/table.cc | 2 +- 14 files changed, 86 insertions(+), 59 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 00f40fae748..054865c6513 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9798,7 +9798,7 @@ bool Column_definition::check(THD *thd) if (vcol_info) { vcol_info->set_field_type(sql_type); - if (check_expression(vcol_info, "VIRTUAL", field_name, + if (check_expression(vcol_info, "GENERATED ALWAYS AS", field_name, vcol_info->stored_in_db)) DBUG_RETURN(TRUE); } diff --git a/sql/item.cc b/sql/item.cc index d8a282cc151..82c0ea7575c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1422,6 +1422,16 @@ bool mark_unsupported_function(const char *where, void *store, uint result) return false; } +/* convenience helper for mark_unsupported_function() above */ +bool mark_unsupported_function(const char *w1, const char *w2, + void *store, uint result) +{ + char *ptr= (char*)current_thd->alloc(strlen(w1) + strlen(w2) + 1); + if (ptr) + strxmov(ptr, w1, w2, NullS); + return mark_unsupported_function(ptr, store, result); +} + /***************************************************************************** Item_sp_variable methods *****************************************************************************/ @@ -8583,6 +8593,13 @@ void Item_trigger_field::print(String *str, enum_query_type query_type) } +bool Item_trigger_field::check_vcol_func_processor(void *arg) +{ + const char *ver= row_version == NEW_ROW ? "NEW." : "OLD."; + return mark_unsupported_function(ver, field_name, arg, VCOL_IMPOSSIBLE); +} + + void Item_trigger_field::cleanup() { want_privilege= original_privilege; diff --git a/sql/item.h b/sql/item.h index 41813e0a80f..4a5efad0048 100644 --- a/sql/item.h +++ b/sql/item.h @@ -62,6 +62,9 @@ char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg) bool mark_unsupported_function(const char *where, void *store, uint result); +/* convenience helper for mark_unsupported_function() above */ +bool mark_unsupported_function(const char *w1, const char *w2, + void *store, uint result); /* Bits for the split_sum_func() function */ #define SPLIT_SUM_SKIP_REGISTERED 1 /* Skip registered funcs */ @@ -2032,6 +2035,10 @@ public: inline int save_in_field(Field *field, bool no_conversions); inline bool send(Protocol *protocol, String *str); + bool check_vcol_func_processor(void *arg) + { + return mark_unsupported_function(m_name.str, arg, VCOL_IMPOSSIBLE); + } }; /***************************************************************************** @@ -2239,7 +2246,7 @@ public: } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function("name_const", arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function("name_const()", arg, VCOL_IMPOSSIBLE); } }; @@ -4936,7 +4943,7 @@ public: bool check_partition_func_processor(void *int_arg) {return TRUE;} bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function("values", arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function("values()", arg, VCOL_IMPOSSIBLE); } }; @@ -5023,10 +5030,7 @@ private: */ bool read_only; public: - bool check_vcol_func_processor(void *arg) - { - return mark_unsupported_function("trigger", arg, VCOL_IMPOSSIBLE); - } + bool check_vcol_func_processor(void *arg); }; diff --git a/sql/item_func.cc b/sql/item_func.cc index bda3b76a8dd..c98630e0431 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4587,6 +4587,11 @@ longlong Item_func_sleep::val_int() } +bool Item_func_user_var::check_vcol_func_processor(void *arg) +{ + return mark_unsupported_function("@", name.str, arg, VCOL_IMPOSSIBLE); +} + #define extra_size sizeof(double) user_var_entry *get_variable(HASH *hash, LEX_STRING &name, @@ -5847,6 +5852,10 @@ void Item_func_get_system_var::print(String *str, enum_query_type query_type) str->append(name, name_length); } +bool Item_func_get_system_var::check_vcol_func_processor(void *arg) +{ + return mark_unsupported_function("@@", var->name.str, arg, VCOL_NON_DETERMINISTIC); +} enum Item_result Item_func_get_system_var::result_type() const { @@ -6850,6 +6859,10 @@ void Item_func_sp::update_used_tables() } } +bool Item_func_sp::check_vcol_func_processor(void *arg) +{ + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); +} /* uuid_short handling. diff --git a/sql/item_func.h b/sql/item_func.h index ddb56015224..474f7b802c0 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -614,7 +614,7 @@ public: longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_NON_DETERMINISTIC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC); } }; @@ -1041,7 +1041,7 @@ public: void cleanup() { first_eval= TRUE; Item_real_func::cleanup(); } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_NON_DETERMINISTIC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC); } private: void seed_random (Item * val); @@ -1337,7 +1337,7 @@ public: bool fix_fields(THD *thd, Item **ref); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1354,7 +1354,7 @@ public: virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1376,7 +1376,7 @@ public: longlong val_int(); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1471,7 +1471,7 @@ public: virtual void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_UNKNOWN); + return mark_unsupported_function(func_name(), "()", arg, VCOL_UNKNOWN); } }; @@ -1646,7 +1646,7 @@ class Item_func_get_lock :public Item_int_func bool is_expensive() { return 1; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1666,7 +1666,7 @@ public: bool is_expensive() { return 1; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1686,7 +1686,7 @@ public: void fix_length_and_dec() { max_length=21; maybe_null=1;} bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1702,7 +1702,7 @@ public: void fix_length_and_dec() { max_length=10+1+10+1+20+1; maybe_null=0;} bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1728,10 +1728,7 @@ public: Item_func_user_var(THD *thd, Item_func_user_var *item) :Item_hybrid_func(thd, item), m_var_entry(item->m_var_entry), name(item->name) { } - bool check_vcol_func_processor(void *arg) - { - return mark_unsupported_function("user_var", arg, VCOL_IMPOSSIBLE); - } + bool check_vcol_func_processor(void *arg); }; @@ -1938,10 +1935,7 @@ public: bool eq(const Item *item, bool binary_cmp) const; void cleanup(); - bool check_vcol_func_processor(void *arg) - { - return mark_unsupported_function(func_name(), arg, VCOL_NON_DETERMINISTIC); - } + bool check_vcol_func_processor(void *arg); }; @@ -1989,7 +1983,7 @@ public: void init_search(THD *thd, bool no_order); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE); } private: /** @@ -2046,7 +2040,7 @@ public: void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -2060,7 +2054,7 @@ public: void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;} bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -2110,7 +2104,7 @@ public: void fix_length_and_dec() { decimals= 0; maybe_null=0; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -2234,10 +2228,7 @@ public: return sp_result_field; } - bool check_vcol_func_processor(void *arg) - { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); - } + bool check_vcol_func_processor(void *arg); bool limit_index_condition_pushdown_processor(void *opt_arg) { return TRUE; @@ -2254,7 +2245,7 @@ public: void fix_length_and_dec() { decimals= 0; maybe_null=0; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -2272,7 +2263,7 @@ public: table_map used_tables() const { return RAND_TABLE_BIT; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_NON_DETERMINISTIC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC); } }; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index d3b49b6e457..5a0a26ea779 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -618,7 +618,7 @@ class Item_func_gis_debug: public Item_int_func longlong val_int(); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; #endif diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 623f33b1eca..b0f5064a190 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -763,7 +763,7 @@ public: const char *func_name() const { return "binlog_gtid_pos"; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -923,7 +923,7 @@ public: } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -1191,7 +1191,7 @@ public: String *val_str(String *); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_NON_DETERMINISTIC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_NON_DETERMINISTIC); } }; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index edbfc050971..bec04813bcf 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -222,7 +222,7 @@ public: bool enumerate_field_refs_processor(void *arg); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function("subselect", arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function("select ...", arg, VCOL_IMPOSSIBLE); } /** Callback to test if an IN predicate is expensive. diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 90a9887f7f7..cc7a76213f0 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -579,6 +579,12 @@ Item *Item_sum::result_item(THD *thd, Field *field) return new (thd->mem_root) Item_field(thd, field); } +bool Item_sum::check_vcol_func_processor(void *arg) +{ + return mark_unsupported_function(func_name(), ")", arg, VCOL_IMPOSSIBLE); +} + + /** Compare keys consisting of single field that cannot be compared as binary. diff --git a/sql/item_sum.h b/sql/item_sum.h index b5f7b1458be..4cb5529e1ce 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -547,11 +547,7 @@ public: virtual void remove() { DBUG_ASSERT(0); } virtual void cleanup(); - bool check_vcol_func_processor(void *arg) - { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); - } - + bool check_vcol_func_processor(void *arg); virtual void setup_window_func(THD *thd, Window_spec *window_spec) {} }; @@ -1555,7 +1551,7 @@ public: void cleanup(); enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} - const char *func_name() const { return "group_concat"; } + const char *func_name() const { return "group_concat("; } virtual Item_result result_type () const { return STRING_RESULT; } virtual Item_result cmp_type () const { return STRING_RESULT; } enum_field_types field_type() const diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index e5040d51b72..9f67a1dabe6 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -196,7 +196,7 @@ public: } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -411,7 +411,7 @@ class Item_func_dayname :public Item_func_weekday bool check_partition_func_processor(void *int_arg) {return TRUE;} bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; @@ -464,7 +464,7 @@ public: { if (arg_count) return FALSE; - return mark_unsupported_function(func_name(), arg, VCOL_TIME_FUNC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC); } longlong int_op(); my_decimal *decimal_op(my_decimal* buf); @@ -614,7 +614,7 @@ public: virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)=0; bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_TIME_FUNC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC); } }; @@ -649,7 +649,7 @@ public: virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)=0; bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, + return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC); } }; @@ -691,7 +691,7 @@ public: NOW is safe for replication as slaves will run with same time as master */ - return mark_unsupported_function(func_name(), arg, VCOL_TIME_FUNC); + return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC); } }; @@ -715,7 +715,7 @@ public: virtual enum Functype functype() const { return NOW_UTC_FUNC; } virtual bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, + return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC); } @@ -737,7 +737,7 @@ public: table_map used_tables() const { return RAND_TABLE_BIT; } bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, + return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC | VCOL_NON_DETERMINISTIC); } virtual enum Functype functype() const { return SYSDATE_FUNC; } @@ -776,7 +776,7 @@ public: bool eq(const Item *item, bool binary_cmp) const; bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), arg, VCOL_IMPOSSIBLE); + return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); } }; diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h index 56fa272ac45..9d2fa135e29 100644 --- a/sql/item_windowfunc.h +++ b/sql/item_windowfunc.h @@ -117,7 +117,7 @@ public: } const char*func_name() const { - return "row_number"; + return "row_number("; } }; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index ba75a6a9149..980055a7933 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6970,7 +6970,7 @@ start-error-number 1900 ER_VCOL_BASED_ON_VCOL eng "A computed column cannot be based on a computed column" ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED - eng "Function or expression '%s' is not allowed for '%s' of column/constraint '%s'" + eng "Function or expression '%s' cannot be used in the %s clause of %`s" ER_DATA_CONVERSION_ERROR_FOR_VIRTUAL_COLUMN eng "Generated value for computed column '%s' cannot be converted to type '%s'" ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN @@ -7209,7 +7209,7 @@ ER_CONSTRAINT_FAILED 23000 rus "проверка CONSTRAINT %`s для %`-.192s.%`-.192s провалилась" ukr "Перевірка CONSTRAINT %`s для %`-.192s.%`-.192s не пройшла" ER_EXPRESSION_IS_TOO_BIG - eng "%s expression is too big for '%s'" + eng "%s expression in the %s clause is too big" ER_ERROR_EVALUATING_EXPRESSION eng "Got an error evaluating stored expression %`s" ER_CALCULATING_DEFAULT_VALUE diff --git a/sql/table.cc b/sql/table.cc index 98f2f755c02..20444114381 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2614,7 +2614,7 @@ static bool fix_vcol_expr(THD *thd, if (error || (res.errors & VCOL_IMPOSSIBLE)) { my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, - field_name); + "???", field_name); goto end; } #endif -- cgit v1.2.1