Below is the list of changes that have just been committed into a local
5.1 repository of monty. When monty does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2221 06/06/20 13:20:32 monty@stripped +21 -0
SHOW STATUS does not anymore change local status variables (except com_show_status).
Global status variables are still updated.
SHOW STATUS are not anymore put in slow query log because of no index usage.
Implemntation done by removing orig_sql_command and moving logic of SHOW STATUS to
mysql_excute_command()
This simplifies code and allows us to remove some if statements all over the code.
Upgraded uc_update_queries[] to sql_command_flags and added more bitmaps to better
categorize commands.
This allowed some overall simplifaction when testing sql_command.
Fixes bugs:
Bug#10210: running SHOW STATUS increments counters it shouldn't
Bug#19764: SHOW commands end up in the slow log as table scans
sql/structs.h
1.62 06/06/20 13:20:28 monty@stripped +1 -1
Updated comment
sql/sql_yacc.yy
1.483 06/06/20 13:20:28 monty@stripped +25 -40
Remove usage of orig_sql_command.
One side effect of this is that we need to test for cursors if the current command is
a SELECT or a SHOW command.
sql/sql_show.cc
1.352 06/06/20 13:20:28 monty@stripped +39 -33
Remove orig_sql_command
Only change sql_command during 'open_normal_and_derived_tables()' (for views) and not
for the full duration of generating data.
Changed 'show status' to use thd->initial_status_var to ensure that the current
statement is not affecting the to-be-used values.
Use thd->fill_information_schema_tables() instead of
'thd->fill_derived_tables()' as the later wrongly checks the value of sql_command.
sql/sql_select.cc
1.414 06/06/20 13:20:28 monty@stripped +1 -6
Remove special handling of SHOW STATUS.
(This is now done in SQLCOM_SHOW_STATUS part in mysql_execute_command())
sql/sql_prepare.cc
1.173 06/06/20 13:20:28 monty@stripped +15 -12
Clean up prepare-check handling of SQLCOM commands by using sql_command_flags[]
This simplifes code and ensures that code works even if someone forgets to put a new
status commands into the switch statement.
sql/sql_parse.cc
1.562 06/06/20 13:20:28 monty@stripped +174 -110
Rename uc_update_queries -> sql_command_flags.
Enhanced 'sql_command_flags' to better classify SQL commands
uc_update_queries[] != 0 is changed to (sql_command_flags[] & CF_CHANGES_DATA)
lex->orig_sql_command == SQLCOM_END is changed to
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
Simplify incrementing of thd->status_var.com_stat[] as we don't have to do special
handling for SHOW commands.
Split SQLCOM_SELECT handling in mysql_execute_command() to a separate function.
Added special handling of SHOW STATUS commands in mysql_execute_command() and call
common SQLCOM_SELECT handling.
These changes allows us to easily fix that we save and restore status variables during
execution of a SHOW STATUS command.
Don't log SHOW STATUS commands to slow query log.
This fixes Bug#10210 and Bug#19764 without adding additional 'if' code.
(The new code is faster than the original as we now have fewer if's than before)
sql/sql_lex.h
1.234 06/06/20 13:20:28 monty@stripped +1 -1
Remove orig_sql_command
sql/sql_lex.cc
1.186 06/06/20 13:20:28 monty@stripped +1 -1
Remove orig_sql_command
sql/sql_class.h
1.299 06/06/20 13:20:28 monty@stripped +14 -2
New function 'fill_information_schema_tables()'
(One could not anymore use fill_derived_tables() for this as only_view_structures() is
not relevant for information schema tables)
Added defines for bit flags in sql_command_flags[]
sql/sql_class.cc
1.267 06/06/20 13:20:28 monty@stripped +25 -0
New function add_diff_to_status(), used to update global status variables when using
SHOW STATUS
sql/mysql_priv.h
1.411 06/06/20 13:20:28 monty@stripped +1 -0
Added 'sql_command_flags'
mysql-test/t/status.test
1.16 06/06/20 13:20:28 monty@stripped +34 -0
Added more tests for testing of last_query_cost and how SHOW STATUS affects status
variables.
(Bug #10210)
mysql-test/t/query_cache.test
1.61 06/06/20 13:20:28 monty@stripped +3 -0
Remove resuts from previous tests
mysql-test/t/information_schema.test
1.83 06/06/20 13:20:28 monty@stripped +2 -0
Added extra test to cover more code
mysql-test/t/events_microsec.test
1.4 06/06/20 13:20:28 monty@stripped +3 -0
Disable warnings at init
mysql-test/r/union.result
1.85 06/06/20 13:20:28 monty@stripped +4 -4
Fixed results after SHOW STATUS is not logged to slow query log
(Bug#19764)
mysql-test/r/temp_table.result
1.24 06/06/20 13:20:28 monty@stripped +1 -1
Fixed results after SHOW STATUS doesn't anymore affect status variables
mysql-test/r/status.result
1.12 06/06/20 13:20:27 monty@stripped +50 -0
Added more tests for testing of last_query_cost and how SHOW STATUS affects status
variables.
(Bug#10210)
mysql-test/r/query_cache.result
1.75 06/06/20 13:20:27 monty@stripped +1 -0
Remove resuts from previous tests
mysql-test/r/information_schema.result
1.125 06/06/20 13:20:27 monty@stripped +2 -0
Added extra test to cover more code
mysql-test/r/grant_cache.result
1.17 06/06/20 13:20:27 monty@stripped +8 -8
Fixed results after SHOW STATUS doesn't anymore affect status variables
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: monty
# Host: narttu.mysql.fi
# Root: /home/my/mysql-5.1
--- 1.410/sql/mysql_priv.h 2006-06-15 14:38:08 +03:00
+++ 1.411/sql/mysql_priv.h 2006-06-20 13:20:28 +03:00
@@ -1582,6 +1582,7 @@
extern const char* any_db;
extern struct my_option my_long_options[];
extern const LEX_STRING view_type;
+extern uint sql_command_flags[];
/* optional things, have_* variables */
--- 1.266/sql/sql_class.cc 2006-06-18 13:20:28 +03:00
+++ 1.267/sql/sql_class.cc 2006-06-20 13:20:28 +03:00
@@ -516,6 +516,31 @@
/* it doesn't make sense to add last_query_cost values */
}
+/*
+ Add the difference between two status variable arrays to another one.
+
+ SYNOPSIS
+ add_diff_to_status
+ to_var add to this array
+ from_var from this array
+ dec_var minus this array
+
+ NOTE
+ This function assumes that all variables are long/ulong.
+*/
+
+void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
+ STATUS_VAR *dec_var)
+{
+ ulong *end= (ulong*) ((byte*) to_var + offsetof(STATUS_VAR,
+ last_system_status_var) +
+ sizeof(ulong));
+ ulong *to= (ulong*) to_var, *from= (ulong*) from_var, *dec= (ulong*) dec_var;
+
+ while (to != end)
+ *(to++)+= *(from++) - *(dec++);
+}
+
void THD::awake(THD::killed_state state_to_set)
{
--- 1.298/sql/sql_class.h 2006-06-18 13:20:28 +03:00
+++ 1.299/sql/sql_class.h 2006-06-20 13:20:28 +03:00
@@ -343,7 +343,6 @@
#define last_system_status_var com_stmt_close
-
#ifdef MYSQL_SERVER
void free_tmp_table(THD *thd, TABLE *entry);
@@ -833,6 +832,7 @@
struct rand_struct rand; // used for authentication
struct system_variables variables; // Changeable local variables
struct system_status_var status_var; // Per thread statistic vars
+ struct system_status_var *initial_status_var; /* used by show status */
THR_LOCK_INFO lock_info; // Locking info of this thread
THR_LOCK_OWNER main_lock_id; // To use for conventional queries
THR_LOCK_OWNER *lock_id; // If not main_lock_id, points to
@@ -1306,6 +1306,10 @@
{
return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure();
}
+ inline bool fill_information_schema_tables()
+ {
+ return !stmt_arena->is_stmt_prepare();
+ }
inline gptr trans_alloc(unsigned int size)
{
return alloc_root(&transaction.mem_root,size);
@@ -1952,8 +1956,16 @@
void cleanup();
};
+/* Bits in sql_command_flags */
+
+#define CF_CHANGES_DATA 1
+#define CF_HAS_ROW_COUNT 2
+#define CF_STATUS_COMMAND 4
+#define CF_SHOW_TABLE_COMMAND 8
+
/* Functions in sql_class.cc */
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
-
+void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
+ STATUS_VAR *dec_var);
#endif /* MYSQL_SERVER */
--- 1.185/sql/sql_lex.cc 2006-06-18 13:20:28 +03:00
+++ 1.186/sql/sql_lex.cc 2006-06-20 13:20:28 +03:00
@@ -168,7 +168,7 @@
lex->select_lex.group_list.empty();
lex->select_lex.order_list.empty();
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
- lex->sql_command= lex->orig_sql_command= SQLCOM_END;
+ lex->sql_command= SQLCOM_END;
lex->duplicates= DUP_ERROR;
lex->ignore= 0;
lex->sphead= NULL;
--- 1.233/sql/sql_lex.h 2006-06-18 13:20:28 +03:00
+++ 1.234/sql/sql_lex.h 2006-06-20 13:20:28 +03:00
@@ -934,7 +934,7 @@
the variable can contain 0 or 1 for each nest level.
*/
nesting_map allow_sum_func;
- enum_sql_command sql_command, orig_sql_command;
+ enum_sql_command sql_command;
thr_lock_type lock_option;
enum SSL_type ssl_type; /* defined in violite.h */
enum my_lex_states next_state;
--- 1.561/sql/sql_parse.cc 2006-06-18 13:20:28 +03:00
+++ 1.562/sql/sql_parse.cc 2006-06-20 13:20:28 +03:00
@@ -68,6 +68,7 @@
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_multi_update_lock(THD *thd);
static void remove_escape(char *name);
+static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
const char *any_db="*any*"; // Special symbol for check_access
@@ -626,50 +627,79 @@
sql_command is actually set to SQLCOM_END sometimes
so we need the +1 to include it in the array.
- numbers are:
- 0 - read-only query
- != 0 - query that may change a table
+ See COMMAND_FLAG_xxx for different type of commands
2 - query that returns meaningful ROW_COUNT() -
a number of modified rows
*/
-char uc_update_queries[SQLCOM_END+1];
+uint sql_command_flags[SQLCOM_END+1];
void init_update_queries(void)
{
- bzero((gptr) &uc_update_queries, sizeof(uc_update_queries));
+ bzero((gptr) &sql_command_flags, sizeof(sql_command_flags));
- uc_update_queries[SQLCOM_CREATE_TABLE]=1;
- uc_update_queries[SQLCOM_CREATE_INDEX]=1;
- uc_update_queries[SQLCOM_ALTER_TABLE]=1;
- uc_update_queries[SQLCOM_UPDATE]=2;
- uc_update_queries[SQLCOM_UPDATE_MULTI]=2;
- uc_update_queries[SQLCOM_INSERT]=2;
- uc_update_queries[SQLCOM_INSERT_SELECT]=2;
- uc_update_queries[SQLCOM_DELETE]=2;
- uc_update_queries[SQLCOM_DELETE_MULTI]=2;
- uc_update_queries[SQLCOM_TRUNCATE]=1;
- uc_update_queries[SQLCOM_DROP_TABLE]=1;
- uc_update_queries[SQLCOM_LOAD]=1;
- uc_update_queries[SQLCOM_CREATE_DB]=1;
- uc_update_queries[SQLCOM_DROP_DB]=1;
- uc_update_queries[SQLCOM_REPLACE]=2;
- uc_update_queries[SQLCOM_REPLACE_SELECT]=2;
- uc_update_queries[SQLCOM_RENAME_TABLE]=1;
- uc_update_queries[SQLCOM_BACKUP_TABLE]=1;
- uc_update_queries[SQLCOM_RESTORE_TABLE]=1;
- uc_update_queries[SQLCOM_DROP_INDEX]=1;
- uc_update_queries[SQLCOM_CREATE_VIEW]=1;
- uc_update_queries[SQLCOM_DROP_VIEW]=1;
- uc_update_queries[SQLCOM_CREATE_EVENT]=1;
- uc_update_queries[SQLCOM_ALTER_EVENT]=1;
- uc_update_queries[SQLCOM_DROP_EVENT]=1;
+ sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
+
+ sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
+
+ sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND;
+ sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND;
+
+ sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
+ CF_SHOW_TABLE_COMMAND);
+ sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
+ CF_SHOW_TABLE_COMMAND);
+
+ /*
+ The following is used to preserver CF_ROW_COUNT during the
+ a CALL or EXECUTE statement, so the value generated by the
+ last called (or executed) statement is preserved.
+ See mysql_execute_command() for how CF_ROW_COUNT is used.
+ */
+ sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT;
+ sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT;
}
+
bool is_update_query(enum enum_sql_command command)
{
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
- return uc_update_queries[command] != 0;
+ return (sql_command_flags[command] & CF_CHANGES_DATA) == 0;
}
/*
@@ -733,7 +763,8 @@
if (check_command < (uint) SQLCOM_END)
{
/* Check that we have not done too many updates / hour */
- if (uc->user_resources.updates && uc_update_queries[check_command]
&&
+ if (uc->user_resources.updates &&
+ (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
uc->updates++ >= uc->user_resources.updates)
{
net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates",
@@ -2290,8 +2321,6 @@
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
table_list->schema_select_lex= sel;
table_list->schema_table_reformed= 1;
- statistic_increment(thd->status_var.com_stat[lex->orig_sql_command],
- &LOCK_status);
DBUG_RETURN(0);
}
@@ -2458,7 +2487,7 @@
*/
if (opt_readonly &&
!(thd->security_ctx->master_access & SUPER_ACL) &&
- uc_update_queries[lex->sql_command] &&
+ (sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) &&
!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
@@ -2470,9 +2499,8 @@
#ifdef HAVE_REPLICATION
} /* endif unlikely slave */
#endif
- if(lex->orig_sql_command == SQLCOM_END)
- statistic_increment(thd->status_var.com_stat[lex->sql_command],
- &LOCK_status);
+ statistic_increment(thd->status_var.com_stat[lex->sql_command],
+ &LOCK_status);
#ifdef HAVE_ROW_BASED_REPLICATION
if (lex->binlog_row_based_if_mixed)
@@ -2480,77 +2508,61 @@
#endif /*HAVE_ROW_BASED_REPLICATION*/
switch (lex->sql_command) {
- case SQLCOM_SELECT:
+ case SQLCOM_SHOW_EVENTS:
+ if ((res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
+ is_schema_db(thd->lex->select_lex.db))))
+ break;
+ /* fall through */
+ case SQLCOM_SHOW_STATUS_PROC:
+ case SQLCOM_SHOW_STATUS_FUNC:
+ res= execute_sqlcom_select(thd, all_tables);
+ break;
+ case SQLCOM_SHOW_STATUS:
{
- /* assign global limit variable if limit is not given */
- {
- SELECT_LEX *param= lex->unit.global_parameters;
- if (!param->explicit_limit)
- param->select_limit=
- new Item_int((ulonglong)thd->variables.select_limit);
- }
-
- select_result *result=lex->result;
+ system_status_var old_status_var= thd->status_var;
+ thd->initial_status_var= &old_status_var;
+ res= execute_sqlcom_select(thd, all_tables);
+ /* Don't log SHOW STATUS commands to slow query log */
+ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
+ SERVER_QUERY_NO_GOOD_INDEX_USED);
+ /*
+ restore status variables, as we don't want 'show status' to cause
+ changes
+ */
+ pthread_mutex_lock(&LOCK_status);
+ add_diff_to_status(&global_status_var, &thd->status_var,
+ &old_status_var);
+ thd->status_var= old_status_var;
+ pthread_mutex_unlock(&LOCK_status);
+ break;
+ }
+ case SQLCOM_SHOW_DATABASES:
+ case SQLCOM_SHOW_TABLES:
+ case SQLCOM_SHOW_TRIGGERS:
+ case SQLCOM_SHOW_TABLE_STATUS:
+ case SQLCOM_SHOW_OPEN_TABLES:
+ case SQLCOM_SHOW_PLUGINS:
+ case SQLCOM_SHOW_FIELDS:
+ case SQLCOM_SHOW_KEYS:
+ case SQLCOM_SHOW_VARIABLES:
+ case SQLCOM_SHOW_CHARSETS:
+ case SQLCOM_SHOW_COLLATIONS:
+ case SQLCOM_SELECT:
+ thd->status_var.last_query_cost= 0.0;
if (all_tables)
{
- if (lex->orig_sql_command != SQLCOM_SHOW_STATUS_PROC &&
- lex->orig_sql_command != SQLCOM_SHOW_STATUS_FUNC &&
- lex->orig_sql_command != SQLCOM_SHOW_EVENTS)
- res= check_table_access(thd,
- lex->exchange ? SELECT_ACL | FILE_ACL :
- SELECT_ACL,
- all_tables, 0);
- else if (lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
- res= check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
- is_schema_db(thd->lex->select_lex.db));
+ res= check_table_access(thd,
+ lex->exchange ? SELECT_ACL | FILE_ACL :
+ SELECT_ACL,
+ all_tables, 0);
}
else
res= check_access(thd,
- lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
- any_db, 0, 0, 0, 0);
- if (res)
- goto error;
-
- if (!(res= open_and_lock_tables(thd, all_tables)))
- {
- if (lex->describe)
- {
- /*
- We always use select_send for EXPLAIN, even if it's an EXPLAIN
- for SELECT ... INTO OUTFILE: a user application should be able
- to prepend EXPLAIN to any query and receive output for it,
- even if the query itself redirects the output.
- */
- if (!(result= new select_send()))
- goto error;
- else
- thd->send_explain_fields(result);
- res= mysql_explain_union(thd, &thd->lex->unit, result);
- if (lex->describe & DESCRIBE_EXTENDED)
- {
- char buff[1024];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- str.length(0);
- thd->lex->unit.print(&str);
- str.append('\0');
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_YES, str.ptr());
- }
- result->send_eof();
- delete result;
- }
- else
- {
- if (!result && !(result= new select_send()))
- goto error;
- query_cache_store_query(thd, all_tables);
- res= handle_select(thd, lex, result, 0);
- if (result != lex->result)
- delete result;
- }
- }
+ lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
+ any_db, 0, 0, 0, 0);
+ if (!res)
+ res= execute_sqlcom_select(thd, all_tables);
break;
- }
case SQLCOM_PREPARE:
{
mysql_sql_stmt_prepare(thd);
@@ -4826,6 +4838,7 @@
}
break;
}
+#ifdef NOT_USED
case SQLCOM_SHOW_STATUS_PROC:
{
res= sp_show_status_procedure(thd, (lex->wild ?
@@ -4838,6 +4851,7 @@
lex->wild->ptr() : NullS));
break;
}
+#endif
#ifndef DBUG_OFF
case SQLCOM_SHOW_PROC_CODE:
case SQLCOM_SHOW_FUNC_CODE:
@@ -5162,13 +5176,10 @@
/*
The return value for ROW_COUNT() is "implementation dependent" if the
statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
- wants.
-
- We do not change the value for a CALL or EXECUTE statement, so the value
- generated by the last called (or executed) statement is preserved.
- */
- if (lex->sql_command != SQLCOM_CALL && lex->sql_command != SQLCOM_EXECUTE
&&
- uc_update_queries[lex->sql_command]<2)
+ wants. We also keep the last value in case of SQLCOM_CALL or
+ SQLCOM_EXECUTE.
+ */
+ if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
thd->row_count_func= -1;
DBUG_RETURN(res || thd->net.report_error);
@@ -5178,6 +5189,59 @@
}
+static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
+{
+ LEX *lex= thd->lex;
+ select_result *result=lex->result;
+ bool res;
+ /* assign global limit variable if limit is not given */
+ {
+ SELECT_LEX *param= lex->unit.global_parameters;
+ if (!param->explicit_limit)
+ param->select_limit=
+ new Item_int((ulonglong) thd->variables.select_limit);
+ }
+ if (!(res= open_and_lock_tables(thd, all_tables)))
+ {
+ if (lex->describe)
+ {
+ /*
+ We always use select_send for EXPLAIN, even if it's an EXPLAIN
+ for SELECT ... INTO OUTFILE: a user application should be able
+ to prepend EXPLAIN to any query and receive output for it,
+ even if the query itself redirects the output.
+ */
+ if (!(result= new select_send()))
+ return 1;
+ thd->send_explain_fields(result);
+ res= mysql_explain_union(thd, &thd->lex->unit, result);
+ if (lex->describe & DESCRIBE_EXTENDED)
+ {
+ char buff[1024];
+ String str(buff,(uint32) sizeof(buff), system_charset_info);
+ str.length(0);
+ thd->lex->unit.print(&str);
+ str.append('\0');
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_YES, str.ptr());
+ }
+ result->send_eof();
+ delete result;
+ }
+ else
+ {
+ if (!result && !(result= new select_send()))
+ return 1;
+ query_cache_store_query(thd, all_tables);
+ res= handle_select(thd, lex, result, 0);
+ if (result != lex->result)
+ delete result;
+ }
+ }
+ return res;
+}
+
+
/*
Check grants for commands which work only with one table and all other
tables belonging to subselects or implicitly opened tables.
@@ -6283,7 +6347,7 @@
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
if (!schema_table ||
(schema_table->hidden &&
- lex->orig_sql_command == SQLCOM_END)) // not a 'show' command
+ (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0))
{
my_error(ER_UNKNOWN_TABLE, MYF(0),
ptr->table_name, information_schema_name.str);
--- 1.413/sql/sql_select.cc 2006-06-18 13:20:28 +03:00
+++ 1.414/sql/sql_select.cc 2006-06-20 13:20:28 +03:00
@@ -551,9 +551,6 @@
DBUG_RETURN(0);
optimized= 1;
- if (thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
- thd->status_var.last_query_cost= 0.0;
-
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
unit->select_limit_cnt);
/* select_limit is used to decide if we are likely to scan the whole table */
@@ -3875,10 +3872,8 @@
/*
Store the cost of this query into a user variable
- Don't update last_query_cost for 'show status' command
*/
- if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
- join->thd->status_var.last_query_cost= join->best_read;
+ join->thd->status_var.last_query_cost= join->best_read;
DBUG_VOID_RETURN;
}
--- 1.351/sql/sql_show.cc 2006-06-16 13:17:00 +03:00
+++ 1.352/sql/sql_show.cc 2006-06-20 13:20:28 +03:00
@@ -2143,7 +2143,7 @@
void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values)
{
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
- switch (lex->orig_sql_command) {
+ switch (lex->sql_command) {
case SQLCOM_SHOW_DATABASES:
index_field_values->db_value= wild;
break;
@@ -2332,10 +2332,9 @@
/*
This part of code is for SHOW TABLES, SHOW TABLE STATUS commands.
idx_field_vals->db_value can't be 0 (see get_index_field_values()
- function). lex->orig_sql_command can be not equal to SQLCOM_END
- only in case of executing of SHOW commands.
+ function).
*/
- if (lex->orig_sql_command != SQLCOM_END)
+ if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
{
if (!my_strcasecmp(system_charset_info, information_schema_name.str,
idx_field_vals->db_value))
@@ -2414,12 +2413,6 @@
LINT_INIT(end);
LINT_INIT(len);
- /*
- Let us set fake sql_command so views won't try to merge
- themselves into main statement.
- */
- lex->sql_command= SQLCOM_SHOW_FIELDS;
-
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
/*
@@ -2442,8 +2435,16 @@
I_S tables will be done.
*/
thd->temporary_tables= open_tables_state_backup.temporary_tables;
+ /*
+ Let us set fake sql_command so views won't try to merge
+ themselves into main statement. If we don't do this,
+ SELECT * from information_schema.xxxx will cause problems.
+ SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
+ */
+ lex->sql_command= SQLCOM_SHOW_FIELDS;
res= open_normal_and_derived_tables(thd, show_table_list,
MYSQL_LOCK_IGNORE_FLUSH);
+ lex->sql_command= save_sql_command;
/*
get_all_tables() returns 1 on failure and 0 on success thus
return only these and not the result code of ::process_table()
@@ -2474,13 +2475,13 @@
partial_cond= make_cond_for_info_schema(cond, tables);
it.rewind(); /* To get access to new elements in basis list */
+
+ /*
+ Below we generate error for non existing database.
+ (to save old behaviour for SHOW TABLES FROM db)
+ */
while ((orig_base_name= base_name= it++) ||
- /*
- generate error for non existing database.
- (to save old behaviour for SHOW TABLES FROM db)
- */
- ((lex->orig_sql_command == SQLCOM_SHOW_TABLES ||
- lex->orig_sql_command == SQLCOM_SHOW_TABLE_STATUS) &&
+ ((sql_command_flags[save_sql_command] & CF_SHOW_TABLE_COMMAND) &&
(base_name= select_lex->db) && !bases.elements))
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -2521,7 +2522,8 @@
{
if (schema_table_idx == SCH_TABLE_NAMES)
{
- if (lex->verbose || lex->orig_sql_command == SQLCOM_END)
+ if (lex->verbose ||
+ (sql_command_flags[save_sql_command] & CF_STATUS_COMMAND) == 0)
{
if (with_i_schema)
{
@@ -2565,8 +2567,10 @@
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
lex->all_selects_list= &sel;
lex->derived_tables= 0;
+ lex->sql_command= SQLCOM_SHOW_FIELDS;
res= open_normal_and_derived_tables(thd, show_table_list,
MYSQL_LOCK_IGNORE_FLUSH);
+ lex->sql_command= save_sql_command;
/*
We should use show_table_list->alias instead of
show_table_list->table_name because table_name
@@ -2876,7 +2880,7 @@
if (res)
{
- if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS)
+ if (lex->sql_command != SQLCOM_SHOW_FIELDS)
{
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
@@ -2927,7 +2931,7 @@
col_access= get_column_grant(thd, &tables->grant,
base_name, file_name,
field->field_name) & COL_ACLS;
- if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS &&
+ if (lex->sql_command != SQLCOM_SHOW_FIELDS &&
!tables->schema_table && !col_access)
continue;
end= tmp;
@@ -2972,7 +2976,7 @@
table->field[5]->set_notnull();
}
else if (field->unireg_check == Field::NEXT_NUMBER ||
- lex->orig_sql_command != SQLCOM_SHOW_FIELDS ||
+ lex->sql_command != SQLCOM_SHOW_FIELDS ||
field->maybe_null())
table->field[5]->set_null(); // Null as default
else
@@ -3242,16 +3246,18 @@
get_field(thd->mem_root, proc_table->field[11], &definer);
if (!full_access)
full_access= !strcmp(sp_user, definer.ptr());
- if (!full_access && check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(),
- proc_table->field[2]->val_int() ==
+ if (!full_access && check_some_routine_access(thd, sp_db.ptr(),
+ sp_name.ptr(),
+ proc_table->field[2]->
+ val_int() ==
TYPE_ENUM_PROCEDURE))
return 0;
- if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
+ if (lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE ||
- lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC &&
+ lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION ||
- lex->orig_sql_command == SQLCOM_END)
+ (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
{
restore_record(table, s->default_values);
if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
@@ -3362,7 +3368,7 @@
DBUG_ENTER("get_schema_stat_record");
if (res)
{
- if (thd->lex->orig_sql_command != SQLCOM_SHOW_KEYS)
+ if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
{
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
@@ -4153,7 +4159,7 @@
optimized. It's guaranteed in case of SHOW EVENTS that the user
has access.
*/
- if (thd->lex->orig_sql_command != SQLCOM_SHOW_EVENTS &&
+ if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS &&
check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
is_schema_db(et.dbname.str)))
DBUG_RETURN(0);
@@ -4383,7 +4389,7 @@
If it's SHOW EVENTS then thd->lex->select_lex.db is guaranteed not to
be NULL. Let's do an assert anyway.
*/
- if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+ if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
{
DBUG_ASSERT(thd->lex->select_lex.db);
if (check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0,
@@ -4411,7 +4417,7 @@
will save use from doing a table scan and comparing
every single row's `db` with the schema which we show.
*/
- if (thd->lex->orig_sql_command == SQLCOM_SHOW_EVENTS)
+ if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
ret= events_table_index_read_for_db(thd, schema_table, event_table);
else
ret= events_table_scan_all(thd, schema_table, event_table);
@@ -4477,7 +4483,7 @@
(SHOW_VAR *)all_status_vars.buffer,
OPT_GLOBAL,
(lex->option_type == OPT_GLOBAL ?
- &tmp: &thd->status_var), "",tables->table);
+ &tmp: thd->initial_status_var), "",tables->table);
pthread_mutex_unlock(&LOCK_status);
DBUG_RETURN(res);
}
@@ -4670,8 +4676,8 @@
schema_table pointer to 'schema_tables' element
RETURN
- -1 errror
- 0 success
+ 1 error
+ 0 success
*/
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
@@ -4994,7 +5000,7 @@
break;
TABLE_LIST *table_list= tab->table->pos_in_table_list;
- if (table_list->schema_table && thd->fill_derived_tables())
+ if (table_list->schema_table && thd->fill_information_schema_tables())
{
bool is_subselect= (&lex->unit != lex->current_select->master_unit()
&&
lex->current_select->master_unit()->item);
--- 1.482/sql/sql_yacc.yy 2006-06-18 13:20:29 +03:00
+++ 1.483/sql/sql_yacc.yy 2006-06-20 13:20:28 +03:00
@@ -2058,16 +2058,19 @@
{
Lex->sphead->reset_lex(YYTHD);
- /* We use statement here just be able to get a better
- error message. Using 'select' works too, but will then
- result in a generic "syntax error" if a non-select
- statement is given. */
+ /*
+ We use statement here just be able to get a better
+ error message. Using 'select' works too, but will then
+ result in a generic "syntax error" if a non-select
+ statement is given.
+ */
}
statement
{
LEX *lex= Lex;
- if (lex->sql_command != SQLCOM_SELECT)
+ if (lex->sql_command != SQLCOM_SELECT &&
+ !(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND))
{
my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY),
MYF(0));
@@ -8062,16 +8065,14 @@
DATABASES wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_DATABASES;
+ lex->sql_command= SQLCOM_SHOW_DATABASES;
if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA))
YYABORT;
}
| opt_full TABLES opt_db wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_TABLES;
+ lex->sql_command= SQLCOM_SHOW_TABLES;
lex->select_lex.db= $3;
if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
YYABORT;
@@ -8079,8 +8080,7 @@
| opt_full TRIGGERS_SYM opt_db wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_TRIGGERS;
+ lex->sql_command= SQLCOM_SHOW_TRIGGERS;
lex->select_lex.db= $3;
if (prepare_schema_table(YYTHD, lex, 0, SCH_TRIGGERS))
YYABORT;
@@ -8088,8 +8088,7 @@
| EVENTS_SYM opt_db wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_EVENTS;
+ lex->sql_command= SQLCOM_SHOW_EVENTS;
lex->select_lex.db= $2;
if (prepare_schema_table(YYTHD, lex, 0, SCH_EVENTS))
YYABORT;
@@ -8106,8 +8105,7 @@
| TABLE_SYM STATUS_SYM opt_db wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATUS;
+ lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
lex->select_lex.db= $3;
if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES))
YYABORT;
@@ -8115,8 +8113,7 @@
| OPEN_SYM TABLES opt_db wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_OPEN_TABLES;
+ lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
lex->select_lex.db= $3;
if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
YYABORT;
@@ -8125,16 +8122,14 @@
{
LEX *lex= Lex;
WARN_DEPRECATED(yythd, "5.2", "SHOW PLUGIN", "'SHOW PLUGINS'");
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_PLUGINS;
+ lex->sql_command= SQLCOM_SHOW_PLUGINS;
if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
YYABORT;
}
| PLUGINS_SYM
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_PLUGINS;
+ lex->sql_command= SQLCOM_SHOW_PLUGINS;
if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
YYABORT;
}
@@ -8147,8 +8142,7 @@
| opt_full COLUMNS from_or_in table_ident opt_db wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_FIELDS;
+ lex->sql_command= SQLCOM_SHOW_FIELDS;
if ($5)
$4->change_db($5);
if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS))
@@ -8180,8 +8174,7 @@
| keys_or_index from_or_in table_ident opt_db where_clause
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_KEYS;
+ lex->sql_command= SQLCOM_SHOW_KEYS;
if ($4)
$3->change_db($4);
if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS))
@@ -8202,7 +8195,6 @@
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
- lex->orig_sql_command= SQLCOM_SHOW_AUTHORS;
if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
YYABORT;
}
@@ -8232,8 +8224,7 @@
| opt_var_type STATUS_SYM wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_STATUS;
+ lex->sql_command= SQLCOM_SHOW_STATUS;
lex->option_type= $1;
if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
YYABORT;
@@ -8267,8 +8258,7 @@
| opt_var_type VARIABLES wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_VARIABLES;
+ lex->sql_command= SQLCOM_SHOW_VARIABLES;
lex->option_type= $1;
if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES))
YYABORT;
@@ -8276,16 +8266,14 @@
| charset wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_CHARSETS;
+ lex->sql_command= SQLCOM_SHOW_CHARSETS;
if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS))
YYABORT;
}
| COLLATION_SYM wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_COLLATIONS;
+ lex->sql_command= SQLCOM_SHOW_COLLATIONS;
if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS))
YYABORT;
}
@@ -8391,8 +8379,7 @@
| PROCEDURE STATUS_SYM wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_STATUS_PROC;
+ lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
if (!sp_add_to_query_tables(YYTHD, lex, "mysql", "proc", TL_READ))
YYABORT;
if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
@@ -8401,8 +8388,7 @@
| FUNCTION_SYM STATUS_SYM wild_and_where
{
LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_STATUS_FUNC;
+ lex->sql_command= SQLCOM_SHOW_STATUS_FUNC;
if (!sp_add_to_query_tables(YYTHD, lex, "mysql", "proc", TL_READ))
YYABORT;
if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
@@ -8497,8 +8483,7 @@
lex->lock_option= TL_READ;
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
- lex->sql_command= SQLCOM_SELECT;
- lex->orig_sql_command= SQLCOM_SHOW_FIELDS;
+ lex->sql_command= SQLCOM_SHOW_FIELDS;
lex->select_lex.db= 0;
lex->verbose= 0;
if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS))
--- 1.61/sql/structs.h 2006-06-18 13:20:29 +03:00
+++ 1.62/sql/structs.h 2006-06-20 13:20:28 +03:00
@@ -180,7 +180,7 @@
uint questions;
/*
Maximum number of updating statements per hour (which statements are
- updating is defined by uc_update_queries array).
+ updating is defined by sql_command_flags array).
*/
uint updates;
/* Maximum number of connections established per hour. */
--- 1.84/mysql-test/r/union.result 2006-06-18 13:20:26 +03:00
+++ 1.85/mysql-test/r/union.result 2006-06-20 13:20:28 +03:00
@@ -836,27 +836,27 @@
26
show status like 'Slow_queries';
Variable_name Value
-Slow_queries 1
+Slow_queries 0
select count(*) from t1 where b=13;
count(*)
10
show status like 'Slow_queries';
Variable_name Value
-Slow_queries 3
+Slow_queries 1
select count(*) from t1 where b=13 union select count(*) from t1 where a=7;
count(*)
10
26
show status like 'Slow_queries';
Variable_name Value
-Slow_queries 5
+Slow_queries 2
select count(*) from t1 where a=7 union select count(*) from t1 where b=13;
count(*)
26
10
show status like 'Slow_queries';
Variable_name Value
-Slow_queries 7
+Slow_queries 3
flush status;
select a from t1 where b not in (1,2,3) union select a from t1 where b not in (4,5,6);
a
--- 1.3/mysql-test/t/events_microsec.test 2006-05-22 21:45:57 +03:00
+++ 1.4/mysql-test/t/events_microsec.test 2006-06-20 13:20:28 +03:00
@@ -1,4 +1,7 @@
+--disable_warnings
create database if not exists events_test;
+--enable_warnings
+
use events_test;
--error ER_NOT_SUPPORTED_YET
--- 1.124/mysql-test/r/information_schema.result 2006-06-14 11:50:14 +03:00
+++ 1.125/mysql-test/r/information_schema.result 2006-06-20 13:20:27 +03:00
@@ -199,6 +199,8 @@
where table_schema = 'mysqltest' and table_name = 'v1';
table_name column_name privileges
v1 c select
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
drop view v1, mysqltest.v1;
drop tables mysqltest.t4, mysqltest.t1, t2, t3, t5;
drop database mysqltest;
--- 1.82/mysql-test/t/information_schema.test 2006-06-14 08:54:50 +03:00
+++ 1.83/mysql-test/t/information_schema.test 2006-06-20 13:20:28 +03:00
@@ -80,6 +80,8 @@
connection user4;
select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 'v1';
+--error 1345
+explain select * from v1;
connection default;
drop view v1, mysqltest.v1;
--- 1.23/mysql-test/r/temp_table.result 2006-02-22 11:09:52 +02:00
+++ 1.24/mysql-test/r/temp_table.result 2006-06-20 13:20:28 +03:00
@@ -98,7 +98,7 @@
show status like "created_tmp%tables";
Variable_name Value
Created_tmp_disk_tables 0
-Created_tmp_tables 2
+Created_tmp_tables 1
drop table t1;
create temporary table v1 as select 'This is temp. table' A;
create view v1 as select 'This is view' A;
--- 1.16/mysql-test/r/grant_cache.result 2005-05-18 23:51:22 +03:00
+++ 1.17/mysql-test/r/grant_cache.result 2006-06-20 13:20:27 +03:00
@@ -60,7 +60,7 @@
Qcache_hits 0
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 5
+Qcache_not_cached 0
select "user1";
user1
user1
@@ -72,7 +72,7 @@
Qcache_hits 0
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 9
+Qcache_not_cached 1
select * from t1;
a b c
1 1 1
@@ -85,7 +85,7 @@
Qcache_hits 1
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 12
+Qcache_not_cached 1
select a from t1 ;
a
1
@@ -98,7 +98,7 @@
Qcache_hits 2
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 15
+Qcache_not_cached 1
select c from t1;
c
1
@@ -111,7 +111,7 @@
Qcache_hits 3
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 18
+Qcache_not_cached 1
show grants for current_user();
Grants for @localhost
GRANT USAGE ON *.* TO ''@'localhost'
@@ -144,7 +144,7 @@
Qcache_hits 7
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 22
+Qcache_not_cached 2
select "user3";
user3
user3
@@ -168,7 +168,7 @@
Qcache_hits 7
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 30
+Qcache_not_cached 7
select "user4";
user4
user4
@@ -198,7 +198,7 @@
Qcache_hits 8
show status like "Qcache_not_cached";
Variable_name Value
-Qcache_not_cached 34
+Qcache_not_cached 8
set names binary;
delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3");
--- 1.74/mysql-test/r/query_cache.result 2006-02-26 15:11:52 +02:00
+++ 1.75/mysql-test/r/query_cache.result 2006-06-20 13:20:27 +03:00
@@ -1050,6 +1050,7 @@
drop table t1;
create table t1 (a int);
insert into t1 values (1),(2);
+drop procedure if exists p1;
CREATE PROCEDURE `p1`()
begin
Declare c1 cursor for select a from t1;
--- 1.60/mysql-test/t/query_cache.test 2006-05-02 16:13:52 +03:00
+++ 1.61/mysql-test/t/query_cache.test 2006-06-20 13:20:28 +03:00
@@ -765,6 +765,9 @@
create table t1 (a int);
insert into t1 values (1),(2);
+--disable_warnings
+drop procedure if exists p1;
+--enable_warnings
delimiter //;
CREATE PROCEDURE `p1`()
begin
--- 1.11/mysql-test/r/status.result 2006-05-23 13:10:00 +03:00
+++ 1.12/mysql-test/r/status.result 2006-06-20 13:20:27 +03:00
@@ -23,6 +23,32 @@
show status like 'last_query_cost';
Variable_name Value
Last_query_cost 0.000000
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t1 where a=6;
+a
+6
+6
+6
+6
+6
+show status like 'last_query_cost';
+Variable_name Value
+Last_query_cost 12.084449
+show status like 'last_query_cost';
+Variable_name Value
+Last_query_cost 12.084449
+select 1;
+1
+1
+show status like 'last_query_cost';
+Variable_name Value
+Last_query_cost 0.000000
+drop table t1;
FLUSH STATUS;
SHOW STATUS LIKE 'max_used_connections';
Variable_name Value
@@ -43,3 +69,27 @@
Variable_name Value
Max_used_connections 5
SET GLOBAL thread_cache_size=@save_thread_cache_size;
+show status like 'com_show_status';
+Variable_name Value
+Com_show_status 3
+show status like 'hand%write%';
+Variable_name Value
+Handler_write 0
+show status like '%tmp%';
+Variable_name Value
+Created_tmp_disk_tables 0
+Created_tmp_files 0
+Created_tmp_tables 0
+show status like 'hand%write%';
+Variable_name Value
+Handler_write 0
+show status like '%tmp%';
+Variable_name Value
+Created_tmp_disk_tables 0
+Created_tmp_files 0
+Created_tmp_tables 0
+show status like 'com_show_status';
+Variable_name Value
+Com_show_status 8
+rnd_diff tmp_table_diff
+20 8
--- 1.15/mysql-test/t/status.test 2006-04-12 16:37:51 +03:00
+++ 1.16/mysql-test/t/status.test 2006-06-20 13:20:28 +03:00
@@ -48,6 +48,19 @@
select 1;
show status like 'last_query_cost';
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t1 where a=6;
+show status like 'last_query_cost';
+# Ensure value dosn't change by second status call
+show status like 'last_query_cost';
+select 1;
+show status like 'last_query_cost';
+drop table t1;
#
# Test for Bug #15933 max_used_connections is wrong after FLUSH STATUS
@@ -144,3 +157,24 @@
disconnect con1;
# End of 5.0 tests
+
+#
+# Ensure that SHOW STATUS only changes global status variables
+#
+
+connect (con1,localhost,root,,);
+let $rnd_next = `show global status like 'handler_read_rnd_next'`;
+let $tmp_table = `show global status like 'Created_tmp_tables'`;
+show status like 'com_show_status';
+show status like 'hand%write%';
+show status like '%tmp%';
+show status like 'hand%write%';
+show status like '%tmp%';
+show status like 'com_show_status';
+let $rnd_next2 = `show global status like 'handler_read_rnd_next'`;
+let $tmp_table2 = `show global status like 'Created_tmp_tables'`;
+--disable_query_log
+eval select substring_index('$rnd_next2',0x9,-1)-substring_index('$rnd_next',0x9,-1) as
rnd_diff, substring_index('$tmp_table2',0x9,-1)-substring_index('$tmp_table',0x9,-1) as
tmp_table_diff;
+--enable_query_log
+
+# End of 5.1 tests
--- 1.172/sql/sql_prepare.cc 2006-06-04 19:23:56 +03:00
+++ 1.173/sql/sql_prepare.cc 2006-06-20 13:20:28 +03:00
@@ -1727,22 +1727,17 @@
res= mysql_test_insert_select(stmt, tables);
break;
- case SQLCOM_SHOW_DATABASES:
+ /*
+ Note that we don't need to have cases in this list if they are
+ marked with CF_STATUS_COMMAND in sql_command_flags
+ */
case SQLCOM_SHOW_PROCESSLIST:
case SQLCOM_SHOW_STORAGE_ENGINES:
case SQLCOM_SHOW_PRIVILEGES:
case SQLCOM_SHOW_COLUMN_TYPES:
- case SQLCOM_SHOW_STATUS:
- case SQLCOM_SHOW_VARIABLES:
case SQLCOM_SHOW_ENGINE_LOGS:
case SQLCOM_SHOW_ENGINE_STATUS:
case SQLCOM_SHOW_ENGINE_MUTEX:
- case SQLCOM_SHOW_TABLES:
- case SQLCOM_SHOW_OPEN_TABLES:
- case SQLCOM_SHOW_CHARSETS:
- case SQLCOM_SHOW_COLLATIONS:
- case SQLCOM_SHOW_FIELDS:
- case SQLCOM_SHOW_KEYS:
case SQLCOM_SHOW_CREATE_DB:
case SQLCOM_SHOW_GRANTS:
case SQLCOM_DROP_TABLE:
@@ -1762,9 +1757,17 @@
break;
default:
- /* All other statements are not supported yet. */
- my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
- goto error;
+ /*
+ Trivial check of all status commands. This is easier than having
+ things in the above case list, as it's less chance for mistakes.
+ */
+ if (!(sql_command_flags[sql_command] & CF_STATUS_COMMAND))
+ {
+ /* All other statements are not supported yet. */
+ my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
+ goto error;
+ }
+ break;
}
if (res == 0)
DBUG_RETURN(text_protocol? FALSE : (send_prep_stmt(stmt, 0) ||
| Thread |
|---|
| • bk commit into 5.1 tree (monty:1.2221) BUG#19764 | monty | 20 Jun |