mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge....
This commit is contained in:
356
sql/sql_parse.cc
356
sql/sql_parse.cc
@ -100,7 +100,17 @@ static void init_signals(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool end_active_trans(THD *thd)
|
||||
static void unlock_locked_tables(THD *thd)
|
||||
{
|
||||
if (thd->locked_tables)
|
||||
{
|
||||
thd->lock=thd->locked_tables;
|
||||
thd->locked_tables=0; // Will be automaticly closed
|
||||
close_thread_tables(thd); // Free tables
|
||||
}
|
||||
}
|
||||
|
||||
static bool end_active_trans(THD *thd)
|
||||
{
|
||||
int error=0;
|
||||
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
|
||||
@ -270,14 +280,14 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
started with corresponding variable that is greater then 0.
|
||||
*/
|
||||
|
||||
static byte* get_key_conn(user_conn *buff, uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
extern "C" byte *get_key_conn(user_conn *buff, uint *length,
|
||||
my_bool not_used __attribute__((unused)))
|
||||
{
|
||||
*length=buff->len;
|
||||
return (byte*) buff->user;
|
||||
}
|
||||
|
||||
static void free_user(struct user_conn *uc)
|
||||
extern "C" void free_user(struct user_conn *uc)
|
||||
{
|
||||
my_free((char*) uc,MYF(0));
|
||||
}
|
||||
@ -286,7 +296,7 @@ void init_max_user_conn(void)
|
||||
{
|
||||
(void) hash_init(&hash_user_connections,system_charset_info,max_connections,
|
||||
0,0,
|
||||
(hash_get_key) get_key_conn, (void (*)(void*)) free_user,
|
||||
(hash_get_key) get_key_conn, (hash_free_key) free_user,
|
||||
0);
|
||||
}
|
||||
|
||||
@ -569,7 +579,13 @@ check_connections(THD *thd)
|
||||
{
|
||||
/* Do the SSL layering. */
|
||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||
sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout);
|
||||
if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout))
|
||||
{
|
||||
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
|
||||
pkt_len));
|
||||
inc_host_errors(&thd->remote.sin_addr);
|
||||
return(ER_HANDSHAKE_ERROR);
|
||||
}
|
||||
DBUG_PRINT("info", ("Reading user information over SSL layer"));
|
||||
if ((pkt_len=my_net_read(net)) == packet_error ||
|
||||
pkt_len < NORMAL_HANDSHAKE_SIZE)
|
||||
@ -740,7 +756,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
||||
goto end_thread;
|
||||
}
|
||||
|
||||
if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
|
||||
if ((ulong) thd->variables.max_join_size == (ulonglong) HA_POS_ERROR)
|
||||
thd->options |= OPTION_BIG_SELECTS;
|
||||
if (thd->client_capabilities & CLIENT_COMPRESS)
|
||||
net->compress=1; // Use compression
|
||||
@ -770,7 +786,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
||||
(net->last_errno ? ER(net->last_errno) :
|
||||
ER(ER_UNKNOWN_ERROR)));
|
||||
send_error(thd,net->last_errno,NullS);
|
||||
thread_safe_increment(aborted_threads,&LOCK_status);
|
||||
statistic_increment(aborted_threads,&LOCK_status);
|
||||
}
|
||||
|
||||
end_thread:
|
||||
@ -791,7 +807,7 @@ end_thread:
|
||||
Used when creating the initial grant tables
|
||||
*/
|
||||
|
||||
pthread_handler_decl(handle_bootstrap,arg)
|
||||
extern "C" pthread_handler_decl(handle_bootstrap,arg)
|
||||
{
|
||||
THD *thd=(THD*) arg;
|
||||
FILE *file=bootstrap_file;
|
||||
@ -816,7 +832,7 @@ pthread_handler_decl(handle_bootstrap,arg)
|
||||
|
||||
#endif
|
||||
|
||||
if ((ulong) thd->variables.max_join_size == (ulong) HA_POS_ERROR)
|
||||
if ((ulong) thd->variables.max_join_size == (ulonglong) HA_POS_ERROR)
|
||||
thd->options |= OPTION_BIG_SELECTS;
|
||||
|
||||
thd->proc_info=0;
|
||||
@ -983,7 +999,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
thd->lex.select_lex.options=0; // We store status here
|
||||
switch (command) {
|
||||
case COM_INIT_DB:
|
||||
thread_safe_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status);
|
||||
if (!mysql_change_db(thd,packet))
|
||||
mysql_log.write(thd,command,"%s",thd->db);
|
||||
break;
|
||||
@ -995,7 +1011,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
}
|
||||
case COM_TABLE_DUMP:
|
||||
{
|
||||
thread_safe_increment(com_other, &LOCK_status);
|
||||
statistic_increment(com_other, &LOCK_status);
|
||||
slow_command = TRUE;
|
||||
uint db_len = *(uchar*)packet;
|
||||
uint tbl_len = *(uchar*)(packet + db_len + 1);
|
||||
@ -1012,7 +1028,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
}
|
||||
case COM_CHANGE_USER:
|
||||
{
|
||||
thread_safe_increment(com_other,&LOCK_status);
|
||||
thd->change_user();
|
||||
clear_error_message(thd); // If errors from rollback
|
||||
|
||||
statistic_increment(com_other,&LOCK_status);
|
||||
char *user= (char*) packet;
|
||||
char *passwd= strend(user)+1;
|
||||
char *db= strend(passwd)+1;
|
||||
@ -1088,7 +1107,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
{
|
||||
char *fields;
|
||||
TABLE_LIST table_list;
|
||||
thread_safe_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status);
|
||||
bzero((char*) &table_list,sizeof(table_list));
|
||||
if (!(table_list.db=thd->db))
|
||||
{
|
||||
@ -1123,7 +1142,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
|
||||
case COM_CREATE_DB: // QQ: To be removed
|
||||
{
|
||||
thread_safe_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status);
|
||||
char *db=thd->strdup(packet);
|
||||
// null test to handle EOM
|
||||
if (!db || !strip_sp(db) || check_db_name(db))
|
||||
@ -1141,7 +1160,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
}
|
||||
case COM_DROP_DB: // QQ: To be removed
|
||||
{
|
||||
thread_safe_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status);
|
||||
char *db=thd->strdup(packet);
|
||||
// null test to handle EOM
|
||||
if (!db || !strip_sp(db) || check_db_name(db))
|
||||
@ -1162,7 +1181,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
}
|
||||
case COM_BINLOG_DUMP:
|
||||
{
|
||||
thread_safe_increment(com_other,&LOCK_status);
|
||||
statistic_increment(com_other,&LOCK_status);
|
||||
slow_command = TRUE;
|
||||
if (check_global_access(thd, REPL_SLAVE_ACL))
|
||||
break;
|
||||
@ -1186,7 +1205,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
}
|
||||
case COM_REFRESH:
|
||||
{
|
||||
thread_safe_increment(com_stat[SQLCOM_FLUSH],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_FLUSH],&LOCK_status);
|
||||
ulong options= (ulong) (uchar) packet[0];
|
||||
if (check_global_access(thd,RELOAD_ACL))
|
||||
break;
|
||||
@ -1198,7 +1217,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
break;
|
||||
}
|
||||
case COM_SHUTDOWN:
|
||||
thread_safe_increment(com_other,&LOCK_status);
|
||||
statistic_increment(com_other,&LOCK_status);
|
||||
if (check_global_access(thd,SHUTDOWN_ACL))
|
||||
break; /* purecov: inspected */
|
||||
DBUG_PRINT("quit",("Got shutdown command"));
|
||||
@ -1221,7 +1240,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
case COM_STATISTICS:
|
||||
{
|
||||
mysql_log.write(thd,command,NullS);
|
||||
thread_safe_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_status);
|
||||
char buff[200];
|
||||
ulong uptime = (ulong) (thd->start_time - start_time);
|
||||
sprintf((char*) buff,
|
||||
@ -1240,11 +1259,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
break;
|
||||
}
|
||||
case COM_PING:
|
||||
thread_safe_increment(com_other,&LOCK_status);
|
||||
statistic_increment(com_other,&LOCK_status);
|
||||
send_ok(thd); // Tell client we are alive
|
||||
break;
|
||||
case COM_PROCESS_INFO:
|
||||
thread_safe_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status);
|
||||
if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL))
|
||||
break;
|
||||
mysql_log.write(thd,command,NullS);
|
||||
@ -1253,13 +1272,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
break;
|
||||
case COM_PROCESS_KILL:
|
||||
{
|
||||
thread_safe_increment(com_stat[SQLCOM_KILL],&LOCK_status);
|
||||
statistic_increment(com_stat[SQLCOM_KILL],&LOCK_status);
|
||||
ulong id=(ulong) uint4korr(packet);
|
||||
kill_one_thread(thd,id);
|
||||
break;
|
||||
}
|
||||
case COM_DEBUG:
|
||||
thread_safe_increment(com_other,&LOCK_status);
|
||||
statistic_increment(com_other,&LOCK_status);
|
||||
if (check_global_access(thd, SUPER_ACL))
|
||||
break; /* purecov: inspected */
|
||||
mysql_print_status(thd);
|
||||
@ -1380,7 +1399,7 @@ mysql_execute_command(THD *thd)
|
||||
that is not a SHOW command or a select that only access local
|
||||
variables, but for now this is probably good enough.
|
||||
*/
|
||||
if (tables)
|
||||
if (tables || lex->select_lex.next_select_in_list())
|
||||
mysql_reset_errors(thd);
|
||||
/*
|
||||
Save old warning count to be able to send to client how many warnings we
|
||||
@ -1411,81 +1430,34 @@ mysql_execute_command(THD *thd)
|
||||
#endif
|
||||
}
|
||||
|
||||
select_result *explain_result= 0;
|
||||
/*
|
||||
TODO: make derived tables processing 'inside' SELECT processing.
|
||||
TODO: solve problem with depended derived tables in subselects
|
||||
*/
|
||||
if (lex->sql_command == SQLCOM_SELECT &&
|
||||
lex->describe && lex->derived_tables)
|
||||
if (lex->derived_tables)
|
||||
{
|
||||
if (!(explain_result= new select_send()))
|
||||
{
|
||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
//check rights
|
||||
for (cursor= tables;
|
||||
cursor;
|
||||
cursor= cursor->next)
|
||||
if (cursor->derived)
|
||||
{
|
||||
TABLE_LIST *tables=
|
||||
(TABLE_LIST *)((SELECT_LEX_UNIT *)
|
||||
cursor->derived)->first_select()->table_list.first;
|
||||
int res;
|
||||
if (tables)
|
||||
res= check_table_access(thd,SELECT_ACL, tables);
|
||||
else
|
||||
res= check_access(thd, SELECT_ACL, any_db);
|
||||
if (res)
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
thd->send_explain_fields(explain_result);
|
||||
// EXPLAIN derived tables
|
||||
for (cursor= tables;
|
||||
cursor;
|
||||
cursor= cursor->next)
|
||||
if (cursor->derived)
|
||||
{
|
||||
SELECT_LEX *select_lex= ((SELECT_LEX_UNIT *)
|
||||
cursor->derived)->first_select();
|
||||
if (!open_and_lock_tables(thd,
|
||||
(TABLE_LIST*) select_lex->table_list.first))
|
||||
{
|
||||
mysql_explain_select(thd, select_lex,
|
||||
"DERIVED", explain_result);
|
||||
// execute derived table SELECT to provide table for other SELECTs
|
||||
if (mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived,
|
||||
cursor, 1))
|
||||
for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select_in_list())
|
||||
if (sl->linkage != DERIVED_TABLE_TYPE)
|
||||
for (TABLE_LIST *cursor= sl->get_table_list();
|
||||
cursor;
|
||||
cursor= cursor->next)
|
||||
if (cursor->derived && (res=mysql_derived(thd, lex,
|
||||
(SELECT_LEX_UNIT *)
|
||||
cursor->derived,
|
||||
cursor)))
|
||||
{
|
||||
if (res < 0 || thd->net.report_error)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
else
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
}
|
||||
else if (lex->derived_tables)
|
||||
{
|
||||
for (TABLE_LIST *cursor= tables;
|
||||
cursor;
|
||||
cursor= cursor->next)
|
||||
if (cursor->derived && (res=mysql_derived(thd, lex,
|
||||
(SELECT_LEX_UNIT *)cursor->derived,
|
||||
cursor, 0)))
|
||||
{
|
||||
if (res < 0)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((lex->select_lex.next_select_in_list() &&
|
||||
lex->unit.create_total_list(thd, lex, &tables)) ||
|
||||
(table_rules_on && tables && thd->slave_thread &&
|
||||
!tables_ok(thd,tables)))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
thread_safe_increment(com_stat[lex->sql_command],&LOCK_status);
|
||||
statistic_increment(com_stat[lex->sql_command],&LOCK_status);
|
||||
switch (lex->sql_command) {
|
||||
case SQLCOM_SELECT:
|
||||
{
|
||||
@ -1506,10 +1478,11 @@ mysql_execute_command(THD *thd)
|
||||
break; // Error message is given
|
||||
}
|
||||
|
||||
unit->offset_limit_cnt= unit->global_parameters->offset_limit;
|
||||
unit->select_limit_cnt= unit->global_parameters->select_limit+
|
||||
unit->global_parameters->offset_limit;
|
||||
if (unit->select_limit_cnt < unit->global_parameters->select_limit)
|
||||
unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit;
|
||||
unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+
|
||||
unit->global_parameters->offset_limit);
|
||||
if (unit->select_limit_cnt <
|
||||
(ha_rows) unit->global_parameters->select_limit)
|
||||
unit->select_limit_cnt= HA_POS_ERROR; // no limit
|
||||
if (unit->select_limit_cnt == HA_POS_ERROR)
|
||||
select_lex->options&= ~OPTION_FOUND_ROWS;
|
||||
@ -1518,19 +1491,18 @@ mysql_execute_command(THD *thd)
|
||||
{
|
||||
if (lex->describe)
|
||||
{
|
||||
if (!explain_result)
|
||||
if (!(explain_result= new select_send()))
|
||||
{
|
||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
else
|
||||
thd->send_explain_fields(explain_result);
|
||||
if (!(result= new select_send()))
|
||||
{
|
||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
else
|
||||
thd->send_explain_fields(result);
|
||||
fix_tables_pointers(select_lex);
|
||||
res= mysql_explain_union(thd, &thd->lex.unit, explain_result);
|
||||
res= mysql_explain_union(thd, &thd->lex.unit, result);
|
||||
MYSQL_LOCK *save_lock= thd->lock;
|
||||
thd->lock= (MYSQL_LOCK *)0;
|
||||
explain_result->send_eof();
|
||||
result->send_eof();
|
||||
thd->lock= save_lock;
|
||||
}
|
||||
else
|
||||
@ -1543,6 +1515,8 @@ mysql_execute_command(THD *thd)
|
||||
Normal select:
|
||||
Change lock if we are using SELECT HIGH PRIORITY,
|
||||
FOR UPDATE or IN SHARE MODE
|
||||
|
||||
TODO: Delete the following loop when locks is set by sql_yacc
|
||||
*/
|
||||
TABLE_LIST *table;
|
||||
for (table = tables ; table ; table=table->next)
|
||||
@ -1772,6 +1746,7 @@ mysql_execute_command(THD *thd)
|
||||
TABLE_LIST *table;
|
||||
if (check_table_access(thd, SELECT_ACL, tables->next))
|
||||
goto error; // Error message is given
|
||||
/* TODO: Delete the following loop when locks is set by sql_yacc */
|
||||
for (table = tables->next ; table ; table=table->next)
|
||||
table->lock_type= lex->lock_option;
|
||||
}
|
||||
@ -1841,7 +1816,7 @@ mysql_execute_command(THD *thd)
|
||||
#else
|
||||
{
|
||||
ulong priv=0;
|
||||
if (lex->name && strlen(lex->name) > NAME_LEN)
|
||||
if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
|
||||
{
|
||||
net_printf(thd,ER_WRONG_TABLE_NAME,lex->name);
|
||||
res=0;
|
||||
@ -2015,18 +1990,13 @@ mysql_execute_command(THD *thd)
|
||||
}
|
||||
if (select_lex->table_list.elements == 1)
|
||||
{
|
||||
res = mysql_update(thd,tables,
|
||||
select_lex->item_list,
|
||||
lex->value_list,
|
||||
select_lex->where,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
select_lex->select_limit,
|
||||
lex->duplicates,
|
||||
lex->lock_option);
|
||||
|
||||
#ifdef DELETE_ITEMS
|
||||
delete select_lex->where;
|
||||
#endif
|
||||
res= mysql_update(thd,tables,
|
||||
select_lex->item_list,
|
||||
lex->value_list,
|
||||
select_lex->where,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
select_lex->select_limit,
|
||||
lex->duplicates);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2036,11 +2006,8 @@ mysql_execute_command(THD *thd)
|
||||
const char *msg=0;
|
||||
|
||||
lex->sql_command=SQLCOM_MULTI_UPDATE;
|
||||
for (auxi=(TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next)
|
||||
{
|
||||
for (auxi= (TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next)
|
||||
table_count++;
|
||||
auxi->lock_type=TL_WRITE;
|
||||
}
|
||||
|
||||
if (select_lex->order_list.elements)
|
||||
msg="ORDER BY";
|
||||
@ -2062,8 +2029,7 @@ mysql_execute_command(THD *thd)
|
||||
!setup_fields(thd,tables,lex->value_list,0,0,0) &&
|
||||
!thd->fatal_error &&
|
||||
(result=new multi_update(thd,tables,select_lex->item_list,
|
||||
lex->duplicates, lex->lock_option,
|
||||
table_count)))
|
||||
lex->duplicates, table_count)))
|
||||
{
|
||||
List <Item> total_list;
|
||||
List_iterator <Item> field_list(select_lex->item_list);
|
||||
@ -2094,8 +2060,7 @@ mysql_execute_command(THD *thd)
|
||||
if (grant_option && check_grant(thd,INSERT_ACL,tables))
|
||||
goto error;
|
||||
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
|
||||
lex->duplicates,
|
||||
lex->lock_option);
|
||||
lex->duplicates);
|
||||
break;
|
||||
case SQLCOM_REPLACE:
|
||||
if (check_access(thd,INSERT_ACL | DELETE_ACL,
|
||||
@ -2106,8 +2071,7 @@ mysql_execute_command(THD *thd)
|
||||
|
||||
goto error;
|
||||
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
|
||||
DUP_REPLACE,
|
||||
lex->lock_option);
|
||||
DUP_REPLACE);
|
||||
break;
|
||||
case SQLCOM_REPLACE_SELECT:
|
||||
case SQLCOM_INSERT_SELECT:
|
||||
@ -2142,8 +2106,8 @@ mysql_execute_command(THD *thd)
|
||||
net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
tables->lock_type=TL_WRITE; // update first table
|
||||
{
|
||||
/* TODO: Delete the following loop when locks is set by sql_yacc */
|
||||
TABLE_LIST *table;
|
||||
for (table = tables->next ; table ; table=table->next)
|
||||
table->lock_type= lex->lock_option;
|
||||
@ -2186,8 +2150,7 @@ mysql_execute_command(THD *thd)
|
||||
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
|
||||
res = mysql_delete(thd,tables, select_lex->where,
|
||||
(ORDER*) select_lex->order_list.first,
|
||||
select_lex->select_limit, lex->lock_option,
|
||||
select_lex->options);
|
||||
select_lex->select_limit, select_lex->options);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_DELETE_MULTI:
|
||||
@ -2223,7 +2186,7 @@ mysql_execute_command(THD *thd)
|
||||
net_printf(thd,ER_NONUNIQ_TABLE,auxi->real_name);
|
||||
goto error;
|
||||
}
|
||||
auxi->lock_type=walk->lock_type=TL_WRITE;
|
||||
walk->lock_type= auxi->lock_type;
|
||||
auxi->table_list= walk; // Remember corresponding table
|
||||
}
|
||||
if (add_item_to_list(new Item_null()))
|
||||
@ -2238,7 +2201,6 @@ mysql_execute_command(THD *thd)
|
||||
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
|
||||
auxi->table= auxi->table_list->table;
|
||||
if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables,
|
||||
lex->lock_option,
|
||||
table_count)))
|
||||
{
|
||||
res= mysql_select(thd,tables,select_lex->item_list,
|
||||
@ -2444,11 +2406,7 @@ mysql_execute_command(THD *thd)
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SQLCOM_UNLOCK_TABLES:
|
||||
if (thd->locked_tables)
|
||||
{
|
||||
thd->lock=thd->locked_tables;
|
||||
thd->locked_tables=0; // Will be automaticly closed
|
||||
}
|
||||
unlock_locked_tables(thd);
|
||||
if (thd->options & OPTION_TABLE_LOCK)
|
||||
{
|
||||
end_active_trans(thd);
|
||||
@ -2459,12 +2417,7 @@ mysql_execute_command(THD *thd)
|
||||
send_ok(thd);
|
||||
break;
|
||||
case SQLCOM_LOCK_TABLES:
|
||||
if (thd->locked_tables)
|
||||
{
|
||||
thd->lock=thd->locked_tables;
|
||||
thd->locked_tables=0; // Will be automaticly closed
|
||||
close_thread_tables(thd);
|
||||
}
|
||||
unlock_locked_tables(thd);
|
||||
if (check_db_used(thd,tables) || end_active_trans(thd))
|
||||
goto error;
|
||||
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables))
|
||||
@ -2614,7 +2567,7 @@ mysql_execute_command(THD *thd)
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length);
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
}
|
||||
@ -2634,7 +2587,7 @@ mysql_execute_command(THD *thd)
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length);
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
if (mqh_used && lex->sql_command == SQLCOM_GRANT)
|
||||
@ -2851,6 +2804,8 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
||||
TABLE_LIST *org_tables=tables;
|
||||
for (; tables ; tables=tables->next)
|
||||
{
|
||||
if (tables->derived || (tables->table && (int)tables->table->tmp_table))
|
||||
continue;
|
||||
if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) &&
|
||||
thd->db)
|
||||
tables->grant.privilege= want_access;
|
||||
@ -2867,7 +2822,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
||||
found=1;
|
||||
}
|
||||
}
|
||||
else if (tables->db && check_access(thd,want_access,tables->db,&tables->grant.privilege,
|
||||
else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
|
||||
0, no_errors))
|
||||
return TRUE;
|
||||
}
|
||||
@ -2984,26 +2939,27 @@ void
|
||||
mysql_init_query(THD *thd)
|
||||
{
|
||||
DBUG_ENTER("mysql_init_query");
|
||||
thd->lex.unit.init_query();
|
||||
thd->lex.unit.init_select();
|
||||
thd->lex.select_lex.init_query();
|
||||
thd->lex.unit.slave= &thd->lex.select_lex;
|
||||
thd->lex.unit.global_parameters= &thd->lex.select_lex; //Global limit & order
|
||||
thd->lex.select_lex.master= &thd->lex.unit;
|
||||
thd->lex.select_lex.prev= &thd->lex.unit.slave;
|
||||
thd->select_number= thd->lex.select_lex.select_number= 1;
|
||||
thd->lex.value_list.empty();
|
||||
LEX *lex=&thd->lex;
|
||||
lex->unit.init_query();
|
||||
lex->unit.init_select();
|
||||
lex->select_lex.init_query();
|
||||
lex->value_list.empty();
|
||||
lex->param_list.empty();
|
||||
lex->unit.global_parameters= lex->unit.slave= lex->current_select=
|
||||
&lex->select_lex;
|
||||
lex->select_lex.master= &lex->unit;
|
||||
lex->select_lex.prev= &lex->unit.slave;
|
||||
lex->olap=lex->describe=0;
|
||||
lex->derived_tables= false;
|
||||
thd->check_loops_counter= thd->select_number=
|
||||
lex->select_lex.select_number= 1;
|
||||
thd->free_list= 0;
|
||||
thd->lex.current_select= &thd->lex.select_lex;
|
||||
thd->lex.olap=thd->lex.describe=0;
|
||||
thd->lex.select_lex.olap= UNSPECIFIED_OLAP_TYPE;
|
||||
thd->fatal_error= 0; // Safety
|
||||
thd->total_warn_count=0; // Warnings for this query
|
||||
thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0;
|
||||
thd->sent_row_count= thd->examined_row_count= 0;
|
||||
thd->rand_used=0;
|
||||
thd->fatal_error= thd->rand_used= 0;
|
||||
thd->safe_to_cache_query= 1;
|
||||
thd->lex.param_list.empty();
|
||||
thd->possible_loops= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3015,7 +2971,6 @@ mysql_init_select(LEX *lex)
|
||||
select_lex->init_select();
|
||||
select_lex->master_unit()->select_limit= select_lex->select_limit=
|
||||
lex->thd->variables.select_limit;
|
||||
select_lex->olap= UNSPECIFIED_OLAP_TYPE;
|
||||
lex->exchange= 0;
|
||||
lex->result= 0;
|
||||
lex->proc_list.first= 0;
|
||||
@ -3099,14 +3054,13 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
||||
|
||||
mysql_init_query(thd);
|
||||
thd->query_length = length;
|
||||
thd->lex.derived_tables= false;
|
||||
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
|
||||
{
|
||||
LEX *lex=lex_start(thd, (uchar*) inBuf, length);
|
||||
if (!yyparse() && ! thd->fatal_error)
|
||||
{
|
||||
if (mqh_used && thd->user_connect &&
|
||||
check_mqh(thd, thd->lex.sql_command))
|
||||
check_mqh(thd, lex->sql_command))
|
||||
{
|
||||
thd->net.error = 0;
|
||||
}
|
||||
@ -3155,6 +3109,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
|
||||
THD *thd=current_thd;
|
||||
LEX *lex= &thd->lex;
|
||||
uint allowed_type_modifier=0;
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
DBUG_ENTER("add_field_to_list");
|
||||
|
||||
if (strlen(field_name) > NAME_LEN)
|
||||
@ -3246,8 +3201,6 @@ bool add_field_to_list(char *field_name, enum_field_types type,
|
||||
if (!length) new_field->length=20;
|
||||
allowed_type_modifier= AUTO_INCREMENT_FLAG;
|
||||
break;
|
||||
case FIELD_TYPE_STRING:
|
||||
case FIELD_TYPE_VAR_STRING:
|
||||
case FIELD_TYPE_NULL:
|
||||
case FIELD_TYPE_GEOMETRY:
|
||||
break;
|
||||
@ -3258,10 +3211,35 @@ bool add_field_to_list(char *field_name, enum_field_types type,
|
||||
if (new_field->decimals)
|
||||
new_field->length++;
|
||||
break;
|
||||
case FIELD_TYPE_STRING:
|
||||
case FIELD_TYPE_VAR_STRING:
|
||||
if (new_field->length < MAX_FIELD_WIDTH || default_value)
|
||||
break;
|
||||
/* Convert long CHAR() and VARCHAR columns to TEXT or BLOB */
|
||||
new_field->sql_type= FIELD_TYPE_BLOB;
|
||||
sprintf(warn_buff, ER(ER_AUTO_CONVERT), field_name, "CHAR",
|
||||
(cs == my_charset_bin) ? "BLOB" : "TEXT");
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_AUTO_CONVERT,
|
||||
warn_buff);
|
||||
/* fall through */
|
||||
case FIELD_TYPE_BLOB:
|
||||
case FIELD_TYPE_TINY_BLOB:
|
||||
case FIELD_TYPE_LONG_BLOB:
|
||||
case FIELD_TYPE_MEDIUM_BLOB:
|
||||
if (new_field->length)
|
||||
{
|
||||
/* The user has given a length to the blob column */
|
||||
if (new_field->length < 256)
|
||||
type= FIELD_TYPE_TINY_BLOB;
|
||||
if (new_field->length < 65536)
|
||||
type= FIELD_TYPE_BLOB;
|
||||
else if (new_field->length < 256L*256L*256L)
|
||||
type= FIELD_TYPE_MEDIUM_BLOB;
|
||||
else
|
||||
type= FIELD_TYPE_LONG_BLOB;
|
||||
new_field->length= 0;
|
||||
}
|
||||
new_field->sql_type= type;
|
||||
if (default_value) // Allow empty as default value
|
||||
{
|
||||
String str,*res;
|
||||
@ -3514,7 +3492,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table,
|
||||
DBUG_RETURN(0); // End of memory
|
||||
alias_str= alias ? alias->str : table->table.str;
|
||||
if (table->table.length > NAME_LEN ||
|
||||
(table->table.length && check_table_name(table->table.str,table->table.length)) ||
|
||||
(table->table.length &&
|
||||
check_table_name(table->table.str,table->table.length)) ||
|
||||
table->db.str && check_db_name(table->db.str))
|
||||
{
|
||||
net_printf(thd,ER_WRONG_TABLE_NAME,table->table.str);
|
||||
@ -3581,14 +3560,49 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set lock for all tables in current select level
|
||||
|
||||
SYNOPSIS:
|
||||
set_lock_for_tables()
|
||||
lock_type Lock to set for tables
|
||||
|
||||
NOTE:
|
||||
If lock is a write lock, then tables->updating is set 1
|
||||
This is to get tables_ok to know that the table is updated by the
|
||||
query
|
||||
*/
|
||||
|
||||
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
|
||||
{
|
||||
bool for_update= lock_type >= TL_READ_NO_INSERT;
|
||||
DBUG_ENTER("set_lock_for_tables");
|
||||
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
|
||||
for_update));
|
||||
|
||||
for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first ;
|
||||
tables ;
|
||||
tables=tables->next)
|
||||
{
|
||||
tables->lock_type= lock_type;
|
||||
tables->updating= for_update;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void add_join_on(TABLE_LIST *b,Item *expr)
|
||||
{
|
||||
if (!b->on_expr)
|
||||
b->on_expr=expr;
|
||||
else
|
||||
if (expr)
|
||||
{
|
||||
// This only happens if you have both a right and left join
|
||||
b->on_expr=new Item_cond_and(b->on_expr,expr);
|
||||
if (!b->on_expr)
|
||||
b->on_expr=expr;
|
||||
else
|
||||
{
|
||||
// This only happens if you have both a right and left join
|
||||
b->on_expr=new Item_cond_and(b->on_expr,expr);
|
||||
}
|
||||
b->on_expr->top_level_item();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3616,7 +3630,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
|
||||
if (options & REFRESH_GRANT)
|
||||
{
|
||||
acl_reload(thd);
|
||||
grant_reload();
|
||||
grant_reload(thd);
|
||||
if (mqh_used)
|
||||
reset_mqh(thd,(LEX_USER *) NULL,true);
|
||||
}
|
||||
|
Reference in New Issue
Block a user