summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2017-05-22 17:06:01 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2017-06-15 19:20:35 +0300
commitf0ad93403f4f39873618759585ca765169ecf000 (patch)
treeedeb6c22b7cc577e5ce795abac9eb68ce9917bbd /sql/item_strfunc.cc
parent34da3be8a832306410ddb42006f8a067d38127be (diff)
downloadmariadb-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.cc27
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();