summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-02-05 12:43:17 +0400
committerAlexander Barkov <bar@mariadb.com>2020-02-08 21:35:35 +0400
commit77c6382312535991d26c85e7eb5492f9b3a59e92 (patch)
treeefcbf3c238aa8b67165031b5c7d9266c0082e7b4
parent06b0623adb71f2b7918f69ab68660ec45736ebb5 (diff)
downloadmariadb-git-77c6382312535991d26c85e7eb5492f9b3a59e92.tar.gz
MDEV-21689 Add Sql_cmd for GRANT/REVOKE statements
Rewriting GRANT/REVOKE grammar to use more bison stack and use Sql_cmd_ style 1. Removing a few members from LEX: - uint grant, grant_to_col, which_columns - List<LEX_COLUMN> columns - bool all_privileges 2. Adding classes Grand_object_name, Lex_grant_object_name 3. Adding classes Grand_privilege, Lex_grand_privilege 4. Adding struct Lex_column_list_privilege_st, class Lex_column_list_privilege 5. Rewriting the GRANT/REVOKE grammar to use new classes and pass them through bison stack (rather than directly access LEX members) 6. Adding classes Sql_cmd_grant* and Sql_cmd_revoke*, changing GRANT/REVOKE to use LEX::m_sql_cmd. 7. Adding the "sp_handler" grammar rule and removing some duplicate grammar for GRANT/REVOKE for different kinds of SP objects. 8. Adding a new rule comma_separated_ident_list, reusing it in: - with_column_list - colum_list_privilege
-rw-r--r--libmysqld/CMakeLists.txt3
-rw-r--r--sql/CMakeLists.txt1
-rw-r--r--sql/grant.cc108
-rw-r--r--sql/grant.h96
-rw-r--r--sql/lex_string.h4
-rw-r--r--sql/sql_acl.cc221
-rw-r--r--sql/sql_acl.h76
-rw-r--r--sql/sql_cte.cc4
-rw-r--r--sql/sql_cte.h4
-rw-r--r--sql/sql_lex.cc74
-rw-r--r--sql/sql_lex.h70
-rw-r--r--sql/sql_parse.cc109
-rw-r--r--sql/sql_yacc.yy360
13 files changed, 813 insertions, 317 deletions
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index d03abc5c378..f9eba7d7713 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -47,7 +47,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/password.c ../sql/discover.cc ../sql/derror.cc
../sql/field.cc ../sql/field_conv.cc ../sql/field_comp.cc
../sql/filesort_utils.cc ../sql/sql_digest.cc
- ../sql/filesort.cc ../sql/gstream.cc ../sql/slave.cc
+ ../sql/filesort.cc ../sql/grant.cc
+ ../sql/gstream.cc ../sql/slave.cc
../sql/signal_handler.cc
../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc
../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 23c66576b19..da046d0ec3a 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -129,6 +129,7 @@ SET (SQL_SOURCE
sql_reload.cc
# added in MariaDB:
+ grant.cc
sql_explain.cc
sql_analyze_stmt.cc
sql_join_cache.cc
diff --git a/sql/grant.cc b/sql/grant.cc
new file mode 100644
index 00000000000..d4bbaa7b1f3
--- /dev/null
+++ b/sql/grant.cc
@@ -0,0 +1,108 @@
+/*
+ Copyright (c) 2009, 2020, MariaDB Corporation
+
+ 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-1335 USA */
+
+#include "mariadb.h"
+#include "sql_acl.h"
+
+
+bool Grant_privilege::add_column_privilege(THD *thd,
+ const Lex_ident_sys &name,
+ uint which_grant)
+{
+ String *new_str= new (thd->mem_root) String((const char*) name.str,
+ name.length,
+ system_charset_info);
+ if (unlikely(new_str == NULL))
+ return true;
+ List_iterator <LEX_COLUMN> iter(m_columns);
+ class LEX_COLUMN *point;
+ while ((point=iter++))
+ {
+ if (!my_strcasecmp(system_charset_info,
+ point->column.c_ptr(), new_str->c_ptr()))
+ break;
+ }
+ m_column_privilege_total|= which_grant;
+ if (point)
+ {
+ point->rights |= which_grant;
+ return false;
+ }
+
+ LEX_COLUMN *col= new (thd->mem_root) LEX_COLUMN(*new_str, which_grant);
+ if (unlikely(col == NULL))
+ return true;
+ return m_columns.push_back(col, thd->mem_root);
+}
+
+
+bool Grant_privilege::add_column_list_privilege(THD *thd,
+ List<Lex_ident_sys> &list,
+ uint privilege)
+{
+ Lex_ident_sys *col;
+ List_iterator<Lex_ident_sys> it(list);
+ while ((col= it++))
+ {
+ if (add_column_privilege(thd, *col, privilege))
+ return true;
+ }
+ return false;
+}
+
+
+uint Grant_object_name::all_privileges_by_type() const
+{
+ switch (m_type) {
+ case STAR: return DB_ACLS & ~GRANT_ACL;
+ case IDENT_STAR: return DB_ACLS & ~GRANT_ACL;
+ case STAR_STAR: return GLOBAL_ACLS & ~GRANT_ACL;
+ case TABLE_IDENT: return TABLE_ACLS & ~GRANT_ACL;
+ }
+ return 0;
+}
+
+
+bool Grant_privilege::set_object_name(THD *thd,
+ const Grant_object_name &ident,
+ SELECT_LEX *sel,
+ uint with_grant_option)
+{
+ DBUG_ASSERT(!m_all_privileges || !m_columns.elements);
+
+ m_db= ident.m_db;
+ if (m_all_privileges)
+ m_object_privilege= ident.all_privileges_by_type();
+ m_object_privilege|= with_grant_option;
+ switch (ident.m_type)
+ {
+ case Lex_grant_object_name::STAR:
+ case Lex_grant_object_name::IDENT_STAR:
+ case Lex_grant_object_name::STAR_STAR:
+ if (!m_all_privileges && m_columns.elements)
+ {
+ // e.g. GRANT SELECT (a) ON db.*
+ my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0));
+ return true;
+ }
+ return false;
+ case Lex_grant_object_name::TABLE_IDENT:
+ m_db= ident.m_table_ident->db;
+ return !sel->add_table_to_list(thd, ident.m_table_ident,
+ NULL, TL_OPTION_UPDATING);
+ }
+ return false; // Make gcc happy
+}
diff --git a/sql/grant.h b/sql/grant.h
new file mode 100644
index 00000000000..18b39ea0719
--- /dev/null
+++ b/sql/grant.h
@@ -0,0 +1,96 @@
+/*
+ Copyright (c) 2020, MariaDB Corporation.
+
+ 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 Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#ifndef SQL_GRANT_INCLUDED
+#define SQL_GRANT_INCLUDED
+
+#include "lex_string.h"
+
+class LEX_COLUMN;
+class Lex_ident_sys;
+class Table_ident;
+
+/*
+ Represents the object name in this standard SQL grammar:
+ GRANT <object privileges> ON <object name>
+*/
+class Grant_object_name
+{
+public:
+ enum Type
+ {
+ STAR, // ON *
+ IDENT_STAR, // ON db.*
+ STAR_STAR, // ON *.*
+ TABLE_IDENT // ON db.name
+ };
+ Lex_cstring m_db;
+ Table_ident *m_table_ident;
+ Type m_type;
+public:
+ Grant_object_name(Table_ident *table_ident)
+ :m_table_ident(table_ident),
+ m_type(TABLE_IDENT)
+ { }
+ Grant_object_name(const LEX_CSTRING &db, Type type)
+ :m_db(db),
+ m_table_ident(NULL),
+ m_type(type)
+ { }
+ uint all_privileges_by_type() const;
+};
+
+
+
+/*
+ Represents standard SQL statements described by:
+ - <grant privilege statement>
+ - <revoke privilege statement>
+*/
+class Grant_privilege
+{
+protected:
+ List<LEX_COLUMN> m_columns;
+ Lex_cstring m_db;
+ uint m_object_privilege;
+ uint m_column_privilege_total;
+ bool m_all_privileges;
+public:
+ Grant_privilege()
+ :m_object_privilege(0), m_column_privilege_total(0), m_all_privileges(false)
+ { }
+ Grant_privilege(uint privilege, bool all_privileges)
+ :m_object_privilege(privilege),
+ m_column_privilege_total(0),
+ m_all_privileges(all_privileges)
+ { }
+ void add_object_privilege(uint privilege)
+ {
+ m_object_privilege|= privilege;
+ }
+ bool add_column_privilege(THD *thd, const Lex_ident_sys &col,
+ uint privilege);
+ bool add_column_list_privilege(THD *thd, List<Lex_ident_sys> &list,
+ uint privilege);
+ bool set_object_name(THD *thd,
+ const Grant_object_name &ident,
+ SELECT_LEX *sel,
+ uint with_grant_option);
+ const List<LEX_COLUMN> & columns() const { return m_columns; }
+};
+
+
+#endif // SQL_GRANT_INCLUDED
diff --git a/sql/lex_string.h b/sql/lex_string.h
index a62609c6b60..008e5f75812 100644
--- a/sql/lex_string.h
+++ b/sql/lex_string.h
@@ -30,6 +30,10 @@ class Lex_cstring : public LEX_CSTRING
str= NULL;
length= 0;
}
+ Lex_cstring(const LEX_CSTRING &str)
+ {
+ LEX_CSTRING::operator=(str);
+ }
Lex_cstring(const char *_str, size_t _len)
{
str= _str;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 67263386706..7bdee80d596 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -11656,6 +11656,227 @@ bool check_grant(THD *, ulong, TABLE_LIST *, bool, uint, bool)
{ return 0; }
#endif /*NO_EMBEDDED_ACCESS_CHECKS */
+
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+
+bool Sql_cmd_grant_proxy::execute(THD *thd)
+{
+ my_ok(thd);
+ return false;
+}
+
+bool Sql_cmd_grant_table::execute(THD *thd)
+{
+ my_ok(thd);
+ return false;
+}
+
+
+bool Sql_cmd_grant_sp::execute(THD *thd)
+{
+ my_ok(thd);
+ return false;
+}
+
+#else // not NO_EMBEDDED_ACCESS_CHECKS
+
+
+void Sql_cmd_grant::warn_hostname_requires_resolving(THD *thd,
+ List<LEX_USER> &users)
+{
+ LEX_USER *user;
+ List_iterator <LEX_USER> it(users);
+ while ((user= it++))
+ {
+ if (specialflag & SPECIAL_NO_RESOLVE &&
+ hostname_requires_resolving(user->host.str))
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WARN_HOSTNAME_WONT_WORK,
+ ER_THD(thd, ER_WARN_HOSTNAME_WONT_WORK));
+ }
+}
+
+
+void Sql_cmd_grant::grant_stage0(THD *thd)
+{
+ thd->binlog_invoker(false); // Replicate current user as grantor
+ if (thd->security_ctx->user) // If not replication
+ warn_hostname_requires_resolving(thd, thd->lex->users_list);
+}
+
+
+bool Sql_cmd_grant::user_list_reset_mqh(THD *thd, List<LEX_USER> &users)
+{
+ List_iterator <LEX_USER> it(users);
+ LEX_USER *user, *tmp_user;
+ while ((tmp_user= it++))
+ {
+ if (!(user= get_current_user(thd, tmp_user)))
+ return true;
+ reset_mqh(user, 0);
+ }
+ return false;
+}
+
+
+bool Sql_cmd_grant_proxy::check_access_proxy(THD *thd, List<LEX_USER> &users)
+{
+ LEX_USER *user;
+ List_iterator <LEX_USER> it(users);
+ if ((user= it++))
+ {
+ // GRANT/REVOKE PROXY has the target user as a first entry in the list
+ if (!(user= get_current_user(thd, user)) || !user->host.str)
+ return true;
+ if (acl_check_proxy_grant_access(thd, user->host.str, user->user.str,
+ m_grant_option & GRANT_ACL))
+ return true;
+ }
+ return false;
+}
+
+
+bool Sql_cmd_grant_proxy::execute(THD *thd)
+{
+ LEX *lex= thd->lex;
+
+ DBUG_ASSERT(lex->first_select_lex()->table_list.first == NULL);
+ DBUG_ASSERT((m_grant_option & ~GRANT_ACL) == 0); // only WITH GRANT OPTION
+
+ grant_stage0(thd);
+
+ if (thd->security_ctx->user /* If not replication */ &&
+ check_access_proxy(thd, lex->users_list))
+ return true;
+
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+ /* Conditionally writes to binlog */
+ if (mysql_grant(thd, NULL/*db*/, lex->users_list, m_grant_option,
+ is_revoke(), true/*proxy*/))
+ return true;
+
+ return !is_revoke() && user_list_reset_mqh(thd, lex->users_list);
+
+#ifdef WITH_WSREP
+wsrep_error_label:
+ return true;
+#endif // WITH_WSREP
+}
+
+
+bool Sql_cmd_grant_object::grant_stage0_exact_object(THD *thd,
+ TABLE_LIST *table)
+{
+ uint priv= m_object_privilege | m_column_privilege_total | GRANT_ACL;
+ if (check_access(thd, priv, table->db.str,
+ &table->grant.privilege, &table->grant.m_internal,
+ 0, 0))
+ return true;
+ grant_stage0(thd);
+ return false;
+}
+
+
+bool Sql_cmd_grant_table::execute_exact_table(THD *thd, TABLE_LIST *table)
+{
+ LEX *lex= thd->lex;
+ if (grant_stage0_exact_object(thd, table) ||
+ check_grant(thd, m_object_privilege | m_column_privilege_total | GRANT_ACL,
+ lex->query_tables, FALSE, UINT_MAX, FALSE))
+ return true;
+ /* Conditionally writes to binlog */
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+ return mysql_table_grant(thd, lex->query_tables, lex->users_list,
+ m_columns, m_object_privilege,
+ is_revoke());
+#ifdef WITH_WSREP
+wsrep_error_label:
+ return true;
+#endif // WITH_WSREP
+}
+
+
+bool Sql_cmd_grant_sp::execute(THD *thd)
+{
+ DBUG_ASSERT(!m_columns.elements);
+ DBUG_ASSERT(!m_column_privilege_total);
+ LEX *lex= thd->lex;
+ TABLE_LIST *table= lex->first_select_lex()->table_list.first;
+ uint grants= m_all_privileges
+ ? (PROC_ACLS & ~GRANT_ACL) | (m_object_privilege & GRANT_ACL)
+ : m_object_privilege;
+
+ if (!table) // e.g: GRANT EXECUTE ON PROCEDURE *.*
+ {
+ my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE),
+ MYF(0));
+ return true;
+ }
+
+ if (grant_stage0_exact_object(thd, table) ||
+ check_grant_routine(thd, grants|GRANT_ACL, lex->query_tables, &m_sph, 0))
+ return true;
+
+ /* Conditionally writes to binlog */
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+ if (mysql_routine_grant(thd, lex->query_tables, &m_sph,
+ lex->users_list, grants,
+ is_revoke(), true))
+ return true;
+ my_ok(thd);
+ return false;
+#ifdef WITH_WSREP
+wsrep_error_label:
+ return true;
+#endif // WITH_WSREP
+}
+
+
+bool Sql_cmd_grant_table::execute_table_mask(THD *thd)
+{
+ LEX *lex= thd->lex;
+ DBUG_ASSERT(lex->first_select_lex()->table_list.first == NULL);
+
+ if (check_access(thd, m_object_privilege | m_column_privilege_total | GRANT_ACL,
+ m_db.str, NULL, NULL, 1, 0))
+ return true;
+
+ grant_stage0(thd);
+
+ if (m_columns.elements) // e.g. GRANT SELECT (a) ON *.*
+ {
+ my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE),
+ MYF(0));
+ return true;
+ }
+
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+ /* Conditionally writes to binlog */
+ if (mysql_grant(thd, m_db.str, lex->users_list, m_object_privilege,
+ is_revoke(), false/*not proxy*/))
+ return true;
+
+ return !is_revoke() && user_list_reset_mqh(thd, lex->users_list);
+
+#ifdef WITH_WSREP
+wsrep_error_label:
+ return true;
+#endif // WITH_WSREP
+}
+
+
+bool Sql_cmd_grant_table::execute(THD *thd)
+{
+ TABLE_LIST *table= thd->lex->first_select_lex()->table_list.first;
+ return table ? execute_exact_table(thd, table) :
+ execute_table_mask(thd);
+}
+
+
+#endif // NO_EMBEDDED_ACCESS_CHECKS
+
+
+
SHOW_VAR acl_statistics[] = {
#ifndef NO_EMBEDDED_ACCESS_CHECKS
{"column_grants", (char*)show_column_grants, SHOW_SIMPLE_FUNC},
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 7989367ec44..4147981bb98 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -19,6 +19,8 @@
#include "violite.h" /* SSL_type */
#include "sql_class.h" /* LEX_COLUMN */
+#include "grant.h"
+#include "sql_cmd.h" /* Sql_cmd */
#define SELECT_ACL (1UL << 0)
#define INSERT_ACL (1UL << 1)
@@ -435,4 +437,78 @@ bool check_role_is_granted(const char *username,
extern ulong role_global_merges, role_db_merges, role_table_merges,
role_column_merges, role_routine_merges;
#endif
+
+
+class Sql_cmd_grant: public Sql_cmd
+{
+protected:
+ enum_sql_command m_command;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ void warn_hostname_requires_resolving(THD *thd, List<LEX_USER> &list);
+ bool user_list_reset_mqh(THD *thd, List<LEX_USER> &list);
+ void grant_stage0(THD *thd);
+#endif
+public:
+ Sql_cmd_grant(enum_sql_command command)
+ :m_command(command)
+ { }
+ bool is_revoke() const { return m_command == SQLCOM_REVOKE; }
+ enum_sql_command sql_command_code() const { return m_command; }
+};
+
+
+class Sql_cmd_grant_proxy: public Sql_cmd_grant
+{
+ uint m_grant_option;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ bool check_access_proxy(THD *thd, List<LEX_USER> &list);
+#endif
+public:
+ Sql_cmd_grant_proxy(enum_sql_command command, uint grant_option)
+ :Sql_cmd_grant(command), m_grant_option(grant_option)
+ { }
+ bool execute(THD *thd);
+};
+
+
+class Sql_cmd_grant_object: public Sql_cmd_grant, public Grant_privilege
+{
+protected:
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ bool grant_stage0_exact_object(THD *thd, TABLE_LIST *table);
+#endif
+public:
+ Sql_cmd_grant_object(enum_sql_command command, const Grant_privilege &grant)
+ :Sql_cmd_grant(command), Grant_privilege(grant)
+ { }
+};
+
+
+class Sql_cmd_grant_table: public Sql_cmd_grant_object
+{
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ bool execute_table_mask(THD *thd);
+ bool execute_exact_table(THD *thd, TABLE_LIST *table);
+#endif
+public:
+ Sql_cmd_grant_table(enum_sql_command command, const Grant_privilege &grant)
+ :Sql_cmd_grant_object(command, grant)
+ { }
+ bool execute(THD *thd);
+};
+
+
+
+class Sql_cmd_grant_sp: public Sql_cmd_grant_object
+{
+ const Sp_handler &m_sph;
+public:
+ Sql_cmd_grant_sp(enum_sql_command command, const Grant_privilege &grant,
+ const Sp_handler &sph)
+ :Sql_cmd_grant_object(command, grant),
+ m_sph(sph)
+ { }
+ bool execute(THD *thd);
+};
+
#endif /* SQL_ACL_INCLUDED */
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 5b3d3108da5..c7a0f9186e2 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -956,7 +956,7 @@ With_element::rename_columns_of_derived_unit(THD *thd,
if (column_list.elements) // The column list is optional
{
List_iterator_fast<Item> it(select->item_list);
- List_iterator_fast<LEX_CSTRING> nm(column_list);
+ List_iterator_fast<Lex_ident_sys> nm(column_list);
Item *item;
LEX_CSTRING *name;
@@ -1442,7 +1442,7 @@ void With_element::print(String *str, enum_query_type query_type)
str->append(query_name);
if (column_list.elements)
{
- List_iterator_fast<LEX_CSTRING> li(column_list);
+ List_iterator_fast<Lex_ident_sys> li(column_list);
str->append('(');
for (LEX_CSTRING *col_name= li++; ; )
{
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 80d56644d7e..92aca5090f3 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -111,7 +111,7 @@ public:
inherited from the query that specified the table. Otherwise the list is
always empty.
*/
- List <LEX_CSTRING> column_list;
+ List <Lex_ident_sys> column_list;
/* The query that specifies the table introduced by this with element */
st_select_lex_unit *spec;
/*
@@ -163,7 +163,7 @@ public:
SQL_I_List<TABLE_LIST> derived_with_rec_ref;
With_element(LEX_CSTRING *name,
- List <LEX_CSTRING> list,
+ List <Lex_ident_sys> list,
st_select_lex_unit *unit)
: next(NULL), base_dep_map(0), derived_dep_map(0),
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 65fbd5a0ede..cbd2e953d7b 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -9009,16 +9009,13 @@ bool LEX::create_package_finalize(THD *thd,
}
-bool LEX::add_grant_command(THD *thd, enum_sql_command sql_command_arg,
- stored_procedure_type type_arg)
+bool LEX::add_grant_command(THD *thd, const List<LEX_COLUMN> &columns)
{
if (columns.elements)
{
thd->parse_error();
return true;
}
- sql_command= sql_command_arg,
- type= type_arg;
return false;
}
@@ -11239,3 +11236,72 @@ bool LEX::add_column_foreign_key(const LEX_CSTRING *name,
return false;
}
+
+
+bool LEX::stmt_grant_table(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ uint grant_option)
+{
+ sql_command= SQLCOM_GRANT;
+ return
+ grant->set_object_name(thd, ident, current_select, grant_option) ||
+ !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_table(sql_command, *grant));
+}
+
+
+bool LEX::stmt_revoke_table(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident)
+{
+ sql_command= SQLCOM_REVOKE;
+ return
+ grant->set_object_name(thd, ident, current_select, 0) ||
+ !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_table(sql_command, *grant));
+}
+
+
+bool LEX::stmt_grant_sp(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ const Sp_handler &sph,
+ uint grant_option)
+{
+ sql_command= SQLCOM_GRANT;
+ return
+ grant->set_object_name(thd, ident, current_select, grant_option) ||
+ add_grant_command(thd, grant->columns()) ||
+ !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_sp(sql_command,
+ *grant, sph));
+}
+
+
+bool LEX::stmt_revoke_sp(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ const Sp_handler &sph)
+{
+ sql_command= SQLCOM_REVOKE;
+ return
+ grant->set_object_name(thd, ident, current_select, 0) ||
+ add_grant_command(thd, grant->columns()) ||
+ !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_sp(sql_command,
+ *grant, sph));
+}
+
+
+bool LEX::stmt_grant_proxy(THD *thd, LEX_USER *user, uint grant_option)
+{
+ users_list.push_front(user);
+ sql_command= SQLCOM_GRANT;
+ return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_proxy(sql_command,
+ grant_option));
+}
+
+
+bool LEX::stmt_revoke_proxy(THD *thd, LEX_USER *user)
+{
+ users_list.push_front(user);
+ sql_command= SQLCOM_REVOKE;
+ return !(m_sql_cmd= new (thd->mem_root) Sql_cmd_grant_proxy(sql_command, 0));
+}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 308bebd9fa1..ad1bd6adfa2 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -25,6 +25,7 @@
#include "sql_trigger.h"
#include "thr_lock.h" /* thr_lock_type, TL_UNLOCK */
#include "mem_root_array.h"
+#include "grant.h"
#include "sql_cmd.h"
#include "sql_alter.h" // Alter_info
#include "sql_window.h"
@@ -183,6 +184,24 @@ public:
};
+struct Lex_column_list_privilege_st
+{
+ List<Lex_ident_sys> *m_columns;
+ uint m_privilege;
+};
+
+
+class Lex_column_list_privilege: public Lex_column_list_privilege_st
+{
+public:
+ Lex_column_list_privilege(List<Lex_ident_sys> *columns, uint privilege)
+ {
+ m_columns= columns;
+ m_privilege= privilege;
+ }
+};
+
+
/**
ORDER BY ... LIMIT parameters;
*/
@@ -3091,6 +3110,28 @@ public:
};
+class Lex_grant_object_name: public Grant_object_name, public Sql_alloc
+{
+public:
+ Lex_grant_object_name(Table_ident *table_ident)
+ :Grant_object_name(table_ident)
+ { }
+ Lex_grant_object_name(const LEX_CSTRING &db, Type type)
+ :Grant_object_name(db, type)
+ { }
+};
+
+
+class Lex_grant_privilege: public Grant_privilege, public Sql_alloc
+{
+public:
+ Lex_grant_privilege() {}
+ Lex_grant_privilege(uint grant, bool all_privileges= false)
+ :Grant_privilege(grant, all_privileges)
+ { }
+};
+
+
struct LEX: public Query_tables_list
{
SELECT_LEX_UNIT unit; /* most upper unit */
@@ -3187,7 +3228,6 @@ public:
Table_type table_type; /* Used for SHOW CREATE */
List<Key_part_spec> ref_list;
List<LEX_USER> users_list;
- List<LEX_COLUMN> columns;
List<Item> *insert_list,field_list,value_list,update_list;
List<List_item> many_values;
List<set_var_base> var_list;
@@ -3309,7 +3349,6 @@ public:
uint profile_query_id;
uint profile_options;
- uint grant, grant_tot_col, which_columns;
enum backup_stages backup_stage;
enum Foreign_key::fk_match_opt fk_match_option;
enum_fk_option fk_update_opt;
@@ -3362,7 +3401,6 @@ public:
sp_head *sphead;
sp_name *spname;
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
- bool all_privileges;
sp_pcontext *spcont;
@@ -4374,8 +4412,30 @@ public:
bool add_create_view(THD *thd, DDL_options_st ddl,
uint16 algorithm, enum_view_suid suid,
Table_ident *table_ident);
- bool add_grant_command(THD *thd, enum_sql_command sql_command_arg,
- stored_procedure_type type_arg);
+ bool add_grant_command(THD *thd, const List<LEX_COLUMN> &columns);
+
+ bool stmt_grant_table(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ uint grant_option);
+
+ bool stmt_revoke_table(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident);
+
+ bool stmt_grant_sp(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ const Sp_handler &sph,
+ uint grant_option);
+
+ bool stmt_revoke_sp(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ const Sp_handler &sph);
+
+ bool stmt_grant_proxy(THD *thd, LEX_USER *user, uint grant_option);
+ bool stmt_revoke_proxy(THD *thd, LEX_USER *user);
Vers_parse_info &vers_get_info()
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a586dd9107c..ab8af4e9b96 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5261,113 +5261,6 @@ mysql_execute_command(THD *thd)
my_ok(thd);
break;
}
- case SQLCOM_REVOKE:
- case SQLCOM_GRANT:
- {
- if (lex->type != TYPE_ENUM_PROXY &&
- check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
- first_table ? first_table->db.str : select_lex->db.str,
- first_table ? &first_table->grant.privilege : NULL,
- first_table ? &first_table->grant.m_internal : NULL,
- first_table ? 0 : 1, 0))
- goto error;
-
- /* Replicate current user as grantor */
- thd->binlog_invoker(false);
-
- if (thd->security_ctx->user) // If not replication
- {
- LEX_USER *user;
- bool first_user= TRUE;
-
- List_iterator <LEX_USER> user_list(lex->users_list);
- while ((user= user_list++))
- {
- if (specialflag & SPECIAL_NO_RESOLVE &&
- hostname_requires_resolving(user->host.str))
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_HOSTNAME_WONT_WORK,
- ER_THD(thd, ER_WARN_HOSTNAME_WONT_WORK));
-
- /*
- GRANT/REVOKE PROXY has the target user as a first entry in the list.
- */
- if (lex->type == TYPE_ENUM_PROXY && first_user)
- {
- if (!(user= get_current_user(thd, user)) || !user->host.str)
- goto error;
-
- first_user= FALSE;
- if (acl_check_proxy_grant_access (thd, user->host.str, user->user.str,
- lex->grant & GRANT_ACL))
- goto error;
- }
- }
- }
- if (first_table)
- {
- const Sp_handler *sph= Sp_handler::handler((stored_procedure_type)
- lex->type);
- if (sph)
- {
- uint grants= lex->all_privileges
- ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
- : lex->grant;
- if (check_grant_routine(thd, grants | GRANT_ACL, all_tables, sph, 0))
- goto error;
- /* Conditionally writes to binlog */
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
- res= mysql_routine_grant(thd, all_tables, sph,
- lex->users_list, grants,
- lex->sql_command == SQLCOM_REVOKE, TRUE);
- if (!res)
- my_ok(thd);
- }
- else
- {
- if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
- all_tables, FALSE, UINT_MAX, FALSE))
- goto error;
- /* Conditionally writes to binlog */
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
- res= mysql_table_grant(thd, all_tables, lex->users_list,
- lex->columns, lex->grant,
- lex->sql_command == SQLCOM_REVOKE);
- }
- }
- else
- {
- if (lex->columns.elements || (lex->type && lex->type != TYPE_ENUM_PROXY))
- {
- my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER_THD(thd, ER_ILLEGAL_GRANT_FOR_TABLE),
- MYF(0));
- goto error;
- }
- else
- {
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
- /* Conditionally writes to binlog */
- res= mysql_grant(thd, select_lex->db.str, lex->users_list, lex->grant,
- lex->sql_command == SQLCOM_REVOKE,
- lex->type == TYPE_ENUM_PROXY);
- }
- if (!res)
- {
- if (lex->sql_command == SQLCOM_GRANT)
- {
- List_iterator <LEX_USER> str_list(lex->users_list);
- LEX_USER *user, *tmp_user;
- while ((tmp_user=str_list++))
- {
- if (!(user= get_current_user(thd, tmp_user)))
- goto error;
- reset_mqh(user, 0);
- }
- }
- }
- }
- break;
- }
case SQLCOM_REVOKE_ROLE:
case SQLCOM_GRANT_ROLE:
{
@@ -5955,6 +5848,8 @@ mysql_execute_command(THD *thd)
case SQLCOM_RESIGNAL:
case SQLCOM_GET_DIAGNOSTICS:
case SQLCOM_CALL:
+ case SQLCOM_REVOKE:
+ case SQLCOM_GRANT:
DBUG_ASSERT(lex->m_sql_cmd != NULL);
res= lex->m_sql_cmd->execute(thd);
DBUG_PRINT("result", ("res: %d killed: %d is_error: %d",
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 332ef6c8aca..53551567b51 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -191,12 +191,14 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
ulonglong ulonglong_number;
longlong longlong_number;
uint sp_instr_addr;
+ uint privilege;
/* structs */
LEX_CSTRING lex_str;
Lex_ident_cli_st kwd;
Lex_ident_cli_st ident_cli;
Lex_ident_sys_st ident_sys;
+ Lex_column_list_privilege_st column_list_privilege;
Lex_string_with_metadata_st lex_string_with_metadata;
Lex_spblock_st spblock;
Lex_spblock_handlers_st spblock_handlers;
@@ -224,10 +226,12 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
Lex_order_limit_lock *order_limit_lock;
/* pointers */
+ Lex_ident_sys *ident_sys_ptr;
Create_field *create_field;
Spvar_definition *spvar_definition;
Row_definition_list *spvar_definition_list;
const Type_handler *type_handler;
+ const class Sp_handler *sp_handler;
CHARSET_INFO *charset;
Condition_information_item *cond_info_item;
DYNCALL_CREATE_DEF *dyncol_def;
@@ -250,7 +254,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
List<sp_assignment_lex> *sp_assignment_lex_list;
List<Statement_information_item> *stmt_info_list;
List<String> *string_list;
- List<LEX_CSTRING> *lex_str_list;
+ List<Lex_ident_sys> *ident_sys_list;
Statement_information_item *stmt_info_item;
String *string;
TABLE_LIST *table_list;
@@ -259,6 +263,8 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
char *simple_string;
const char *const_simple_string;
chooser_compare_func_creator boolfunc2creator;
+ class Lex_grant_privilege *lex_grant;
+ class Lex_grant_object_name *lex_grant_ident;
class my_var *myvar;
class sp_condition_value *spcondvalue;
class sp_head *sphead;
@@ -1294,6 +1300,9 @@ End SQL_MODE_ORACLE_SPECIFIC */
ident_cli
ident_cli_set_usual_case
+%type <ident_sys_ptr>
+ ident_sys_alloc
+
%type <kwd>
keyword_data_type
keyword_cast_type
@@ -1336,6 +1345,8 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <type_handler> int_type real_type
+%type <sp_handler> sp_handler
+
%type <Lex_field_type> type_with_opt_collate field_type
field_type_numeric
field_type_string
@@ -1346,6 +1357,9 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <Lex_dyncol_type> opt_dyncol_type dyncol_type
numeric_dyncol_type temporal_dyncol_type string_dyncol_type
+%type <column_list_privilege>
+ column_list_privilege
+
%type <create_field> field_spec column_def
%type <num>
@@ -1383,6 +1397,21 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <m_fk_option>
delete_option
+%type <privilege>
+ column_privilege
+ object_privilege
+ opt_grant_options
+ opt_grant_option
+ grant_option_list
+ grant_option
+
+%type <lex_grant>
+ object_privilege_list
+ grant_privileges
+
+%type <lex_grant_ident>
+ grant_ident
+
%type <ulong_num>
ulong_num real_ulong_num merge_insert_types
ws_nweights
@@ -1602,9 +1631,8 @@ End SQL_MODE_ORACLE_SPECIFIC */
attribute attribute_list
compressed_deprecated_data_type_attribute
compressed_deprecated_column_attribute
- column_list column_list_id
- opt_column_list grant_privileges grant_ident grant_list grant_option
- object_privilege object_privilege_list user_list user_and_role_list
+ grant_list
+ user_list user_and_role_list
rename_list table_or_tables
clear_privileges flush_options flush_option
opt_flush_lock flush_lock flush_options_list
@@ -1717,7 +1745,10 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <lex_str_ptr> query_name
-%type <lex_str_list> opt_with_column_list with_column_list
+%type <ident_sys_list>
+ comma_separated_ident_list
+ opt_with_column_list
+ with_column_list
%type <vers_range_unit> opt_history_unit
%type <vers_history_point> history_point
@@ -2810,9 +2841,6 @@ clear_privileges:
{
LEX *lex=Lex;
lex->users_list.empty();
- lex->columns.empty();
- lex->grant= lex->grant_tot_col= 0;
- lex->all_privileges= 0;
lex->first_select_lex()->db= null_clex_str;
lex->account_options.reset();
}
@@ -2823,6 +2851,15 @@ opt_aggregate:
| AGGREGATE_SYM { $$= GROUP_AGGREGATE; }
;
+
+sp_handler:
+ FUNCTION_SYM { $$= &sp_handler_function; }
+ | PROCEDURE_SYM { $$= &sp_handler_procedure; }
+ | PACKAGE_ORACLE_SYM { $$= &sp_handler_package_spec; }
+ | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM { $$= &sp_handler_package_body; }
+ ;
+
+
sp_name:
ident '.' ident
{
@@ -14717,7 +14754,7 @@ with_list_element:
opt_with_column_list:
/* empty */
{
- if (($$= new (thd->mem_root) List<LEX_CSTRING>) == NULL)
+ if (($$= new (thd->mem_root) List<Lex_ident_sys>) == NULL)
MYSQL_YYABORT;
}
| '(' with_column_list ')'
@@ -14725,22 +14762,30 @@ opt_with_column_list:
;
with_column_list:
- ident
+ comma_separated_ident_list
+ ;
+
+ident_sys_alloc:
+ ident_cli
{
+ void *buf= thd->alloc(sizeof(Lex_ident_sys));
+ if (!buf)
+ MYSQL_YYABORT;
+ $$= new (buf) Lex_ident_sys(thd, &$1);
+ }
+ ;
- $$= new (thd->mem_root) List<LEX_CSTRING>;
- if (unlikely($$ == NULL) ||
- unlikely($$->push_back((LEX_CSTRING*)
- thd->memdup(&$1, sizeof(LEX_CSTRING)),
- thd->mem_root)))
+comma_separated_ident_list:
+ ident_sys_alloc
+ {
+ $$= new (thd->mem_root) List<Lex_ident_sys>;
+ if (unlikely($$ == NULL || $$->push_back($1)))
MYSQL_YYABORT;
}
- | with_column_list ',' ident
+ | comma_separated_ident_list ',' ident_sys_alloc
{
- $1->push_back((LEX_CSTRING*)
- thd->memdup(&$3, sizeof(LEX_CSTRING)),
- thd->mem_root);
- $$= $1;
+ if (($$= $1)->push_back($3))
+ MYSQL_YYABORT;
}
;
@@ -16615,34 +16660,12 @@ revoke:
revoke_command:
grant_privileges ON opt_table grant_ident FROM user_and_role_list
{
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_REVOKE;
- lex->type= 0;
- }
- | grant_privileges ON FUNCTION_SYM grant_ident FROM user_and_role_list
- {
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE,
- TYPE_ENUM_FUNCTION)))
- MYSQL_YYABORT;
- }
- | grant_privileges ON PROCEDURE_SYM grant_ident FROM user_and_role_list
- {
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE,
- TYPE_ENUM_PROCEDURE)))
+ if (Lex->stmt_revoke_table(thd, $1, *$4))
MYSQL_YYABORT;
}
- | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident
- FROM user_and_role_list
+ | grant_privileges ON sp_handler grant_ident FROM user_and_role_list
{
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE,
- TYPE_ENUM_PACKAGE)))
- MYSQL_YYABORT;
- }
- | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident
- FROM user_and_role_list
- {
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_REVOKE,
- TYPE_ENUM_PACKAGE_BODY)))
+ if (Lex->stmt_revoke_sp(thd, $1, *$4, *$3))
MYSQL_YYABORT;
}
| ALL opt_privileges ',' GRANT OPTION FROM user_and_role_list
@@ -16651,10 +16674,8 @@ revoke_command:
}
| PROXY_SYM ON user FROM user_list
{
- LEX *lex= Lex;
- lex->users_list.push_front ($3);
- lex->sql_command= SQLCOM_REVOKE;
- lex->type= TYPE_ENUM_PROXY;
+ if (Lex->stmt_revoke_proxy(thd, $3))
+ MYSQL_YYABORT;
}
| admin_option_for_role FROM user_and_role_list
{
@@ -16680,44 +16701,19 @@ grant_command:
grant_privileges ON opt_table grant_ident TO_SYM grant_list
opt_require_clause opt_grant_options
{
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_GRANT;
- lex->type= 0;
- }
- | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list
- opt_require_clause opt_grant_options
- {
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT,
- TYPE_ENUM_FUNCTION)))
- MYSQL_YYABORT;
- }
- | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list
- opt_require_clause opt_grant_options
- {
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT,
- TYPE_ENUM_PROCEDURE)))
- MYSQL_YYABORT;
- }
- | grant_privileges ON PACKAGE_ORACLE_SYM grant_ident TO_SYM grant_list
- opt_require_clause opt_grant_options
- {
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT,
- TYPE_ENUM_PACKAGE)))
+ if (Lex->stmt_grant_table(thd, $1, *$4, $8))
MYSQL_YYABORT;
}
- | grant_privileges ON PACKAGE_ORACLE_SYM BODY_ORACLE_SYM grant_ident TO_SYM grant_list
+ | grant_privileges ON sp_handler grant_ident TO_SYM grant_list
opt_require_clause opt_grant_options
{
- if (unlikely(Lex->add_grant_command(thd, SQLCOM_GRANT,
- TYPE_ENUM_PACKAGE_BODY)))
+ if (Lex->stmt_grant_sp(thd, $1, *$4, *$3, $8))
MYSQL_YYABORT;
}
| PROXY_SYM ON user TO_SYM grant_list opt_grant_option
{
- LEX *lex= Lex;
- lex->users_list.push_front ($3);
- lex->sql_command= SQLCOM_GRANT;
- lex->type= TYPE_ENUM_PROXY;
+ if (Lex->stmt_grant_proxy(thd, $3, $6))
+ MYSQL_YYABORT;
}
| grant_role TO_SYM grant_list opt_with_admin_option
{
@@ -16792,11 +16788,11 @@ opt_table:
;
grant_privileges:
- object_privilege_list {}
+ object_privilege_list
| ALL opt_privileges
{
- Lex->all_privileges= 1;
- Lex->grant= GLOBAL_ACLS;
+ if (!($$= new (thd->mem_root) Lex_grant_privilege(GLOBAL_ACLS, true)))
+ MYSQL_YYABORT;
}
;
@@ -16807,49 +16803,75 @@ opt_privileges:
object_privilege_list:
object_privilege
+ {
+ if (!($$= new (thd->mem_root) Lex_grant_privilege($1)))
+ MYSQL_YYABORT;
+ }
+ | column_list_privilege
+ {
+ if (!($$= new (thd->mem_root) Lex_grant_privilege()) ||
+ $$->add_column_list_privilege(thd, $1.m_columns[0],
+ $1.m_privilege))
+ MYSQL_YYABORT;
+ }
| object_privilege_list ',' object_privilege
+ {
+ ($$= $1)->add_object_privilege($3);
+ }
+ | object_privilege_list ',' column_list_privilege
+ {
+ if (($$= $1)->add_column_list_privilege(thd, $3.m_columns[0],
+ $3.m_privilege))
+ MYSQL_YYABORT;
+ }
+ ;
+
+column_list_privilege:
+ column_privilege '(' comma_separated_ident_list ')'
+ {
+ $$= Lex_column_list_privilege($3, $1);
+ }
+ ;
+
+column_privilege:
+ SELECT_SYM { $$= SELECT_ACL; }
+ | INSERT { $$= INSERT_ACL; }
+ | UPDATE_SYM { $$= UPDATE_ACL; }
+ | REFERENCES { $$= REFERENCES_ACL; }
;
object_privilege:
- SELECT_SYM
- { Lex->which_columns = SELECT_ACL;}
- opt_column_list {}
- | INSERT
- { Lex->which_columns = INSERT_ACL;}
- opt_column_list {}
- | UPDATE_SYM
- { Lex->which_columns = UPDATE_ACL; }
- opt_column_list {}
- | REFERENCES
- { Lex->which_columns = REFERENCES_ACL;}
- opt_column_list {}
- | DELETE_SYM { Lex->grant |= DELETE_ACL;}
- | USAGE {}
- | INDEX_SYM { Lex->grant |= INDEX_ACL;}
- | ALTER { Lex->grant |= ALTER_ACL;}
- | CREATE { Lex->grant |= CREATE_ACL;}
- | DROP { Lex->grant |= DROP_ACL;}
- | EXECUTE_SYM { Lex->grant |= EXECUTE_ACL;}
- | RELOAD { Lex->grant |= RELOAD_ACL;}
- | SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;}
- | PROCESS { Lex->grant |= PROCESS_ACL;}
- | FILE_SYM { Lex->grant |= FILE_ACL;}
- | GRANT OPTION { Lex->grant |= GRANT_ACL;}
- | SHOW DATABASES { Lex->grant |= SHOW_DB_ACL;}
- | SUPER_SYM { Lex->grant |= SUPER_ACL;}
- | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;}
- | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; }
- | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL; }
- | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL; }
- | CREATE VIEW_SYM { Lex->grant |= CREATE_VIEW_ACL; }
- | SHOW VIEW_SYM { Lex->grant |= SHOW_VIEW_ACL; }
- | CREATE ROUTINE_SYM { Lex->grant |= CREATE_PROC_ACL; }
- | ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; }
- | CREATE USER_SYM { Lex->grant |= CREATE_USER_ACL; }
- | EVENT_SYM { Lex->grant |= EVENT_ACL;}
- | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; }
- | CREATE TABLESPACE { Lex->grant |= CREATE_TABLESPACE_ACL; }
- | DELETE_SYM HISTORY_SYM { Lex->grant |= DELETE_HISTORY_ACL; }
+ SELECT_SYM { $$= SELECT_ACL; }
+ | INSERT { $$= INSERT_ACL; }
+ | UPDATE_SYM { $$= UPDATE_ACL; }
+ | REFERENCES { $$= REFERENCES_ACL; }
+ | DELETE_SYM { $$= DELETE_ACL;}
+ | USAGE { $$= 0; }
+ | INDEX_SYM { $$= INDEX_ACL;}
+ | ALTER { $$= ALTER_ACL;}
+ | CREATE { $$= CREATE_ACL;}
+ | DROP { $$= DROP_ACL;}
+ | EXECUTE_SYM { $$= EXECUTE_ACL;}
+ | RELOAD { $$= RELOAD_ACL;}
+ | SHUTDOWN { $$= SHUTDOWN_ACL;}
+ | PROCESS { $$= PROCESS_ACL;}
+ | FILE_SYM { $$= FILE_ACL;}
+ | GRANT OPTION { $$= GRANT_ACL;}
+ | SHOW DATABASES { $$= SHOW_DB_ACL;}
+ | SUPER_SYM { $$= SUPER_ACL;}
+ | CREATE TEMPORARY TABLES { $$= CREATE_TMP_ACL;}
+ | LOCK_SYM TABLES { $$= LOCK_TABLES_ACL; }
+ | REPLICATION SLAVE { $$= REPL_SLAVE_ACL; }
+ | REPLICATION CLIENT_SYM { $$= REPL_CLIENT_ACL; }
+ | CREATE VIEW_SYM { $$= CREATE_VIEW_ACL; }
+ | SHOW VIEW_SYM { $$= SHOW_VIEW_ACL; }
+ | CREATE ROUTINE_SYM { $$= CREATE_PROC_ACL; }
+ | ALTER ROUTINE_SYM { $$= ALTER_PROC_ACL; }
+ | CREATE USER_SYM { $$= CREATE_USER_ACL; }
+ | EVENT_SYM { $$= EVENT_ACL;}
+ | TRIGGER_SYM { $$= TRIGGER_ACL; }
+ | CREATE TABLESPACE { $$= CREATE_TABLESPACE_ACL; }
+ | DELETE_SYM HISTORY_SYM { $$= DELETE_HISTORY_ACL; }
;
opt_and:
@@ -16889,41 +16911,30 @@ require_list_element:
grant_ident:
'*'
{
- LEX *lex= Lex;
- if (unlikely(lex->copy_db_to(&lex->current_select->db)))
+ LEX_CSTRING db;
+ if (unlikely(Lex->copy_db_to(&db)))
+ MYSQL_YYABORT;
+ if (!($$= new (thd->mem_root) Lex_grant_object_name(db,
+ Lex_grant_object_name::STAR)))
MYSQL_YYABORT;
- if (lex->grant == GLOBAL_ACLS)
- lex->grant = DB_ACLS & ~GRANT_ACL;
- else if (unlikely(lex->columns.elements))
- my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)));
}
| ident '.' '*'
{
- LEX *lex= Lex;
- lex->current_select->db= $1;
- if (lex->grant == GLOBAL_ACLS)
- lex->grant = DB_ACLS & ~GRANT_ACL;
- else if (unlikely(lex->columns.elements))
- my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)));
+ if (!($$= new (thd->mem_root) Lex_grant_object_name($1,
+ Lex_grant_object_name::IDENT_STAR)))
+ MYSQL_YYABORT;
}
| '*' '.' '*'
{
- LEX *lex= Lex;
- lex->current_select->db= null_clex_str;
- if (lex->grant == GLOBAL_ACLS)
- lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
- else if (unlikely(lex->columns.elements))
- my_yyabort_error((ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)));
+ if (!($$= new (thd->mem_root) Lex_grant_object_name(
+ null_clex_str,
+ Lex_grant_object_name::STAR_STAR)))
+ MYSQL_YYABORT;
}
| table_ident
{
- LEX *lex=Lex;
- if (unlikely(!lex->current_select->
- add_table_to_list(thd, $1,NULL,
- TL_OPTION_UPDATING)))
+ if (!($$= new (thd->mem_root) Lex_grant_object_name($1)))
MYSQL_YYABORT;
- if (lex->grant == GLOBAL_ACLS)
- lex->grant = TABLE_ACLS & ~GRANT_ACL;
}
;
@@ -17034,49 +17045,6 @@ opt_auth_str:
}
;
-opt_column_list:
- /* empty */
- {
- LEX *lex=Lex;
- lex->grant |= lex->which_columns;
- }
- | '(' column_list ')' { }
- ;
-
-column_list:
- column_list ',' column_list_id
- | column_list_id
- ;
-
-column_list_id:
- ident
- {
- String *new_str= new (thd->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
- if (unlikely(new_str == NULL))
- MYSQL_YYABORT;
- List_iterator <LEX_COLUMN> iter(Lex->columns);
- class LEX_COLUMN *point;
- LEX *lex=Lex;
- while ((point=iter++))
- {
- if (!my_strcasecmp(system_charset_info,
- point->column.c_ptr(), new_str->c_ptr()))
- break;
- }
- lex->grant_tot_col|= lex->which_columns;
- if (point)
- point->rights |= lex->which_columns;
- else
- {
- LEX_COLUMN *col= (new (thd->mem_root)
- LEX_COLUMN(*new_str,lex->which_columns));
- if (unlikely(col == NULL))
- MYSQL_YYABORT;
- lex->columns.push_back(col, thd->mem_root);
- }
- }
- ;
-
opt_require_clause:
/* empty */
| REQUIRE_SYM require_list
@@ -17137,23 +17105,23 @@ opt_resource_options:
opt_grant_options:
- /* empty */ {}
- | WITH grant_option_list {}
+ /* empty */ { $$= 0; }
+ | WITH grant_option_list { $$= $2; }
;
opt_grant_option:
- /* empty */ {}
- | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ /* empty */ { $$= 0; }
+ | WITH GRANT OPTION { $$= GRANT_ACL; }
;
grant_option_list:
- grant_option_list grant_option {}
- | grant_option {}
+ grant_option_list grant_option { $$= $1 | $2; }
+ | grant_option
;
grant_option:
- GRANT OPTION { Lex->grant |= GRANT_ACL;}
- | resource_option {}
+ GRANT OPTION { $$= GRANT_ACL;}
+ | resource_option { $$= 0; }
;
begin_stmt_mariadb: