MySQL 8.0.40
Source Code Documentation
sql_user_table.cc File Reference
#include "sql/auth/sql_user_table.h"
#include "my_config.h"
#include <stddef.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <memory>
#include <set>
#include <unordered_map>
#include <utility>
#include "lex_string.h"
#include "m_ctype.h"
#include "m_string.h"
#include "map_helpers.h"
#include "my_alloc.h"
#include "my_base.h"
#include "my_dbug.h"
#include "my_sqlcommand.h"
#include "my_sys.h"
#include "mysql/components/services/log_builtins.h"
#include "mysql/components/services/log_shared.h"
#include "mysql/psi/mysql_statement.h"
#include "mysql_com.h"
#include "mysql_time.h"
#include "mysqld_error.h"
#include "sql/auth/acl_change_notification.h"
#include "sql/auth/auth_acls.h"
#include "sql/auth/auth_common.h"
#include "sql/auth/auth_internal.h"
#include "sql/auth/sql_auth_cache.h"
#include "sql/auth/sql_authentication.h"
#include "sql/auth/sql_security_ctx.h"
#include "sql/binlog.h"
#include "sql/debug_sync.h"
#include "sql/error_handler.h"
#include "sql/field.h"
#include "sql/handler.h"
#include "sql/item_func.h"
#include "sql/key.h"
#include "sql/log.h"
#include "sql/mdl.h"
#include "sql/mysqld.h"
#include "sql/rpl_filter.h"
#include "sql/rpl_rli.h"
#include "sql/sql_base.h"
#include "sql/sql_class.h"
#include "sql/sql_connect.h"
#include "sql/sql_const.h"
#include "sql/sql_error.h"
#include "sql/sql_lex.h"
#include "sql/sql_list.h"
#include "sql/sql_parse.h"
#include "sql/sql_rewrite.h"
#include "sql/sql_table.h"
#include "sql/sql_update.h"
#include "sql/system_variables.h"
#include "sql/table.h"
#include "sql/transaction.h"
#include "sql/tztime.h"
#include "sql_string.h"
#include "thr_lock.h"
#include "typelib.h"
#include "violite.h"

Classes

class  acl_tables_setup_for_write_and_acquire_mdl_error_handler
 Internal_error_handler subclass to suppress ER_LOCK_DEADLOCK error. More...
 

Functions

static bool acl_tables_setup_for_write_and_acquire_mdl (THD *thd, Table_ref *tables)
 Setup ACL tables to be opened in write mode. More...
 
void commit_and_close_mysql_tables (THD *thd)
 A helper function to commit statement transaction and close ACL tables after reading some data from them as part of FLUSH PRIVILEGES statement or during server initialization. More...
 
Access_bitmask get_access (TABLE *form, uint fieldnr, uint *next_field)
 
void acl_notify_htons (THD *thd, enum_sql_command operation, const List< LEX_USER > *users, std::set< LEX_USER * > *rewrite_users, const List< LEX_CSTRING > *dynamic_privs)
 
static bool acl_end_trans_and_close_tables (THD *thd, bool rollback_transaction)
 Commit or rollback ACL statement (and transaction), close tables which it has opened and release metadata locks. More...
 
bool log_and_commit_acl_ddl (THD *thd, bool transactional_tables, std::set< LEX_USER * > *extra_users, Rewrite_params *rewrite_params, bool extra_error, bool write_to_binlog)
 
static void get_grantor (THD *thd, char *grantor)
 
void acl_print_ha_error (int handler_error)
 Take a handler error and generate the mysql error ER_ACL_OPERATION_FAILED containing original text of HA error. More...
 
int replace_db_table (THD *thd, TABLE *table, const char *db, const LEX_USER &combo, Access_bitmask rights, bool revoke_grant)
 change grants in the mysql.db table. More...
 
int replace_proxies_priv_table (THD *thd, TABLE *table, const LEX_USER *user, const LEX_USER *proxied_user, bool with_grant_arg, bool revoke_grant)
 Insert, update or remove a record in the mysql.proxies_priv table. More...
 
int replace_column_table (THD *thd, GRANT_TABLE *g_t, TABLE *table, const LEX_USER &combo, List< LEX_COLUMN > &columns, const char *db, const char *table_name, Access_bitmask rights, bool revoke_grant)
 Update record in the table mysql.columns_priv. More...
 
int replace_table_table (THD *thd, GRANT_TABLE *grant_table, std::unique_ptr< GRANT_TABLE, Destroy_only< GRANT_TABLE > > *deleted_grant_table, TABLE *table, const LEX_USER &combo, const char *db, const char *table_name, Access_bitmask rights, Access_bitmask col_rights, bool revoke_grant)
 Search and create/update a record for requested table privileges. More...
 
int replace_routine_table (THD *thd, GRANT_NAME *grant_name, TABLE *table, const LEX_USER &combo, const char *db, const char *routine_name, bool is_proc, Access_bitmask rights, bool revoke_grant)
 Search and create/update a record for the routine requested. More...
 
static void acl_tables_setup (Table_ref *tables, thr_lock_type lock_type, enum_mdl_type mdl_type)
 Construct Table_ref array for ACL tables. More...
 
void acl_tables_setup_for_read (Table_ref *tables)
 Setup ACL tables to be opened in read mode. More...
 
int open_grant_tables (THD *thd, Table_ref *tables, bool *transactional_tables)
 Open the grant tables. More...
 
static int modify_grant_table (TABLE *table, Field *host_field, Field *user_field, LEX_USER *user_to)
 Modify a privilege table. More...
 
int handle_grant_table (THD *, Table_ref *tables, ACL_TABLES table_no, bool drop, LEX_USER *user_from, LEX_USER *user_to)
 Handle a privilege table. More...
 
bool check_engine_type_for_acl_table (Table_ref *tables, bool report_error)
 Check that every ACL table has a supported storage engine (InnoDB). More...
 
bool is_acl_table_name (const char *name)
 Check if given table name is a ACL table name. More...
 
bool is_acl_table (const TABLE *table)
 Check if given TABLE* is a ACL table name. More...
 

Variables

static const int MAX_ACL_TABLE_NAMES = 10
 
static const char * ACL_TABLE_NAMES [MAX_ACL_TABLE_NAMES]
 
static const TABLE_FIELD_TYPE mysql_db_table_fields [MYSQL_DB_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_user_table_fields [MYSQL_USER_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_proxies_priv_table_fields [MYSQL_PROXIES_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_procs_priv_table_fields [MYSQL_PROCS_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_columns_priv_table_fields [MYSQL_COLUMNS_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_tables_priv_table_fields [MYSQL_TABLES_PRIV_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_role_edges_table_fields [MYSQL_ROLE_EDGES_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_default_roles_table_fields [MYSQL_DEFAULT_ROLES_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_password_history_table_fields [MYSQL_PASSWORD_HISTORY_FIELD_COUNT]
 
static const TABLE_FIELD_TYPE mysql_dynamic_priv_table_fields [MYSQL_DYNAMIC_PRIV_FIELD_COUNT]
 
bool initialized
 

Function Documentation

◆ acl_end_trans_and_close_tables()

static bool acl_end_trans_and_close_tables ( THD thd,
bool  rollback_transaction 
)
static

Commit or rollback ACL statement (and transaction), close tables which it has opened and release metadata locks.

Note
In case of failure to commit transaction we try to restore correct state of in-memory structures by reloading privileges.
Return values
False- Success.
True- Error.

◆ acl_notify_htons()

void acl_notify_htons ( THD thd,
enum_sql_command  operation,
const List< LEX_USER > *  users,
std::set< LEX_USER * > *  rewrite_users,
const List< LEX_CSTRING > *  dynamic_privs 
)

◆ acl_print_ha_error()

void acl_print_ha_error ( int  handler_error)

Take a handler error and generate the mysql error ER_ACL_OPERATION_FAILED containing original text of HA error.

Parameters
handler_erroran error number resulted from storage engine

◆ acl_tables_setup()

static void acl_tables_setup ( Table_ref tables,
thr_lock_type  lock_type,
enum_mdl_type  mdl_type 
)
static

Construct Table_ref array for ACL tables.

Parameters
[in,out]tablesTable_ref array
[in]lock_typeRead or Write
[in]mdl_typeMDL to be used

◆ acl_tables_setup_for_read()

void acl_tables_setup_for_read ( Table_ref tables)

Setup ACL tables to be opened in read mode.

Prepare references to all of the grant tables in the order of the ACL_TABLES enum.

Parameters
[in,out]tablesTable handles

◆ acl_tables_setup_for_write_and_acquire_mdl()

static bool acl_tables_setup_for_write_and_acquire_mdl ( THD thd,
Table_ref tables 
)
static

Setup ACL tables to be opened in write mode.

Prepare references to all of the grant tables in the order of the ACL_TABLES enum.

Obtain locks on required MDLs upfront.

Parameters
[in]thdTHD handle
[in,out]tablesTable handles
Returns
Status of MDL acquisition
Return values
falseOK
trueError

◆ check_engine_type_for_acl_table()

bool check_engine_type_for_acl_table ( Table_ref tables,
bool  report_error 
)

Check that every ACL table has a supported storage engine (InnoDB).

Report error if table's engine type is not supported.

Parameters
tablesPointer to TABLES_LIST of ACL tables to check.
report_errorIf true report error to the client/diagnostic area, otherwise write a warning to the error log.
Returns
bool
Return values
falseOK
truesome of ACL tables has an unsupported engine type.

◆ commit_and_close_mysql_tables()

void commit_and_close_mysql_tables ( THD thd)

A helper function to commit statement transaction and close ACL tables after reading some data from them as part of FLUSH PRIVILEGES statement or during server initialization.

Note
We assume that we have only read from the tables so commit can't fail.
See also
close_mysql_tables().
Note
This function also rollbacks the transaction if rollback was requested (e.g. as result of deadlock).

◆ get_access()

Access_bitmask get_access ( TABLE form,
uint  fieldnr,
uint next_field 
)

◆ get_grantor()

static void get_grantor ( THD thd,
char *  grantor 
)
static

◆ handle_grant_table()

int handle_grant_table ( THD ,
Table_ref tables,
ACL_TABLES  table_no,
bool  drop,
LEX_USER user_from,
LEX_USER user_to 
)

Handle a privilege table.

Parameters
tablesThe array with the four open tables.
table_noThe number of the table to handle (0..4).
dropIf user_from is to be dropped.
user_fromThe the user to be searched/dropped/renamed.
user_toThe new name for the user if to be renamed, NULL otherwise.

This function scans through following tables: mysql.user, mysql.db, mysql.tables_priv, mysql.columns_priv, mysql.procs_priv, mysql.proxies_priv. For all above tables, we do an index scan and then iterate over the found records do following: Delete from grant table if drop is true. Update in grant table if drop is false and user_to is not NULL. Search in grant table if drop is false and user_to is NULL.

Returns
Operation result
Return values
0OK, but no record matched.
<0 Error.
>0 At least one record matched.

◆ is_acl_table()

bool is_acl_table ( const TABLE table)

Check if given TABLE* is a ACL table name.

Parameters
tableTABLE object.
Returns
bool
Return values
trueIf it is a ACL table, otherwise false.

◆ is_acl_table_name()

bool is_acl_table_name ( const char *  name)

Check if given table name is a ACL table name.

Parameters
nameTable name.
Returns
bool
Return values
trueIf it is a ACL table, otherwise false.

◆ log_and_commit_acl_ddl()

bool log_and_commit_acl_ddl ( THD thd,
bool  transactional_tables,
std::set< LEX_USER * > *  extra_users,
Rewrite_params rewrite_params,
bool  extra_error,
bool  write_to_binlog 
)

◆ modify_grant_table()

static int modify_grant_table ( TABLE table,
Field host_field,
Field user_field,
LEX_USER user_to 
)
static

Modify a privilege table.

Parameters
tableThe table to modify.
host_fieldThe host name field.
user_fieldThe user name field.
user_toThe new name for the user if to be renamed, NULL otherwise.
Note
Update user/host in the current record if user_to is not NULL. Delete the current record if user_to is NULL.
Return values
0OK.
!=0 Error.

◆ open_grant_tables()

int open_grant_tables ( THD thd,
Table_ref tables,
bool *  transactional_tables 
)

Open the grant tables.

Parameters
thdThe current thread.
[in,out]tablesArray of ACL_TABLES::LAST_ENTRY table list elements which will be used for opening tables.
[out]transactional_tablesSet to true if one of grant tables is transactional, false otherwise.
Return values
1Skip GRANT handling during replication.
0OK.
<0 Error.
Note
IX Backup Lock is implicitly acquired as side effect of calling this function.

◆ replace_column_table()

int replace_column_table ( THD thd,
GRANT_TABLE g_t,
TABLE table,
const LEX_USER combo,
List< LEX_COLUMN > &  columns,
const char *  db,
const char *  table_name,
Access_bitmask  rights,
bool  revoke_grant 
)

Update record in the table mysql.columns_priv.

Parameters
thdCurrent thread execution context.
g_tPointer to a cached table grant object
tablePointer to a TABLE object for open mysql.columns_priv table
comboPointer to a LEX_USER object containing info about a user being processed
columnsList of columns to give/revoke grant
dbDatabase name of table for which column privileges are modified
table_nameName of table for which column privileges are modified
rightsTable level grant
revoke_grantSet to true if this is a REVOKE command
Returns
Operation result
Return values
0OK.
<0 System error or storage engine error happen
>0 Error in handling current user entry but still can continue processing subsequent user specified in the ACL statement.

◆ replace_db_table()

int replace_db_table ( THD thd,
TABLE table,
const char *  db,
const LEX_USER combo,
Access_bitmask  rights,
bool  revoke_grant 
)

change grants in the mysql.db table.

Parameters
thdCurrent thread execution context.
tablePointer to a TABLE object for opened mysql.db table.
dbDatabase name of table for which column privileges are modified.
comboPointer to a LEX_USER object containing info about a user being processed.
rightsDatabase level grant.
revoke_grantSet to true if this is a REVOKE command.
Returns
Operation result
Return values
0OK.
1Error in handling current user entry but still can continue processing subsequent user specified in the ACL statement.
<0 Error.

◆ replace_proxies_priv_table()

int replace_proxies_priv_table ( THD thd,
TABLE table,
const LEX_USER user,
const LEX_USER proxied_user,
bool  with_grant_arg,
bool  revoke_grant 
)

Insert, update or remove a record in the mysql.proxies_priv table.

Parameters
thdThe current thread.
tablePointer to a TABLE object for opened mysql.proxies_priv table.
userInformation about user being handled.
proxied_userInformation about proxied user being handled.
with_grant_argTrue if a user is allowed to execute GRANT, else false.
revoke_grantSet to true if this is REVOKE command.
Returns
Operation result.
Return values
0OK.
1Error in handling current user entry but still can continue processing subsequent user specified in the ACL statement.
<0 Error.

◆ replace_routine_table()

int replace_routine_table ( THD thd,
GRANT_NAME grant_name,
TABLE table,
const LEX_USER combo,
const char *  db,
const char *  routine_name,
bool  is_proc,
Access_bitmask  rights,
bool  revoke_grant 
)

Search and create/update a record for the routine requested.

Parameters
thdThe current thread.
grant_nameCached info about stored routine.
tablePointer to a TABLE object for open mysql.procs_priv table.
comboUser information.
dbDatabase name for stored routine.
routine_nameName for stored routine.
is_procTrue for stored procedure, false for stored function.
rightsRights requested.
revoke_grantSet to true if a REVOKE command is executed.
Returns
Operation result
Return values
0OK.
<0 System error or storage engine error happen
>0 Error in handling current routine entry but still can continue processing subsequent user specified in the ACL statement.

◆ replace_table_table()

int replace_table_table ( THD thd,
GRANT_TABLE grant_table,
std::unique_ptr< GRANT_TABLE, Destroy_only< GRANT_TABLE > > *  deleted_grant_table,
TABLE table,
const LEX_USER combo,
const char *  db,
const char *  table_name,
Access_bitmask  rights,
Access_bitmask  col_rights,
bool  revoke_grant 
)

Search and create/update a record for requested table privileges.

Parameters
thdThe current thread.
grant_tableCached info about table/columns privileges.
deleted_grant_tableIf non-nullptr and grant is removed from column cache, it is returned here instead of being destroyed.
tablePointer to a TABLE object for open mysql.tables_priv table.
comboUser information.
dbDatabase name of table to give grant.
table_nameName of table to give grant.
rightsTable privileges to set/update.
col_rightsColumn privileges to set/update.
revoke_grantSet to true if a REVOKE command is executed.
Returns
Operation result
Return values
0OK.
<0 System error or storage engine error happen.
1No entry for request.

Variable Documentation

◆ ACL_TABLE_NAMES

const char* ACL_TABLE_NAMES[MAX_ACL_TABLE_NAMES]
static
Initial value:
= {
"user", "db",
"tables_priv", "columns_priv",
"procs_priv", "proxies_priv",
"role_edges", "default_roles",
"global_grants", "password_history"}

◆ initialized

bool initialized
extern

◆ MAX_ACL_TABLE_NAMES

const int MAX_ACL_TABLE_NAMES = 10
static

◆ mysql_columns_priv_table_fields

const TABLE_FIELD_TYPE mysql_columns_priv_table_fields[MYSQL_COLUMNS_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Db")}, {STRING_WITH_LEN("char(64)")}, {nullptr, 0}},
{{STRING_WITH_LEN("User")},
{nullptr, 0}},
{{STRING_WITH_LEN("Table_name")},
{STRING_WITH_LEN("char(64)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Column_name")},
{STRING_WITH_LEN("char(64)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{nullptr, 0}},
{{STRING_WITH_LEN("Column_priv")},
{STRING_WITH_LEN("set('Select','Insert','Update','References')")},
{STRING_WITH_LEN("utf8mb3")}}}
#define STRING_WITH_LEN(X)
Definition: m_string.h:315
#define USERNAME_CHAR_LENGTH_STR
Definition: mysql_com.h:65

◆ mysql_db_table_fields

const TABLE_FIELD_TYPE mysql_db_table_fields[MYSQL_DB_FIELD_COUNT]
static

◆ mysql_default_roles_table_fields

const TABLE_FIELD_TYPE mysql_default_roles_table_fields[MYSQL_DEFAULT_ROLES_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("HOST")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("USER")},
{nullptr, 0}},
{{STRING_WITH_LEN("DEFAULT_ROLE_HOST")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("DEFAULT_ROLE_USER")},
{nullptr, 0}}}

◆ mysql_dynamic_priv_table_fields

const TABLE_FIELD_TYPE mysql_dynamic_priv_table_fields[MYSQL_DYNAMIC_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("USER")},
{nullptr, 0}},
{{STRING_WITH_LEN("HOST")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("PRIV")},
{STRING_WITH_LEN("char(32)")},
{nullptr, 0}},
{{STRING_WITH_LEN("WITH_GRANT_OPTION")},
{STRING_WITH_LEN("enum('N','Y')")},
{nullptr, 0}}}

◆ mysql_password_history_table_fields

const TABLE_FIELD_TYPE mysql_password_history_table_fields[MYSQL_PASSWORD_HISTORY_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("User")},
{nullptr, 0}},
{{STRING_WITH_LEN("Password_timestamp")},
{STRING_WITH_LEN("timestamp")},
{nullptr, 0}},
{{STRING_WITH_LEN("Password")},
{STRING_WITH_LEN("text")},
{nullptr, 0}}}

◆ mysql_procs_priv_table_fields

const TABLE_FIELD_TYPE mysql_procs_priv_table_fields[MYSQL_PROCS_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Db")}, {STRING_WITH_LEN("char(64)")}, {nullptr, 0}},
{{STRING_WITH_LEN("User")},
{nullptr, 0}},
{{STRING_WITH_LEN("Routine_name")},
{STRING_WITH_LEN("char(64)")},
{STRING_WITH_LEN("utf8mb3")}},
{{STRING_WITH_LEN("Routine_type")},
{STRING_WITH_LEN("enum('FUNCTION','PROCEDURE')")},
{nullptr, 0}},
{{STRING_WITH_LEN("Grantor")},
{STRING_WITH_LEN("varchar(288)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Proc_priv")},
{STRING_WITH_LEN("set('Execute','Alter Routine','Grant')")},
{STRING_WITH_LEN("utf8mb3")}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{nullptr, 0}}}

◆ mysql_proxies_priv_table_fields

const TABLE_FIELD_TYPE mysql_proxies_priv_table_fields[MYSQL_PROXIES_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("User")},
{nullptr, 0}},
{{STRING_WITH_LEN("Proxied_host")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Proxied_user")},
{nullptr, 0}},
{{STRING_WITH_LEN("With_grant")},
{STRING_WITH_LEN("tinyint")},
{nullptr, 0}},
{{STRING_WITH_LEN("Grantor")},
{STRING_WITH_LEN("varchar(288)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{nullptr, 0}}}

◆ mysql_role_edges_table_fields

const TABLE_FIELD_TYPE mysql_role_edges_table_fields[MYSQL_ROLE_EDGES_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("FROM_HOST")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("FROM_USER")},
{nullptr, 0}},
{{STRING_WITH_LEN("TO_HOST")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("TO_USER")},
{nullptr, 0}},
{{STRING_WITH_LEN("WITH_ADMIN_OPTION")},
{STRING_WITH_LEN("enum('N','Y')")},
{STRING_WITH_LEN("utf8mb3")}}}

◆ mysql_tables_priv_table_fields

const TABLE_FIELD_TYPE mysql_tables_priv_table_fields[MYSQL_TABLES_PRIV_FIELD_COUNT]
static
Initial value:
= {
{{STRING_WITH_LEN("Host")},
{STRING_WITH_LEN("char(255)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Db")}, {STRING_WITH_LEN("char(64)")}, {nullptr, 0}},
{{STRING_WITH_LEN("User")},
{nullptr, 0}},
{{STRING_WITH_LEN("Table_name")},
{STRING_WITH_LEN("char(64)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Grantor")},
{STRING_WITH_LEN("varchar(288)")},
{nullptr, 0}},
{{STRING_WITH_LEN("Timestamp")},
{STRING_WITH_LEN("timestamp")},
{nullptr, 0}},
{{STRING_WITH_LEN("Table_priv")},
{STRING_WITH_LEN("set('Select','Insert','Update','Delete','Create',"
"'Drop','Grant','References','Index','Alter',"
"'Create View','Show view','Trigger')")},
{STRING_WITH_LEN("utf8mb3")}},
{{STRING_WITH_LEN("Column_priv")},
{STRING_WITH_LEN("set('Select','Insert','Update','References')")},
{STRING_WITH_LEN("utf8mb3")}}}

◆ mysql_user_table_fields

const TABLE_FIELD_TYPE mysql_user_table_fields[MYSQL_USER_FIELD_COUNT]
static