# name : innodb_admin_command_base.patch # introduced : 11 or before # maintainer : Yasufumi # #!!! notice !!! # Any small change to this file in the main branch # should be done or reviewed by the maintainer! --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -12041,7 +12041,8 @@ i_s_innodb_sys_foreign_cols, i_s_innodb_sys_stats, i_s_innodb_table_stats, -i_s_innodb_index_stats +i_s_innodb_index_stats, +i_s_innodb_admin_command mysql_declare_plugin_end; /** @brief Initialize the default value of innodb_commit_concurrency. --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -4243,3 +4243,140 @@ STRUCT_FLD(__reserved1, NULL), STRUCT_FLD(flags, 0UL) }; + +/*********************************************************************** +*/ +static ST_FIELD_INFO i_s_innodb_admin_command_info[] = +{ + {STRUCT_FLD(field_name, "result_message"), + STRUCT_FLD(field_length, 1024), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + END_OF_ST_FIELD_INFO +}; + +#ifndef INNODB_COMPATIBILITY_HOOKS +#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS +#endif + +extern "C" { +char **thd_query(MYSQL_THD thd); +} + +static +int +i_s_innodb_admin_command_fill( +/*==========================*/ + THD* thd, + TABLE_LIST* tables, + COND* cond) +{ + TABLE* i_s_table = (TABLE *) tables->table; + char** query_str; + char* ptr; + char quote = '\0'; + const char* command_head = "XTRA_"; + + DBUG_ENTER("i_s_innodb_admin_command_fill"); + + /* deny access to non-superusers */ + if (check_global_access(thd, PROCESS_ACL)) { + DBUG_RETURN(0); + } + + if(thd_sql_command(thd) != SQLCOM_SELECT) { + field_store_string(i_s_table->field[0], + "SELECT command is only accepted."); + goto end_func; + } + + query_str = thd_query(thd); + ptr = *query_str; + + for (; *ptr; ptr++) { + if (*ptr == quote) { + quote = '\0'; + } else if (quote) { + } else if (*ptr == '`' || *ptr == '"') { + quote = *ptr; + } else { + long i; + for (i = 0; command_head[i]; i++) { + if (toupper((int)(unsigned char)(ptr[i])) + != toupper((int)(unsigned char) + (command_head[i]))) { + goto nomatch; + } + } + break; +nomatch: + ; + } + } + + if (!*ptr) { + field_store_string(i_s_table->field[0], + "No XTRA_* command in the SQL statement." + " Please add /*!XTRA_xxxx*/ to the SQL."); + goto end_func; + } + + if (!strncasecmp("XTRA_HELLO", ptr, 10)) { + /* This is example command XTRA_HELLO */ + + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: administration command test for XtraDB" + " 'XTRA_HELLO' was detected.\n"); + + field_store_string(i_s_table->field[0], + "Hello!"); + goto end_func; + } + + field_store_string(i_s_table->field[0], + "Undefined XTRA_* command."); + goto end_func; + +end_func: + if (schema_table_store_record(thd, i_s_table)) { + DBUG_RETURN(1); + } else { + DBUG_RETURN(0); + } +} + +static +int +i_s_innodb_admin_command_init( +/*==========================*/ + void* p) +{ + DBUG_ENTER("i_s_innodb_admin_command_init"); + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; + + schema->fields_info = i_s_innodb_admin_command_info; + schema->fill_table = i_s_innodb_admin_command_fill; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_mysql_plugin i_s_innodb_admin_command = +{ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + STRUCT_FLD(info, &i_s_info), + STRUCT_FLD(name, "XTRADB_ADMIN_COMMAND"), + STRUCT_FLD(author, "Percona"), + STRUCT_FLD(descr, "XtraDB specific command acceptor"), + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + STRUCT_FLD(init, i_s_innodb_admin_command_init), + STRUCT_FLD(deinit, i_s_common_deinit), + STRUCT_FLD(version, 0x0100 /* 1.0 */), + STRUCT_FLD(status_vars, NULL), + STRUCT_FLD(system_vars, NULL), + STRUCT_FLD(__reserved1, NULL), + STRUCT_FLD(flags, 0UL) +}; --- a/storage/innobase/handler/i_s.h +++ b/storage/innobase/handler/i_s.h @@ -46,5 +46,6 @@ extern struct st_mysql_plugin i_s_innodb_sys_stats; extern struct st_mysql_plugin i_s_innodb_table_stats; extern struct st_mysql_plugin i_s_innodb_index_stats; +extern struct st_mysql_plugin i_s_innodb_admin_command; #endif /* i_s_h */ --- /dev/null +++ b/mysql-test/r/percona_xtradb_admin_command.result @@ -0,0 +1,6 @@ +select * from information_schema.XTRADB_ADMIN_COMMAND; +result_message +No XTRA_* command in the SQL statement. Please add /*!XTRA_xxxx*/ to the SQL. +select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/; +result_message +Hello! --- /dev/null +++ b/mysql-test/t/percona_xtradb_admin_command.test @@ -0,0 +1,3 @@ +--source include/have_innodb.inc +select * from information_schema.XTRADB_ADMIN_COMMAND; +select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/; --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -733,6 +733,10 @@ -V, --version Output version information and exit. --wait-timeout=# The number of seconds the server waits for activity on a connection before closing it + --xtradb-admin-command[=name] + Enable or disable XTRADB_ADMIN_COMMAND plugin. Possible + values are ON, OFF, FORCE (don't start if the plugin + fails to load). Variables (--variable-name=value) abort-slave-event-count 0 @@ -958,6 +962,7 @@ updatable-views-with-limit YES verbose TRUE wait-timeout 28800 +xtradb-admin-command ON To see what values a running MySQL server is using, type 'mysqladmin variables' instead of 'mysqld --verbose --help'.