diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-05-22 17:06:01 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-06-15 19:20:35 +0300 |
commit | f0ad93403f4f39873618759585ca765169ecf000 (patch) | |
tree | edeb6c22b7cc577e5ce795abac9eb68ce9917bbd /sql/item_strfunc.cc | |
parent | 34da3be8a832306410ddb42006f8a067d38127be (diff) | |
download | mariadb-git-f0ad93403f4f39873618759585ca765169ecf000.tar.gz |
MDEV-12666: CURRENT_ROLE() and DATABASE() does not work in a view
The problem lies in how CURRENT_ROLE is defined. The
Item_func_current_role inherits from Item_func_sysconst, which defines
a safe_charset_converter to be a const_charset_converter.
During view creation, if there is no role previously set, the current_role()
function returns NULL.
This is captured on item instantiation and the
const_charset_converter call subsequently returns an Item_null.
In turn, the function is replaced with Item_null and the view is
then created with an Item_null instead of Item_func_current_role.
Without this patch, the first SHOW CREATE VIEW from the testcase would
have a where clause of WHERE role_name = NULL, while the second SHOW
CREATE VIEW would show a correctly created view.
The same applies for the DATABASE function, as it can change as well.
There is an additional problem with CURRENT_ROLE() when used in a
prepared statement. During prepared statement creation we used to set
the string_value of the function to the current role as well as the
null_value flag. During execution, if CURRENT_ROLE was not null, the
null_value flag was never set to not-null during fix_fields.
Item_func_current_user however can never be NULL so it did not show this
problem in a view before. At the same time, the CURRENT_USER() can not
be changed between prepared statement execution and creation so the
implementation where the value is stored during fix_fields is
sufficient.
Note also that DATABASE() function behaves differently during prepared
statements. See bug 25843 for details or commit
7e0ad09edff587dadc3e9855fc81e1b7de8f2199
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7cd712cc5e1..08b9ded80f5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2344,6 +2344,7 @@ String *Item_func_database::val_str(String *str) } else str->copy(thd->db, thd->db_length, system_charset_info); + null_value= 0; return str; } @@ -2378,6 +2379,28 @@ bool Item_func_user::init(const char *user, const char *host) } +Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs) +{ + /* + During view or prepared statement creation, the item should not + make use of const_charset_converter as it would imply substitution + with constant items which is not correct. Functions can have different + values during view creation and view execution based on context. + + Return the identical item during view creation and prepare. + */ + if (!Item_func_sysconst::const_item()) + return this; + return const_charset_converter(tocs, true, fully_qualified_func_name()); +} + +bool Item_func_sysconst::const_item() const +{ + if (current_thd->lex->is_ps_or_view_context_analysis()) + return false; + return true; +} + bool Item_func_user::fix_fields(THD *thd, Item **ref) { return (Item_func_sysconst::fix_fields(thd, ref) || @@ -2403,21 +2426,19 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref) Security_context *ctx= context->security_ctx ? context->security_ctx : thd->security_ctx; - if (ctx->priv_role[0]) { if (str_value.copy(ctx->priv_role, strlen(ctx->priv_role), system_charset_info)) return 1; - str_value.mark_as_const(); + null_value= maybe_null= 0; return 0; } null_value= maybe_null= 1; return 0; } - void Item_func_soundex::fix_length_and_dec() { uint32 char_length= args[0]->max_char_length(); |