mirror of
https://github.com/MariaDB/server.git
synced 2026-04-30 12:15:32 +02:00
Merge bodhi.local:/opt/local/work/tmp_merge
into bodhi.local:/opt/local/work/mysql-5.1-runtime-merge-5.0 include/my_sys.h: Auto merged mysql-test/r/auto_increment.result: Auto merged mysql-test/r/func_math.result: Auto merged mysql-test/r/func_system.result: Auto merged mysql-test/r/func_time.result: Auto merged mysql-test/r/information_schema.result: Auto merged mysql-test/r/query_cache.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/r/trigger.result: Auto merged mysql-test/r/type_blob.result: Auto merged mysql-test/r/variables.result: Auto merged mysql-test/r/view.result: Auto merged mysql-test/t/trigger.test: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/log.cc: Auto merged sql/slave.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_trigger.cc: Auto merged sql/sql_yacc.yy: Auto merged storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp: Auto merged storage/ndb/src/mgmsrv/ConfigInfo.cpp: Auto merged sql/slave.h: SCCS merged mysql-test/r/show_check.result: Manual merge. mysql-test/t/show_check.test: Manual merge. sql/log_event.cc: Manual merge. sql/share/errmsg.txt: Manual merge. sql/sql_class.h: Manual merge. sql/sql_db.cc: Manual merge.
This commit is contained in:
commit
d013f9e53a
26 changed files with 352 additions and 179 deletions
|
|
@ -1693,14 +1693,33 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
|||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
static const char *rewrite_db(const char *db)
|
||||
{
|
||||
if (replicate_rewrite_db.is_empty() || db == NULL)
|
||||
return db;
|
||||
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
|
||||
i_string_pair* tmp;
|
||||
|
||||
while ((tmp=it++))
|
||||
{
|
||||
if (strcmp(tmp->key, db) == 0)
|
||||
return tmp->val;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
return exec_event(rli, query, q_len);
|
||||
}
|
||||
|
||||
|
||||
int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query_arg, uint32 q_len_arg)
|
||||
int Query_log_event::exec_event(struct st_relay_log_info* rli,
|
||||
const char *query_arg, uint32 q_len_arg)
|
||||
{
|
||||
LEX_STRING new_db;
|
||||
int expected_error,actual_error= 0;
|
||||
/*
|
||||
Colleagues: please never free(thd->catalog) in MySQL. This would lead to
|
||||
|
|
@ -1709,8 +1728,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
|
|||
Thank you.
|
||||
*/
|
||||
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
|
||||
thd->db_length= db_len;
|
||||
thd->db= (char *) rpl_filter->get_rewrite_db(db, &thd->db_length);
|
||||
new_db.length= db_len;
|
||||
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
|
||||
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
|
||||
thd->variables.auto_increment_increment= auto_increment_increment;
|
||||
thd->variables.auto_increment_offset= auto_increment_offset;
|
||||
|
||||
|
|
@ -1929,7 +1949,7 @@ end:
|
|||
TABLE uses the db.table syntax.
|
||||
*/
|
||||
thd->catalog= 0;
|
||||
thd->reset_db(NULL, 0); // prevent db from being freed
|
||||
thd->set_db(NULL, 0); /* will free the current database */
|
||||
thd->query= 0; // just to be sure
|
||||
thd->query_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
|
|
@ -2906,8 +2926,10 @@ void Load_log_event::set_fields(const char* affected_db,
|
|||
int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
||||
bool use_rli_only_for_errors)
|
||||
{
|
||||
thd->db_length= db_len;
|
||||
thd->db= (char *) rpl_filter->get_rewrite_db(db, &thd->db_length);
|
||||
LEX_STRING new_db;
|
||||
new_db.length= db_len;
|
||||
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
|
||||
thd->set_db(new_db.str, new_db.length);
|
||||
DBUG_ASSERT(thd->query == 0);
|
||||
thd->query_length= 0; // Should not be needed
|
||||
thd->query_error= 0;
|
||||
|
|
@ -3110,7 +3132,7 @@ error:
|
|||
const char *remember_db= thd->db;
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->catalog= 0;
|
||||
thd->reset_db(NULL, 0);
|
||||
thd->set_db(NULL, 0); /* will free the current database */
|
||||
thd->query= 0;
|
||||
thd->query_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
|
|
|
|||
|
|
@ -5594,6 +5594,8 @@ ER_NON_GROUPING_FIELD_USED 42000
|
|||
eng "non-grouping field '%-.64s' is used in %-.64s clause"
|
||||
ER_TABLE_CANT_HANDLE_SPKEYS
|
||||
eng "The used table type doesn't support SPATIAL indexes"
|
||||
ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
|
||||
eng "Triggers can not be created on system tables"
|
||||
ER_ILLEGAL_HA_CREATE_OPTION
|
||||
eng "Table storage engine '%-.64s' does not support the create option '%.64s'"
|
||||
ER_PARTITION_REQUIRES_VALUES_ERROR
|
||||
|
|
|
|||
|
|
@ -1576,21 +1576,29 @@ public:
|
|||
|
||||
/*
|
||||
Initialize the current database from a NULL-terminated string with length
|
||||
If we run out of memory, we free the current database and return TRUE.
|
||||
This way the user will notice the error as there will be no current
|
||||
database selected (in addition to the error message set by malloc).
|
||||
*/
|
||||
void set_db(const char *new_db, uint new_db_len)
|
||||
bool set_db(const char *new_db, uint new_db_len)
|
||||
{
|
||||
if (new_db)
|
||||
/* Do not reallocate memory if current chunk is big enough. */
|
||||
if (db && new_db && db_length >= new_db_len)
|
||||
memcpy(db, new_db, new_db_len+1);
|
||||
else
|
||||
{
|
||||
/* Do not reallocate memory if current chunk is big enough. */
|
||||
if (db && db_length >= new_db_len)
|
||||
memcpy(db, new_db, new_db_len+1);
|
||||
else
|
||||
{
|
||||
safeFree(db);
|
||||
db= my_strndup(new_db, new_db_len, MYF(MY_WME));
|
||||
x_free(db);
|
||||
db= new_db ? my_strndup(new_db, new_db_len, MYF(MY_WME)) : NULL;
|
||||
}
|
||||
db_length= db ? new_db_len: 0;
|
||||
}
|
||||
db_length= db ? new_db_len : 0;
|
||||
return new_db && !db;
|
||||
}
|
||||
void reset_db(char *new_db, uint new_db_len)
|
||||
{
|
||||
|
|
|
|||
155
sql/sql_db.cc
155
sql/sql_db.cc
|
|
@ -906,32 +906,13 @@ exit:
|
|||
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
|
||||
error= Events::drop_schema_events(thd, db);
|
||||
/*
|
||||
If this database was the client's selected database, we silently change the
|
||||
client's selected database to nothing (to have an empty SELECT DATABASE()
|
||||
in the future). For this we free() thd->db and set it to 0. But we don't do
|
||||
free() for the slave thread. Indeed, doing a x_free() on it leads to nasty
|
||||
problems (i.e. long painful debugging) because in this thread, thd->db is
|
||||
the same as data_buf and db of the Query_log_event which is dropping the
|
||||
database. So if you free() thd->db, you're freeing data_buf. You set
|
||||
thd->db to 0 but not data_buf (thd->db and data_buf are two distinct
|
||||
pointers which point to the same place). Then in ~Query_log_event(), we
|
||||
have 'if (data_buf) free(data_buf)' data_buf is !=0 so this makes a
|
||||
DOUBLE free().
|
||||
Side effects of this double free() are, randomly (depends on the machine),
|
||||
when the slave is replicating a DROP DATABASE:
|
||||
- garbage characters in the error message:
|
||||
"Error 'Can't drop database 'test2'; database doesn't exist' on query
|
||||
'h4zI<EFBFBD>©'"
|
||||
- segfault
|
||||
- hang in "free(vio)" (yes!) in the I/O or SQL slave threads (so slave
|
||||
server hangs at shutdown etc).
|
||||
If this database was the client's selected database, we silently
|
||||
change the client's selected database to nothing (to have an empty
|
||||
SELECT DATABASE() in the future). For this we free() thd->db and set
|
||||
it to 0.
|
||||
*/
|
||||
if (thd->db && !strcmp(thd->db, db))
|
||||
{
|
||||
if (!(thd->slave_thread)) /* a slave thread will free it itself */
|
||||
x_free(thd->db);
|
||||
thd->reset_db(NULL, 0);
|
||||
}
|
||||
thd->set_db(NULL, 0);
|
||||
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
|
||||
start_waiting_global_read_lock(thd);
|
||||
exit2:
|
||||
|
|
@ -1227,38 +1208,52 @@ err:
|
|||
|
||||
|
||||
/*
|
||||
Change default database.
|
||||
Change the current database.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_change_db()
|
||||
thd Thread handler
|
||||
name Databasename
|
||||
no_access_check True don't do access check. In this case name may be ""
|
||||
thd thread handle
|
||||
name database name
|
||||
no_access_check if TRUE, don't do access check. In this
|
||||
case name may be ""
|
||||
|
||||
DESCRIPTION
|
||||
Becasue the database name may have been given directly from the
|
||||
communication packet (in case of 'connect' or 'COM_INIT_DB')
|
||||
we have to do end space removal in this function.
|
||||
Check that the database name corresponds to a valid and
|
||||
existent database, check access rights (unless called with
|
||||
no_access_check), and set the current database. This function
|
||||
is called to change the current database upon user request
|
||||
(COM_CHANGE_DB command) or temporarily, to execute a stored
|
||||
routine.
|
||||
|
||||
NOTES
|
||||
Do as little as possible in this function, as it is not called for the
|
||||
replication slave SQL thread (for that thread, setting of thd->db is done
|
||||
in ::exec_event() methods of log_event.cc).
|
||||
This function is not the only way to switch the database that
|
||||
is currently employed. When the replication slave thread
|
||||
switches the database before executing a query, it calls
|
||||
thd->set_db directly. However, if the query, in turn, uses
|
||||
a stored routine, the stored routine will use this function,
|
||||
even if it's run on the slave.
|
||||
|
||||
This function does not send anything, including error messages to the
|
||||
client, if that should be sent to the client, call net_send_error after
|
||||
this function.
|
||||
This function allocates the name of the database on the system
|
||||
heap: this is necessary to be able to uniformly change the
|
||||
database from any module of the server. Up to 5.0 different
|
||||
modules were using different memory to store the name of the
|
||||
database, and this led to memory corruption: a stack pointer
|
||||
set by Stored Procedures was used by replication after the
|
||||
stack address was long gone.
|
||||
|
||||
This function does not send anything, including error
|
||||
messages, to the client. If that should be sent to the client,
|
||||
call net_send_error after this function.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
0 OK
|
||||
1 error
|
||||
*/
|
||||
|
||||
bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
|
||||
{
|
||||
int length, db_length;
|
||||
char *dbname= thd->slave_thread ? (char *) name :
|
||||
my_strdup((char *) name, MYF(MY_WME));
|
||||
int path_length, db_length;
|
||||
char *db_name;
|
||||
char path[FN_REFLEN];
|
||||
HA_CREATE_INFO create;
|
||||
bool system_db= 0;
|
||||
|
|
@ -1270,32 +1265,35 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
|
|||
DBUG_ENTER("mysql_change_db");
|
||||
DBUG_PRINT("enter",("name: '%s'",name));
|
||||
|
||||
LINT_INIT(db_length);
|
||||
|
||||
/* dbname can only be NULL if malloc failed */
|
||||
if (!dbname || !(db_length= strlen(dbname)))
|
||||
if (name == NULL || name[0] == '\0' && no_access_check == FALSE)
|
||||
{
|
||||
if (no_access_check && dbname)
|
||||
{
|
||||
/* Called from SP when orignal database was not set */
|
||||
system_db= 1;
|
||||
goto end;
|
||||
}
|
||||
if (!(thd->slave_thread))
|
||||
x_free(dbname); /* purecov: inspected */
|
||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
|
||||
MYF(0)); /* purecov: inspected */
|
||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||
DBUG_RETURN(1); /* purecov: inspected */
|
||||
}
|
||||
if (check_db_name(dbname))
|
||||
else if (name[0] == '\0')
|
||||
{
|
||||
my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
|
||||
if (!(thd->slave_thread))
|
||||
my_free(dbname, MYF(0));
|
||||
/* Called from SP to restore the original database, which was NULL */
|
||||
DBUG_ASSERT(no_access_check);
|
||||
system_db= 1;
|
||||
db_name= NULL;
|
||||
db_length= 0;
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
Now we need to make a copy because check_db_name requires a
|
||||
non-constant argument. TODO: fix check_db_name.
|
||||
*/
|
||||
if ((db_name= my_strdup(name, MYF(MY_WME))) == NULL)
|
||||
DBUG_RETURN(1); /* the error is set */
|
||||
db_length= strlen(db_name);
|
||||
if (check_db_name(db_name))
|
||||
{
|
||||
my_error(ER_WRONG_DB_NAME, MYF(0), db_name);
|
||||
my_free(db_name, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_PRINT("info",("Use database: %s", dbname));
|
||||
if (!my_strcasecmp(system_charset_info, dbname, information_schema_name.str))
|
||||
DBUG_PRINT("info",("Use database: %s", db_name));
|
||||
if (!my_strcasecmp(system_charset_info, db_name, information_schema_name.str))
|
||||
{
|
||||
system_db= 1;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
|
@ -1310,44 +1308,35 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
|
|||
if (test_all_bits(sctx->master_access, DB_ACLS))
|
||||
db_access=DB_ACLS;
|
||||
else
|
||||
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
|
||||
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name, 0) |
|
||||
sctx->master_access);
|
||||
if (!(db_access & DB_ACLS) && (!grant_option ||
|
||||
check_grant_db(thd,dbname)))
|
||||
check_grant_db(thd,db_name)))
|
||||
{
|
||||
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
|
||||
sctx->priv_user,
|
||||
sctx->priv_host,
|
||||
dbname);
|
||||
db_name);
|
||||
general_log_print(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
|
||||
sctx->priv_user, sctx->priv_host, dbname);
|
||||
if (!(thd->slave_thread))
|
||||
my_free(dbname,MYF(0));
|
||||
sctx->priv_user, sctx->priv_host, db_name);
|
||||
my_free(db_name,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
length= build_table_filename(path, sizeof(path), dbname, "", "");
|
||||
if (length && path[length-1] == FN_LIBCHAR)
|
||||
path[length-1]=0; // remove ending '\'
|
||||
path_length= build_table_filename(path, sizeof(path), db_name, "", "");
|
||||
if (path_length && path[path_length-1] == FN_LIBCHAR)
|
||||
path[path_length-1]= '\0'; // remove ending '\'
|
||||
if (my_access(path,F_OK))
|
||||
{
|
||||
my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
|
||||
if (!(thd->slave_thread))
|
||||
my_free(dbname,MYF(0));
|
||||
my_error(ER_BAD_DB_ERROR, MYF(0), db_name);
|
||||
my_free(db_name, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
end:
|
||||
if (!(thd->slave_thread))
|
||||
x_free(thd->db);
|
||||
if (dbname && dbname[0] == 0)
|
||||
{
|
||||
if (!(thd->slave_thread))
|
||||
my_free(dbname, MYF(0));
|
||||
thd->reset_db(NULL, 0);
|
||||
}
|
||||
else
|
||||
thd->reset_db(dbname, db_length); // THD::~THD will free this
|
||||
x_free(thd->db);
|
||||
DBUG_ASSERT(db_name == NULL || db_name[0] != '\0');
|
||||
thd->reset_db(db_name, db_length); // THD::~THD will free this
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (!no_access_check)
|
||||
sctx->db_access= db_access;
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ void lex_start(THD *thd, const uchar *buf, uint length)
|
|||
lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
|
||||
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
|
||||
lex->select_lex.options= 0;
|
||||
lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
|
||||
lex->select_lex.init_order();
|
||||
lex->select_lex.group_list.empty();
|
||||
lex->describe= 0;
|
||||
|
|
@ -1070,6 +1071,7 @@ int MYSQLlex(void *arg, void *yythd)
|
|||
void st_select_lex_node::init_query()
|
||||
{
|
||||
options= 0;
|
||||
sql_cache= SQL_CACHE_UNSPECIFIED;
|
||||
linkage= UNSPECIFIED_TYPE;
|
||||
no_error= no_table_names_allowed= 0;
|
||||
uncacheable= 0;
|
||||
|
|
@ -1146,6 +1148,7 @@ void st_select_lex::init_select()
|
|||
table_join_options= 0;
|
||||
in_sum_expr= with_wild= 0;
|
||||
options= 0;
|
||||
sql_cache= SQL_CACHE_UNSPECIFIED;
|
||||
braces= 0;
|
||||
when_list.empty();
|
||||
expr_list.empty();
|
||||
|
|
|
|||
|
|
@ -338,6 +338,14 @@ protected:
|
|||
public:
|
||||
|
||||
ulonglong options;
|
||||
|
||||
/*
|
||||
In sql_cache we store SQL_CACHE flag as specified by user to be
|
||||
able to restore SELECT statement from internal structures.
|
||||
*/
|
||||
enum e_sql_cache { SQL_CACHE_UNSPECIFIED, SQL_NO_CACHE, SQL_CACHE };
|
||||
e_sql_cache sql_cache;
|
||||
|
||||
/*
|
||||
result of this query can't be cached, bit field, can be :
|
||||
UNCACHEABLE_DEPENDENT
|
||||
|
|
|
|||
|
|
@ -14584,10 +14584,19 @@ void st_select_lex::print(THD *thd, String *str)
|
|||
str->append(STRING_WITH_LEN("sql_buffer_result "));
|
||||
if (options & OPTION_FOUND_ROWS)
|
||||
str->append(STRING_WITH_LEN("sql_calc_found_rows "));
|
||||
if (!thd->lex->safe_to_cache_query)
|
||||
str->append(STRING_WITH_LEN("sql_no_cache "));
|
||||
if (options & OPTION_TO_QUERY_CACHE)
|
||||
str->append(STRING_WITH_LEN("sql_cache "));
|
||||
switch (sql_cache)
|
||||
{
|
||||
case SQL_NO_CACHE:
|
||||
str->append(STRING_WITH_LEN("sql_no_cache "));
|
||||
break;
|
||||
case SQL_CACHE:
|
||||
str->append(STRING_WITH_LEN("sql_cache "));
|
||||
break;
|
||||
case SQL_CACHE_UNSPECIFIED:
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
|
||||
//Item List
|
||||
bool first= 1;
|
||||
|
|
|
|||
|
|
@ -183,6 +183,15 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
|||
!(tables= add_table_for_trigger(thd, thd->lex->spname)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/*
|
||||
We don't allow creating triggers on tables in the 'mysql' schema
|
||||
*/
|
||||
if (create && !my_strcasecmp(system_charset_info, "mysql", tables->db))
|
||||
{
|
||||
my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* We should have only one table in table list. */
|
||||
DBUG_ASSERT(tables->next_global == 0);
|
||||
|
||||
|
|
@ -372,7 +381,9 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
|
|||
/* We don't allow creation of several triggers of the same type yet */
|
||||
if (bodies[lex->trg_chistics.event][lex->trg_chistics.action_time])
|
||||
{
|
||||
my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0));
|
||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
|
||||
"multiple triggers with the same action time"
|
||||
" and event for one table");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5707,10 +5707,21 @@ select_option:
|
|||
YYABORT;
|
||||
Select->options|= OPTION_FOUND_ROWS;
|
||||
}
|
||||
| SQL_NO_CACHE_SYM { Lex->safe_to_cache_query=0; }
|
||||
| SQL_NO_CACHE_SYM
|
||||
{
|
||||
Lex->safe_to_cache_query=0;
|
||||
Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
|
||||
Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
|
||||
}
|
||||
| SQL_CACHE_SYM
|
||||
{
|
||||
Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
|
||||
/* Honor this flag only if SQL_NO_CACHE wasn't specified. */
|
||||
if (Lex->select_lex.sql_cache != SELECT_LEX::SQL_NO_CACHE)
|
||||
{
|
||||
Lex->safe_to_cache_query=1;
|
||||
Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
|
||||
Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE;
|
||||
}
|
||||
}
|
||||
| ALL { Select->options|= SELECT_ALL; }
|
||||
;
|
||||
|
|
@ -8073,6 +8084,7 @@ truncate:
|
|||
LEX* lex= Lex;
|
||||
lex->sql_command= SQLCOM_TRUNCATE;
|
||||
lex->select_lex.options= 0;
|
||||
lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
|
||||
lex->select_lex.init_order();
|
||||
}
|
||||
;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue