~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/sql_parse.cc

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#define MYSQL_LEX 1
 
17
#include "mysql_priv.h"
 
18
#include "sql_repl.h"
 
19
#include "rpl_filter.h"
 
20
#include "repl_failsafe.h"
 
21
#include <m_ctype.h>
 
22
#include <myisam.h>
 
23
#include <my_dir.h>
 
24
 
 
25
#include "sp_head.h"
 
26
#include "sp.h"
 
27
#include "sp_cache.h"
 
28
#include "events.h"
 
29
#include "sql_trigger.h"
 
30
 
 
31
/**
 
32
  @defgroup Runtime_Environment Runtime Environment
 
33
  @{
 
34
*/
 
35
 
 
36
/* Used in error handling only */
 
37
#define SP_TYPE_STRING(LP) \
 
38
  ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
 
39
#define SP_COM_STRING(LP) \
 
40
  ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
 
41
   (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
 
42
   (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
 
43
   (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
 
44
   "FUNCTION" : "PROCEDURE")
 
45
 
 
46
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
 
47
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
 
48
 
 
49
const char *any_db="*any*";     // Special symbol for check_access
 
50
 
 
51
const LEX_STRING command_name[]={
 
52
  { C_STRING_WITH_LEN("Sleep") },
 
53
  { C_STRING_WITH_LEN("Quit") },
 
54
  { C_STRING_WITH_LEN("Init DB") },
 
55
  { C_STRING_WITH_LEN("Query") },
 
56
  { C_STRING_WITH_LEN("Field List") },
 
57
  { C_STRING_WITH_LEN("Create DB") },
 
58
  { C_STRING_WITH_LEN("Drop DB") },
 
59
  { C_STRING_WITH_LEN("Refresh") },
 
60
  { C_STRING_WITH_LEN("Shutdown") },
 
61
  { C_STRING_WITH_LEN("Statistics") },
 
62
  { C_STRING_WITH_LEN("Processlist") },
 
63
  { C_STRING_WITH_LEN("Connect") },
 
64
  { C_STRING_WITH_LEN("Kill") },
 
65
  { C_STRING_WITH_LEN("Debug") },
 
66
  { C_STRING_WITH_LEN("Ping") },
 
67
  { C_STRING_WITH_LEN("Time") },
 
68
  { C_STRING_WITH_LEN("Delayed insert") },
 
69
  { C_STRING_WITH_LEN("Change user") },
 
70
  { C_STRING_WITH_LEN("Binlog Dump") },
 
71
  { C_STRING_WITH_LEN("Table Dump") },
 
72
  { C_STRING_WITH_LEN("Connect Out") },
 
73
  { C_STRING_WITH_LEN("Register Slave") },
 
74
  { C_STRING_WITH_LEN("Prepare") },
 
75
  { C_STRING_WITH_LEN("Execute") },
 
76
  { C_STRING_WITH_LEN("Long Data") },
 
77
  { C_STRING_WITH_LEN("Close stmt") },
 
78
  { C_STRING_WITH_LEN("Reset stmt") },
 
79
  { C_STRING_WITH_LEN("Set option") },
 
80
  { C_STRING_WITH_LEN("Fetch") },
 
81
  { C_STRING_WITH_LEN("Daemon") },
 
82
  { C_STRING_WITH_LEN("Error") }  // Last command number
 
83
};
 
84
 
 
85
const char *xa_state_names[]={
 
86
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY"
 
87
};
 
88
 
 
89
/**
 
90
  Mark a XA transaction as rollback-only if the RM unilaterally
 
91
  rolled back the transaction branch.
 
92
 
 
93
  @note If a rollback was requested by the RM, this function sets
 
94
        the appropriate rollback error code and transits the state
 
95
        to XA_ROLLBACK_ONLY.
 
96
 
 
97
  @return TRUE if transaction was rolled back or if the transaction
 
98
          state is XA_ROLLBACK_ONLY. FALSE otherwise.
 
99
*/
 
100
static bool xa_trans_rolled_back(XID_STATE *xid_state)
 
101
{
 
102
  if (xid_state->rm_error)
 
103
  {
 
104
    switch (xid_state->rm_error) {
 
105
    case ER_LOCK_WAIT_TIMEOUT:
 
106
      my_error(ER_XA_RBTIMEOUT, MYF(0));
 
107
      break;
 
108
    case ER_LOCK_DEADLOCK:
 
109
      my_error(ER_XA_RBDEADLOCK, MYF(0));
 
110
      break;
 
111
    default:
 
112
      my_error(ER_XA_RBROLLBACK, MYF(0));
 
113
    }
 
114
    xid_state->xa_state= XA_ROLLBACK_ONLY;
 
115
  }
 
116
 
 
117
  return (xid_state->xa_state == XA_ROLLBACK_ONLY);
 
118
}
 
119
 
 
120
/**
 
121
  Rollback work done on behalf of at ransaction branch.
 
122
*/
 
123
static bool xa_trans_rollback(THD *thd)
 
124
{
 
125
  /*
 
126
    Resource Manager error is meaningless at this point, as we perform
 
127
    explicit rollback request by user. We must reset rm_error before
 
128
    calling ha_rollback(), so thd->transaction.xid structure gets reset
 
129
    by ha_rollback()/THD::transaction::cleanup().
 
130
  */
 
131
  thd->transaction.xid_state.rm_error= 0;
 
132
 
 
133
  bool status= test(ha_rollback(thd));
 
134
 
 
135
  thd->options&= ~(ulong) OPTION_BEGIN;
 
136
  thd->transaction.all.modified_non_trans_table= FALSE;
 
137
  thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
138
  xid_cache_delete(&thd->transaction.xid_state);
 
139
  thd->transaction.xid_state.xa_state= XA_NOTR;
 
140
 
 
141
  return status;
 
142
}
 
143
 
 
144
static void unlock_locked_tables(THD *thd)
 
145
{
 
146
  if (thd->locked_tables)
 
147
  {
 
148
    thd->lock=thd->locked_tables;
 
149
    thd->locked_tables=0;                       // Will be automatically closed
 
150
    close_thread_tables(thd);                   // Free tables
 
151
  }
 
152
}
 
153
 
 
154
 
 
155
bool end_active_trans(THD *thd)
 
156
{
 
157
  int error=0;
 
158
  DBUG_ENTER("end_active_trans");
 
159
  if (unlikely(thd->in_sub_stmt))
 
160
  {
 
161
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
162
    DBUG_RETURN(1);
 
163
  }
 
164
  if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
165
  {
 
166
    my_error(ER_XAER_RMFAIL, MYF(0),
 
167
             xa_state_names[thd->transaction.xid_state.xa_state]);
 
168
    DBUG_RETURN(1);
 
169
  }
 
170
  if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
 
171
                      OPTION_TABLE_LOCK))
 
172
  {
 
173
    DBUG_PRINT("info",("options: 0x%llx", thd->options));
 
174
    /* Safety if one did "drop table" on locked tables */
 
175
    if (!thd->locked_tables)
 
176
      thd->options&= ~OPTION_TABLE_LOCK;
 
177
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
178
    if (ha_commit(thd))
 
179
      error=1;
 
180
  }
 
181
  thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
182
  thd->transaction.all.modified_non_trans_table= FALSE;
 
183
  DBUG_RETURN(error);
 
184
}
 
185
 
 
186
 
 
187
bool begin_trans(THD *thd)
 
188
{
 
189
  int error=0;
 
190
  if (unlikely(thd->in_sub_stmt))
 
191
  {
 
192
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
193
    return 1;
 
194
  }
 
195
  if (thd->locked_tables)
 
196
  {
 
197
    thd->lock=thd->locked_tables;
 
198
    thd->locked_tables=0;                       // Will be automatically closed
 
199
    close_thread_tables(thd);                   // Free tables
 
200
  }
 
201
  if (end_active_trans(thd))
 
202
    error= -1;
 
203
  else
 
204
  {
 
205
    thd->options|= OPTION_BEGIN;
 
206
    thd->server_status|= SERVER_STATUS_IN_TRANS;
 
207
  }
 
208
  return error;
 
209
}
 
210
 
 
211
#ifdef HAVE_REPLICATION
 
212
/**
 
213
  Returns true if all tables should be ignored.
 
214
*/
 
215
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
 
216
{
 
217
  return rpl_filter->is_on() && tables && !thd->spcont &&
 
218
         !rpl_filter->tables_ok(thd->db, tables);
 
219
}
 
220
#endif
 
221
 
 
222
 
 
223
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
 
224
{
 
225
  for (TABLE_LIST *table= tables; table; table= table->next_global)
 
226
  {
 
227
    DBUG_ASSERT(table->db && table->table_name);
 
228
    if (table->updating &&
 
229
        !find_temporary_table(thd, table->db, table->table_name))
 
230
      return 1;
 
231
  }
 
232
  return 0;
 
233
}
 
234
 
 
235
 
 
236
/**
 
237
  Mark all commands that somehow changes a table.
 
238
 
 
239
  This is used to check number of updates / hour.
 
240
 
 
241
  sql_command is actually set to SQLCOM_END sometimes
 
242
  so we need the +1 to include it in the array.
 
243
 
 
244
  See COMMAND_FLAG_xxx for different type of commands
 
245
     2  - query that returns meaningful ROW_COUNT() -
 
246
          a number of modified rows
 
247
*/
 
248
 
 
249
uint sql_command_flags[SQLCOM_END+1];
 
250
 
 
251
void init_update_queries(void)
 
252
{
 
253
  bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
 
254
 
 
255
  sql_command_flags[SQLCOM_CREATE_TABLE]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
 
256
  sql_command_flags[SQLCOM_CREATE_INDEX]=   CF_CHANGES_DATA;
 
257
  sql_command_flags[SQLCOM_ALTER_TABLE]=    CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
 
258
  sql_command_flags[SQLCOM_TRUNCATE]=       CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
 
259
  sql_command_flags[SQLCOM_DROP_TABLE]=     CF_CHANGES_DATA;
 
260
  sql_command_flags[SQLCOM_LOAD]=           CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
 
261
  sql_command_flags[SQLCOM_CREATE_DB]=      CF_CHANGES_DATA;
 
262
  sql_command_flags[SQLCOM_DROP_DB]=        CF_CHANGES_DATA;
 
263
  sql_command_flags[SQLCOM_RENAME_TABLE]=   CF_CHANGES_DATA;
 
264
  sql_command_flags[SQLCOM_BACKUP_TABLE]=   CF_CHANGES_DATA;
 
265
  sql_command_flags[SQLCOM_RESTORE_TABLE]=  CF_CHANGES_DATA;
 
266
  sql_command_flags[SQLCOM_DROP_INDEX]=     CF_CHANGES_DATA;
 
267
  sql_command_flags[SQLCOM_CREATE_VIEW]=    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
 
268
  sql_command_flags[SQLCOM_DROP_VIEW]=      CF_CHANGES_DATA;
 
269
  sql_command_flags[SQLCOM_CREATE_EVENT]=   CF_CHANGES_DATA;
 
270
  sql_command_flags[SQLCOM_ALTER_EVENT]=    CF_CHANGES_DATA;
 
271
  sql_command_flags[SQLCOM_DROP_EVENT]=     CF_CHANGES_DATA;
 
272
 
 
273
  sql_command_flags[SQLCOM_UPDATE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
274
                                            CF_REEXECUTION_FRAGILE;
 
275
  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
276
                                            CF_REEXECUTION_FRAGILE;
 
277
  sql_command_flags[SQLCOM_INSERT]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
278
                                            CF_REEXECUTION_FRAGILE;
 
279
  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
280
                                            CF_REEXECUTION_FRAGILE;
 
281
  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
282
                                            CF_REEXECUTION_FRAGILE;
 
283
  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
284
                                            CF_REEXECUTION_FRAGILE;
 
285
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
286
                                            CF_REEXECUTION_FRAGILE;
 
287
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
 
288
                                            CF_REEXECUTION_FRAGILE;
 
289
  sql_command_flags[SQLCOM_SELECT]=         CF_REEXECUTION_FRAGILE;
 
290
  sql_command_flags[SQLCOM_SET_OPTION]=     CF_REEXECUTION_FRAGILE;
 
291
  sql_command_flags[SQLCOM_DO]=             CF_REEXECUTION_FRAGILE;
 
292
 
 
293
  sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
294
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
295
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
296
  sql_command_flags[SQLCOM_SHOW_TRIGGERS]=    CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
297
  sql_command_flags[SQLCOM_SHOW_EVENTS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
298
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
299
  sql_command_flags[SQLCOM_SHOW_PLUGINS]=     CF_STATUS_COMMAND;
 
300
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
301
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
302
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
303
  sql_command_flags[SQLCOM_SHOW_CHARSETS]=    CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
304
  sql_command_flags[SQLCOM_SHOW_COLLATIONS]=  CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
305
  sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND;
 
306
  sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
 
307
  sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
 
308
  sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
 
309
  sql_command_flags[SQLCOM_SHOW_COLUMN_TYPES]= CF_STATUS_COMMAND;
 
310
  sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
 
311
  sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND;
 
312
  sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND;
 
313
  sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
 
314
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
 
315
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
316
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
317
  sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
 
318
  sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
 
319
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
 
320
  sql_command_flags[SQLCOM_SHOW_GRANTS]=  CF_STATUS_COMMAND;
 
321
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
 
322
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
 
323
  sql_command_flags[SQLCOM_SHOW_MASTER_STAT]=  CF_STATUS_COMMAND;
 
324
  sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]=  CF_STATUS_COMMAND;
 
325
  sql_command_flags[SQLCOM_SHOW_CREATE_PROC]=  CF_STATUS_COMMAND;
 
326
  sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]=  CF_STATUS_COMMAND;
 
327
  sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]=  CF_STATUS_COMMAND;
 
328
  sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]=  CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
 
329
  sql_command_flags[SQLCOM_SHOW_PROC_CODE]=  CF_STATUS_COMMAND;
 
330
  sql_command_flags[SQLCOM_SHOW_FUNC_CODE]=  CF_STATUS_COMMAND;
 
331
  sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]=  CF_STATUS_COMMAND;
 
332
  sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
 
333
  sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
 
334
 
 
335
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
336
                                                 CF_SHOW_TABLE_COMMAND |
 
337
                                                 CF_REEXECUTION_FRAGILE);
 
338
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
339
                                                CF_SHOW_TABLE_COMMAND |
 
340
                                                CF_REEXECUTION_FRAGILE);
 
341
 
 
342
  /*
 
343
    The following is used to preserver CF_ROW_COUNT during the
 
344
    a CALL or EXECUTE statement, so the value generated by the
 
345
    last called (or executed) statement is preserved.
 
346
    See mysql_execute_command() for how CF_ROW_COUNT is used.
 
347
  */
 
348
  sql_command_flags[SQLCOM_CALL]=               CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE;
 
349
  sql_command_flags[SQLCOM_EXECUTE]=            CF_HAS_ROW_COUNT;
 
350
 
 
351
  /*
 
352
    The following admin table operations are allowed
 
353
    on log tables.
 
354
  */
 
355
  sql_command_flags[SQLCOM_REPAIR]=           CF_WRITE_LOGS_COMMAND;
 
356
  sql_command_flags[SQLCOM_OPTIMIZE]=         CF_WRITE_LOGS_COMMAND;
 
357
  sql_command_flags[SQLCOM_ANALYZE]=          CF_WRITE_LOGS_COMMAND;
 
358
}
 
359
 
 
360
 
 
361
bool is_update_query(enum enum_sql_command command)
 
362
{
 
363
  DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
 
364
  return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
 
365
}
 
366
 
 
367
/**
 
368
  Check if a sql command is allowed to write to log tables.
 
369
  @param command The SQL command
 
370
  @return true if writing is allowed
 
371
*/
 
372
bool is_log_table_write_query(enum enum_sql_command command)
 
373
{
 
374
  DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
 
375
  return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
 
376
}
 
377
 
 
378
void execute_init_command(THD *thd, sys_var_str *init_command_var,
 
379
                          rw_lock_t *var_mutex)
 
380
{
 
381
  Vio* save_vio;
 
382
  ulong save_client_capabilities;
 
383
 
 
384
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
385
  thd->profiling.start_new_query();
 
386
  thd->profiling.set_query_source(init_command_var->value,
 
387
                                  init_command_var->value_length);
 
388
#endif
 
389
 
 
390
  thd_proc_info(thd, "Execution of init_command");
 
391
  /*
 
392
    We need to lock init_command_var because
 
393
    during execution of init_command_var query
 
394
    values of init_command_var can't be changed
 
395
  */
 
396
  rw_rdlock(var_mutex);
 
397
  save_client_capabilities= thd->client_capabilities;
 
398
  thd->client_capabilities|= CLIENT_MULTI_QUERIES;
 
399
  /*
 
400
    We don't need return result of execution to client side.
 
401
    To forbid this we should set thd->net.vio to 0.
 
402
  */
 
403
  save_vio= thd->net.vio;
 
404
  thd->net.vio= 0;
 
405
  dispatch_command(COM_QUERY, thd,
 
406
                   init_command_var->value,
 
407
                   init_command_var->value_length);
 
408
  rw_unlock(var_mutex);
 
409
  thd->client_capabilities= save_client_capabilities;
 
410
  thd->net.vio= save_vio;
 
411
 
 
412
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
413
  thd->profiling.finish_current_query();
 
414
#endif
 
415
}
 
416
 
 
417
 
 
418
static void handle_bootstrap_impl(THD *thd)
 
419
{
 
420
  FILE *file=bootstrap_file;
 
421
  char *buff;
 
422
  const char* found_semicolon= NULL;
 
423
 
 
424
  DBUG_ENTER("handle_bootstrap");
 
425
 
 
426
#ifndef EMBEDDED_LIBRARY
 
427
  pthread_detach_this_thread();
 
428
  thd->thread_stack= (char*) &thd;
 
429
#endif /* EMBEDDED_LIBRARY */
 
430
 
 
431
  if (thd->variables.max_join_size == HA_POS_ERROR)
 
432
    thd->options |= OPTION_BIG_SELECTS;
 
433
 
 
434
  thd_proc_info(thd, 0);
 
435
  thd->version=refresh_version;
 
436
  thd->security_ctx->priv_user=
 
437
    thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
 
438
  thd->security_ctx->priv_host[0]=0;
 
439
  /*
 
440
    Make the "client" handle multiple results. This is necessary
 
441
    to enable stored procedures with SELECTs and Dynamic SQL
 
442
    in init-file.
 
443
  */
 
444
  thd->client_capabilities|= CLIENT_MULTI_RESULTS;
 
445
 
 
446
  buff= (char*) thd->net.buff;
 
447
  thd->init_for_queries();
 
448
  while (fgets(buff, thd->net.max_packet, file))
 
449
  {
 
450
    char *query, *res;
 
451
    /* strlen() can't be deleted because fgets() doesn't return length */
 
452
    ulong length= (ulong) strlen(buff);
 
453
    while (buff[length-1] != '\n' && !feof(file))
 
454
    {
 
455
      /*
 
456
        We got only a part of the current string. Will try to increase
 
457
        net buffer then read the rest of the current string.
 
458
      */
 
459
      /* purecov: begin tested */
 
460
      if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
 
461
      {
 
462
        net_end_statement(thd);
 
463
        bootstrap_error= 1;
 
464
        break;
 
465
      }
 
466
      buff= (char*) thd->net.buff;
 
467
      res= fgets(buff + length, thd->net.max_packet - length, file);
 
468
      length+= (ulong) strlen(buff + length);
 
469
      /* purecov: end */
 
470
    }
 
471
    if (bootstrap_error)
 
472
      break;                                    /* purecov: inspected */
 
473
 
 
474
    while (length && (my_isspace(thd->charset(), buff[length-1]) ||
 
475
                      buff[length-1] == ';'))
 
476
      length--;
 
477
    buff[length]=0;
 
478
 
 
479
    /* Skip lines starting with delimiter */
 
480
    if (strncmp(buff, STRING_WITH_LEN("delimiter")) == 0)
 
481
      continue;
 
482
 
 
483
    query= (char *) thd->memdup_w_gap(buff, length + 1,
 
484
                                      thd->db_length + 1 +
 
485
                                      QUERY_CACHE_FLAGS_SIZE);
 
486
    thd->set_query(query, length);
 
487
    DBUG_PRINT("query",("%-.4096s", thd->query()));
 
488
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
489
    thd->profiling.start_new_query();
 
490
    thd->profiling.set_query_source(thd->query(), length);
 
491
#endif
 
492
 
 
493
    /*
 
494
      We don't need to obtain LOCK_thread_count here because in bootstrap
 
495
      mode we have only one thread.
 
496
    */
 
497
    thd->query_id=next_query_id();
 
498
    thd->set_time();
 
499
    mysql_parse(thd, thd->query(), length, & found_semicolon);
 
500
    close_thread_tables(thd);                   // Free tables
 
501
 
 
502
    bootstrap_error= thd->is_error();
 
503
    net_end_statement(thd);
 
504
 
 
505
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
506
    thd->profiling.finish_current_query();
 
507
#endif
 
508
 
 
509
    if (bootstrap_error)
 
510
      break;
 
511
 
 
512
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
513
#ifdef USING_TRANSACTIONS
 
514
    free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
 
515
#endif
 
516
  }
 
517
 
 
518
  DBUG_VOID_RETURN;
 
519
}
 
520
 
 
521
 
 
522
/**
 
523
  Execute commands from bootstrap_file.
 
524
 
 
525
  Used when creating the initial grant tables.
 
526
*/
 
527
 
 
528
pthread_handler_t handle_bootstrap(void *arg)
 
529
{
 
530
  THD *thd=(THD*) arg;
 
531
 
 
532
  /* The following must be called before DBUG_ENTER */
 
533
  thd->thread_stack= (char*) &thd;
 
534
  if (my_thread_init() || thd->store_globals())
 
535
  {
 
536
#ifndef EMBEDDED_LIBRARY
 
537
    close_connection(thd, ER_OUT_OF_RESOURCES, 1);
 
538
#endif
 
539
    thd->fatal_error();
 
540
    goto end;
 
541
  }
 
542
 
 
543
  handle_bootstrap_impl(thd);
 
544
 
 
545
end:
 
546
  net_end(&thd->net);
 
547
  thd->cleanup();
 
548
  delete thd;
 
549
 
 
550
#ifndef EMBEDDED_LIBRARY
 
551
  (void) pthread_mutex_lock(&LOCK_thread_count);
 
552
  thread_count--;
 
553
  in_bootstrap= FALSE;
 
554
  (void) pthread_cond_broadcast(&COND_thread_count);
 
555
  (void) pthread_mutex_unlock(&LOCK_thread_count);
 
556
  my_thread_end();
 
557
  pthread_exit(0);
 
558
#endif
 
559
 
 
560
  return 0;
 
561
}
 
562
 
 
563
 
 
564
/**
 
565
  @brief Check access privs for a MERGE table and fix children lock types.
 
566
 
 
567
  @param[in]        thd         thread handle
 
568
  @param[in]        db          database name
 
569
  @param[in,out]    table_list  list of child tables (merge_list)
 
570
                                lock_type and optionally db set per table
 
571
 
 
572
  @return           status
 
573
    @retval         0           OK
 
574
    @retval         != 0        Error
 
575
 
 
576
  @detail
 
577
    This function is used for write access to MERGE tables only
 
578
    (CREATE TABLE, ALTER TABLE ... UNION=(...)). Set TL_WRITE for
 
579
    every child. Set 'db' for every child if not present.
 
580
*/
 
581
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
582
static bool check_merge_table_access(THD *thd, char *db,
 
583
                                     TABLE_LIST *table_list)
 
584
{
 
585
  int error= 0;
 
586
 
 
587
  if (table_list)
 
588
  {
 
589
    /* Check that all tables use the current database */
 
590
    TABLE_LIST *tlist;
 
591
 
 
592
    for (tlist= table_list; tlist; tlist= tlist->next_local)
 
593
    {
 
594
      if (!tlist->db || !tlist->db[0])
 
595
        tlist->db= db; /* purecov: inspected */
 
596
    }
 
597
    error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
 
598
                              table_list, UINT_MAX, FALSE);
 
599
  }
 
600
  return error;
 
601
}
 
602
#endif
 
603
 
 
604
/* This works because items are allocated with sql_alloc() */
 
605
 
 
606
void free_items(Item *item)
 
607
{
 
608
  Item *next;
 
609
  DBUG_ENTER("free_items");
 
610
  for (; item ; item=next)
 
611
  {
 
612
    next=item->next;
 
613
    item->delete_self();
 
614
  }
 
615
  DBUG_VOID_RETURN;
 
616
}
 
617
 
 
618
/**
 
619
   This works because items are allocated with sql_alloc().
 
620
   @note The function also handles null pointers (empty list).
 
621
*/
 
622
void cleanup_items(Item *item)
 
623
{
 
624
  DBUG_ENTER("cleanup_items");  
 
625
  for (; item ; item=item->next)
 
626
    item->cleanup();
 
627
  DBUG_VOID_RETURN;
 
628
}
 
629
 
 
630
/**
 
631
  Handle COM_TABLE_DUMP command.
 
632
 
 
633
  @param thd           thread handle
 
634
  @param db            database name or an empty string. If empty,
 
635
                       the current database of the connection is used
 
636
  @param tbl_name      name of the table to dump
 
637
 
 
638
  @note
 
639
    This function is written to handle one specific command only.
 
640
 
 
641
  @retval
 
642
    0               success
 
643
  @retval
 
644
    1               error, the error message is set in THD
 
645
*/
 
646
 
 
647
static
 
648
int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
 
649
{
 
650
  TABLE* table;
 
651
  TABLE_LIST* table_list;
 
652
  int error = 0;
 
653
  DBUG_ENTER("mysql_table_dump");
 
654
  if (db->length == 0)
 
655
  {
 
656
    db->str= thd->db;            /* purecov: inspected */
 
657
    db->length= thd->db_length;  /* purecov: inspected */
 
658
  }
 
659
  if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
 
660
    DBUG_RETURN(1); // out of memory
 
661
  table_list->db= db->str;
 
662
  table_list->table_name= table_list->alias= tbl_name;
 
663
  table_list->lock_type= TL_READ_NO_INSERT;
 
664
  table_list->prev_global= &table_list; // can be removed after merge with 4.1
 
665
 
 
666
  if (check_db_name(db))
 
667
  {
 
668
    /* purecov: begin inspected */
 
669
    my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
 
670
    goto err;
 
671
    /* purecov: end */
 
672
  }
 
673
  if (lower_case_table_names)
 
674
    my_casedn_str(files_charset_info, tbl_name);
 
675
 
 
676
  if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT, 0)))
 
677
    DBUG_RETURN(1);
 
678
 
 
679
  if (check_one_table_access(thd, SELECT_ACL, table_list))
 
680
    goto err;
 
681
  thd->free_list = 0;
 
682
  thd->set_query(tbl_name, (uint) strlen(tbl_name));
 
683
  if ((error = mysqld_dump_create_info(thd, table_list, -1)))
 
684
  {
 
685
    my_error(ER_GET_ERRNO, MYF(0), my_errno);
 
686
    goto err;
 
687
  }
 
688
  net_flush(&thd->net);
 
689
  if ((error= table->file->dump(thd,-1)))
 
690
    my_error(ER_GET_ERRNO, MYF(0), error);
 
691
 
 
692
err:
 
693
  DBUG_RETURN(error);
 
694
}
 
695
 
 
696
/**
 
697
  Ends the current transaction and (maybe) begin the next.
 
698
 
 
699
  @param thd            Current thread
 
700
  @param completion     Completion type
 
701
 
 
702
  @retval
 
703
    0   OK
 
704
*/
 
705
 
 
706
int end_trans(THD *thd, enum enum_mysql_completiontype completion)
 
707
{
 
708
  bool do_release= 0;
 
709
  int res= 0;
 
710
  DBUG_ENTER("end_trans");
 
711
 
 
712
  if (unlikely(thd->in_sub_stmt))
 
713
  {
 
714
    my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
 
715
    DBUG_RETURN(1);
 
716
  }
 
717
  if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
718
  {
 
719
    my_error(ER_XAER_RMFAIL, MYF(0),
 
720
             xa_state_names[thd->transaction.xid_state.xa_state]);
 
721
    DBUG_RETURN(1);
 
722
  }
 
723
  switch (completion) {
 
724
  case COMMIT:
 
725
    /*
 
726
     We don't use end_active_trans() here to ensure that this works
 
727
     even if there is a problem with the OPTION_AUTO_COMMIT flag
 
728
     (Which of course should never happen...)
 
729
    */
 
730
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
731
    res= ha_commit(thd);
 
732
    thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
733
    thd->transaction.all.modified_non_trans_table= FALSE;
 
734
    break;
 
735
  case COMMIT_RELEASE:
 
736
    do_release= 1; /* fall through */
 
737
  case COMMIT_AND_CHAIN:
 
738
    res= end_active_trans(thd);
 
739
    if (!res && completion == COMMIT_AND_CHAIN)
 
740
      res= begin_trans(thd);
 
741
    break;
 
742
  case ROLLBACK_RELEASE:
 
743
    do_release= 1; /* fall through */
 
744
  case ROLLBACK:
 
745
  case ROLLBACK_AND_CHAIN:
 
746
  {
 
747
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
748
    if (ha_rollback(thd))
 
749
      res= -1;
 
750
    thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
751
    thd->transaction.all.modified_non_trans_table= FALSE;
 
752
    if (!res && (completion == ROLLBACK_AND_CHAIN))
 
753
      res= begin_trans(thd);
 
754
    break;
 
755
  }
 
756
  default:
 
757
    res= -1;
 
758
    my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
 
759
    DBUG_RETURN(-1);
 
760
  }
 
761
 
 
762
  if (res < 0)
 
763
    my_error(thd->killed_errno(), MYF(0));
 
764
  else if ((res == 0) && do_release)
 
765
    thd->killed= THD::KILL_CONNECTION;
 
766
 
 
767
  DBUG_RETURN(res);
 
768
}
 
769
 
 
770
#ifndef EMBEDDED_LIBRARY
 
771
 
 
772
/**
 
773
  Read one command from connection and execute it (query or simple command).
 
774
  This function is called in loop from thread function.
 
775
 
 
776
  For profiling to work, it must never be called recursively.
 
777
 
 
778
  @retval
 
779
    0  success
 
780
  @retval
 
781
    1  request of thread shutdown (see dispatch_command() description)
 
782
*/
 
783
 
 
784
bool do_command(THD *thd)
 
785
{
 
786
  bool return_value;
 
787
  char *packet= 0;
 
788
  ulong packet_length;
 
789
  NET *net= &thd->net;
 
790
  enum enum_server_command command;
 
791
  DBUG_ENTER("do_command");
 
792
 
 
793
  /*
 
794
    indicator of uninitialized lex => normal flow of errors handling
 
795
    (see my_message_sql)
 
796
  */
 
797
  thd->lex->current_select= 0;
 
798
 
 
799
  /*
 
800
    This thread will do a blocking read from the client which
 
801
    will be interrupted when the next command is received from
 
802
    the client, the connection is closed or "net_wait_timeout"
 
803
    number of seconds has passed
 
804
  */
 
805
  my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
 
806
 
 
807
  /*
 
808
    XXX: this code is here only to clear possible errors of init_connect. 
 
809
    Consider moving to init_connect() instead.
 
810
  */
 
811
  thd->clear_error();                           // Clear error message
 
812
  thd->main_da.reset_diagnostics_area();
 
813
 
 
814
  net_new_transaction(net);
 
815
 
 
816
  packet_length= my_net_read(net);
 
817
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
818
  thd->profiling.start_new_query();
 
819
#endif
 
820
  if (packet_length == packet_error)
 
821
  {
 
822
    DBUG_PRINT("info",("Got error %d reading command from socket %s",
 
823
                       net->error,
 
824
                       vio_description(net->vio)));
 
825
 
 
826
    /* Check if we can continue without closing the connection */
 
827
 
 
828
    /* The error must be set. */
 
829
    DBUG_ASSERT(thd->is_error());
 
830
    net_end_statement(thd);
 
831
 
 
832
    if (net->error != 3)
 
833
    {
 
834
      return_value= TRUE;                       // We have to close it.
 
835
      goto out;
 
836
    }
 
837
 
 
838
    net->error= 0;
 
839
    return_value= FALSE;
 
840
    goto out;
 
841
  }
 
842
 
 
843
  packet= (char*) net->read_pos;
 
844
  /*
 
845
    'packet_length' contains length of data, as it was stored in packet
 
846
    header. In case of malformed header, my_net_read returns zero.
 
847
    If packet_length is not zero, my_net_read ensures that the returned
 
848
    number of bytes was actually read from network.
 
849
    There is also an extra safety measure in my_net_read:
 
850
    it sets packet[packet_length]= 0, but only for non-zero packets.
 
851
  */
 
852
  if (packet_length == 0)                       /* safety */
 
853
  {
 
854
    /* Initialize with COM_SLEEP packet */
 
855
    packet[0]= (uchar) COM_SLEEP;
 
856
    packet_length= 1;
 
857
  }
 
858
  /* Do not rely on my_net_read, extra safety against programming errors. */
 
859
  packet[packet_length]= '\0';                  /* safety */
 
860
 
 
861
  command= (enum enum_server_command) (uchar) packet[0];
 
862
 
 
863
  if (command >= COM_END)
 
864
    command= COM_END;                           // Wrong command
 
865
 
 
866
  DBUG_PRINT("info",("Command on %s = %d (%s)",
 
867
                     vio_description(net->vio), command,
 
868
                     command_name[command].str));
 
869
 
 
870
  /* Restore read timeout value */
 
871
  my_net_set_read_timeout(net, thd->variables.net_read_timeout);
 
872
 
 
873
  DBUG_ASSERT(packet_length);
 
874
  return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
 
875
 
 
876
out:
 
877
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
878
  thd->profiling.finish_current_query();
 
879
#endif
 
880
  DBUG_RETURN(return_value);
 
881
}
 
882
#endif  /* EMBEDDED_LIBRARY */
 
883
 
 
884
/**
 
885
  @brief Determine if an attempt to update a non-temporary table while the
 
886
    read-only option was enabled has been made.
 
887
 
 
888
  This is a helper function to mysql_execute_command.
 
889
 
 
890
  @note SQLCOM_MULTI_UPDATE is an exception and delt with elsewhere.
 
891
 
 
892
  @see mysql_execute_command
 
893
  @returns Status code
 
894
    @retval TRUE The statement should be denied.
 
895
    @retval FALSE The statement isn't updating any relevant tables.
 
896
*/
 
897
 
 
898
static my_bool deny_updates_if_read_only_option(THD *thd,
 
899
                                                TABLE_LIST *all_tables)
 
900
{
 
901
  DBUG_ENTER("deny_updates_if_read_only_option");
 
902
 
 
903
  if (!opt_readonly)
 
904
    DBUG_RETURN(FALSE);
 
905
 
 
906
  LEX *lex= thd->lex;
 
907
 
 
908
  const my_bool user_is_super=
 
909
    ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
 
910
     (ulong)SUPER_ACL);
 
911
 
 
912
  if (user_is_super)
 
913
    DBUG_RETURN(FALSE);
 
914
 
 
915
  if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
 
916
    DBUG_RETURN(FALSE);
 
917
 
 
918
  /* Multi update is an exception and is dealt with later. */
 
919
  if (lex->sql_command == SQLCOM_UPDATE_MULTI)
 
920
    DBUG_RETURN(FALSE);
 
921
 
 
922
  const my_bool create_temp_tables= 
 
923
    (lex->sql_command == SQLCOM_CREATE_TABLE) &&
 
924
    (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
 
925
 
 
926
  const my_bool drop_temp_tables= 
 
927
    (lex->sql_command == SQLCOM_DROP_TABLE) &&
 
928
    lex->drop_temporary;
 
929
 
 
930
  const my_bool update_real_tables=
 
931
    some_non_temp_table_to_be_updated(thd, all_tables) &&
 
932
    !(create_temp_tables || drop_temp_tables);
 
933
 
 
934
 
 
935
  const my_bool create_or_drop_databases=
 
936
    (lex->sql_command == SQLCOM_CREATE_DB) ||
 
937
    (lex->sql_command == SQLCOM_DROP_DB);
 
938
 
 
939
  if (update_real_tables || create_or_drop_databases)
 
940
  {
 
941
      /*
 
942
        An attempt was made to modify one or more non-temporary tables.
 
943
      */
 
944
      DBUG_RETURN(TRUE);
 
945
  }
 
946
 
 
947
 
 
948
  /* Assuming that only temporary tables are modified. */
 
949
  DBUG_RETURN(FALSE);
 
950
}
 
951
 
 
952
/**
 
953
  Perform one connection-level (COM_XXXX) command.
 
954
 
 
955
  @param command         type of command to perform
 
956
  @param thd             connection handle
 
957
  @param packet          data for the command, packet is always null-terminated
 
958
  @param packet_length   length of packet + 1 (to show that data is
 
959
                         null-terminated) except for COM_SLEEP, where it
 
960
                         can be zero.
 
961
 
 
962
  @todo
 
963
    set thd->lex->sql_command to SQLCOM_END here.
 
964
  @todo
 
965
    The following has to be changed to an 8 byte integer
 
966
 
 
967
  @retval
 
968
    0   ok
 
969
  @retval
 
970
    1   request of thread shutdown, i. e. if command is
 
971
        COM_QUIT/COM_SHUTDOWN
 
972
*/
 
973
bool dispatch_command(enum enum_server_command command, THD *thd,
 
974
                      char* packet, uint packet_length)
 
975
{
 
976
  NET *net= &thd->net;
 
977
  bool error= 0;
 
978
  DBUG_ENTER("dispatch_command");
 
979
  DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
 
980
 
 
981
  thd->command=command;
 
982
  /*
 
983
    Commands which always take a long time are logged into
 
984
    the slow log only if opt_log_slow_admin_statements is set.
 
985
  */
 
986
  thd->enable_slow_log= TRUE;
 
987
  thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
 
988
  thd->set_time();
 
989
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
990
  thd->query_id= global_query_id;
 
991
 
 
992
  switch( command ) {
 
993
  /* Ignore these statements. */
 
994
  case COM_STATISTICS:
 
995
  case COM_PING:
 
996
    break;
 
997
  /* Only increase id on these statements but don't count them. */
 
998
  case COM_STMT_PREPARE: 
 
999
  case COM_STMT_CLOSE:
 
1000
  case COM_STMT_RESET:
 
1001
    next_query_id();
 
1002
    break;
 
1003
  /* Increase id and count all other statements. */
 
1004
  default:
 
1005
    statistic_increment(thd->status_var.questions, &LOCK_status);
 
1006
    next_query_id();
 
1007
  }
 
1008
 
 
1009
  thread_running++;
 
1010
  /* TODO: set thd->lex->sql_command to SQLCOM_END here */
 
1011
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
1012
 
 
1013
  /**
 
1014
    Clear the set of flags that are expected to be cleared at the
 
1015
    beginning of each command.
 
1016
  */
 
1017
  thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
 
1018
  switch (command) {
 
1019
  case COM_INIT_DB:
 
1020
  {
 
1021
    LEX_STRING tmp;
 
1022
    status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
 
1023
    thd->convert_string(&tmp, system_charset_info,
 
1024
                        packet, packet_length, thd->charset());
 
1025
    if (!mysql_change_db(thd, &tmp, FALSE))
 
1026
    {
 
1027
      general_log_write(thd, command, thd->db, thd->db_length);
 
1028
      my_ok(thd);
 
1029
    }
 
1030
    break;
 
1031
  }
 
1032
#ifdef HAVE_REPLICATION
 
1033
  case COM_REGISTER_SLAVE:
 
1034
  {
 
1035
    if (!register_slave(thd, (uchar*)packet, packet_length))
 
1036
      my_ok(thd);
 
1037
    break;
 
1038
  }
 
1039
#endif
 
1040
  case COM_TABLE_DUMP:
 
1041
  {
 
1042
    char *tbl_name;
 
1043
    LEX_STRING db;
 
1044
    /* Safe because there is always a trailing \0 at the end of the packet */
 
1045
    uint db_len= *(uchar*) packet;
 
1046
    if (db_len + 1 > packet_length || db_len > NAME_LEN)
 
1047
    {
 
1048
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1049
      break;
 
1050
    }
 
1051
    /* Safe because there is always a trailing \0 at the end of the packet */
 
1052
    uint tbl_len= *(uchar*) (packet + db_len + 1);
 
1053
    if (db_len + tbl_len + 2 > packet_length || tbl_len > NAME_LEN)
 
1054
    {
 
1055
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1056
      break;
 
1057
    }
 
1058
 
 
1059
    status_var_increment(thd->status_var.com_other);
 
1060
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
1061
    db.str= (char*) thd->alloc(db_len + tbl_len + 2);
 
1062
    if (!db.str)
 
1063
    {
 
1064
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 
1065
      break;
 
1066
    }
 
1067
    db.length= db_len;
 
1068
    tbl_name= strmake(db.str, packet + 1, db_len)+1;
 
1069
    strmake(tbl_name, packet + db_len + 2, tbl_len);
 
1070
    if (mysql_table_dump(thd, &db, tbl_name) == 0)
 
1071
      thd->main_da.disable_status();
 
1072
    break;
 
1073
  }
 
1074
  case COM_CHANGE_USER:
 
1075
  {
 
1076
    status_var_increment(thd->status_var.com_other);
 
1077
    char *user= (char*) packet, *packet_end= packet + packet_length;
 
1078
    /* Safe because there is always a trailing \0 at the end of the packet */
 
1079
    char *passwd= strend(user)+1;
 
1080
 
 
1081
    thd->change_user();
 
1082
    thd->clear_error();                         // if errors from rollback
 
1083
 
 
1084
    /*
 
1085
      Old clients send null-terminated string ('\0' for empty string) for
 
1086
      password.  New clients send the size (1 byte) + string (not null
 
1087
      terminated, so also '\0' for empty string).
 
1088
 
 
1089
      Cast *passwd to an unsigned char, so that it doesn't extend the sign
 
1090
      for *passwd > 127 and become 2**32-127 after casting to uint.
 
1091
    */
 
1092
    char db_buff[NAME_LEN+1];                 // buffer to store db in utf8
 
1093
    char *db= passwd;
 
1094
    char *save_db;
 
1095
    /*
 
1096
      If there is no password supplied, the packet must contain '\0',
 
1097
      in any type of handshake (4.1 or pre-4.1).
 
1098
     */
 
1099
    if (passwd >= packet_end)
 
1100
    {
 
1101
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1102
      break;
 
1103
    }
 
1104
    uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
 
1105
                      (uchar)(*passwd++) : strlen(passwd));
 
1106
    uint dummy_errors, save_db_length, db_length;
 
1107
    int res;
 
1108
    Security_context save_security_ctx= *thd->security_ctx;
 
1109
    USER_CONN *save_user_connect;
 
1110
 
 
1111
    db+= passwd_len + 1;
 
1112
    /*
 
1113
      Database name is always NUL-terminated, so in case of empty database
 
1114
      the packet must contain at least the trailing '\0'.
 
1115
    */
 
1116
    if (db >= packet_end)
 
1117
    {
 
1118
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1119
      break;
 
1120
    }
 
1121
    db_length= strlen(db);
 
1122
 
 
1123
    char *ptr= db + db_length + 1;
 
1124
    uint cs_number= 0;
 
1125
 
 
1126
    if (ptr < packet_end)
 
1127
    {
 
1128
      if (ptr + 2 > packet_end)
 
1129
      {
 
1130
        my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1131
        break;
 
1132
      }
 
1133
 
 
1134
      cs_number= uint2korr(ptr);
 
1135
    }
 
1136
 
 
1137
    /* Convert database name to utf8 */
 
1138
    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
 
1139
                             system_charset_info, db, db_length,
 
1140
                             thd->charset(), &dummy_errors)]= 0;
 
1141
    db= db_buff;
 
1142
 
 
1143
    /* Save user and privileges */
 
1144
    save_db_length= thd->db_length;
 
1145
    save_db= thd->db;
 
1146
    save_user_connect= thd->user_connect;
 
1147
 
 
1148
    if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
 
1149
    {
 
1150
      thd->security_ctx->user= save_security_ctx.user;
 
1151
      my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 
1152
      break;
 
1153
    }
 
1154
 
 
1155
    /* Clear variables that are allocated */
 
1156
    thd->user_connect= 0;
 
1157
    thd->security_ctx->priv_user= thd->security_ctx->user;
 
1158
    res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
 
1159
 
 
1160
    if (res)
 
1161
    {
 
1162
      x_free(thd->security_ctx->user);
 
1163
      *thd->security_ctx= save_security_ctx;
 
1164
      thd->user_connect= save_user_connect;
 
1165
      thd->db= save_db;
 
1166
      thd->db_length= save_db_length;
 
1167
    }
 
1168
    else
 
1169
    {
 
1170
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1171
      /* we've authenticated new user */
 
1172
      if (save_user_connect)
 
1173
        decrease_user_connections(save_user_connect);
 
1174
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 
1175
      x_free(save_db);
 
1176
      x_free(save_security_ctx.user);
 
1177
 
 
1178
      if (cs_number)
 
1179
      {
 
1180
        thd_init_client_charset(thd, cs_number);
 
1181
        thd->update_charset();
 
1182
      }
 
1183
    }
 
1184
    break;
 
1185
  }
 
1186
  case COM_STMT_EXECUTE:
 
1187
  {
 
1188
    mysqld_stmt_execute(thd, packet, packet_length);
 
1189
    break;
 
1190
  }
 
1191
  case COM_STMT_FETCH:
 
1192
  {
 
1193
    mysqld_stmt_fetch(thd, packet, packet_length);
 
1194
    break;
 
1195
  }
 
1196
  case COM_STMT_SEND_LONG_DATA:
 
1197
  {
 
1198
    mysql_stmt_get_longdata(thd, packet, packet_length);
 
1199
    break;
 
1200
  }
 
1201
  case COM_STMT_PREPARE:
 
1202
  {
 
1203
    mysqld_stmt_prepare(thd, packet, packet_length);
 
1204
    break;
 
1205
  }
 
1206
  case COM_STMT_CLOSE:
 
1207
  {
 
1208
    mysqld_stmt_close(thd, packet);
 
1209
    break;
 
1210
  }
 
1211
  case COM_STMT_RESET:
 
1212
  {
 
1213
    mysqld_stmt_reset(thd, packet);
 
1214
    break;
 
1215
  }
 
1216
  case COM_QUERY:
 
1217
  {
 
1218
    if (alloc_query(thd, packet, packet_length))
 
1219
      break;                                    // fatal error is set
 
1220
    char *packet_end= thd->query() + thd->query_length();
 
1221
    /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
 
1222
    const char* end_of_stmt= NULL;
 
1223
 
 
1224
    general_log_write(thd, command, thd->query(), thd->query_length());
 
1225
    DBUG_PRINT("query",("%-.4096s",thd->query()));
 
1226
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
1227
    thd->profiling.set_query_source(thd->query(), thd->query_length());
 
1228
#endif
 
1229
 
 
1230
    if (!(specialflag & SPECIAL_NO_PRIOR))
 
1231
      my_pthread_setprio(pthread_self(),QUERY_PRIOR);
 
1232
 
 
1233
    mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
 
1234
 
 
1235
    while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
 
1236
    {
 
1237
      char *beginning_of_next_stmt= (char*) end_of_stmt;
 
1238
 
 
1239
      net_end_statement(thd);
 
1240
      query_cache_end_of_result(thd);
 
1241
      /*
 
1242
        Multiple queries exits, execute them individually
 
1243
      */
 
1244
      close_thread_tables(thd);
 
1245
      ulong length= (ulong)(packet_end - beginning_of_next_stmt);
 
1246
 
 
1247
      log_slow_statement(thd);
 
1248
 
 
1249
      /* Remove garbage at start of query */
 
1250
      while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
 
1251
      {
 
1252
        beginning_of_next_stmt++;
 
1253
        length--;
 
1254
      }
 
1255
 
 
1256
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
1257
      thd->profiling.finish_current_query();
 
1258
      thd->profiling.start_new_query("continuing");
 
1259
      thd->profiling.set_query_source(beginning_of_next_stmt, length);
 
1260
#endif
 
1261
 
 
1262
      thd->set_query(beginning_of_next_stmt, length);
 
1263
      VOID(pthread_mutex_lock(&LOCK_thread_count));
 
1264
      /*
 
1265
        Count each statement from the client.
 
1266
      */
 
1267
      statistic_increment(thd->status_var.questions, &LOCK_status);
 
1268
      thd->query_id= next_query_id();
 
1269
      thd->set_time(); /* Reset the query start time. */
 
1270
      /* TODO: set thd->lex->sql_command to SQLCOM_END here */
 
1271
      VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
1272
      mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
 
1273
    }
 
1274
 
 
1275
    if (!(specialflag & SPECIAL_NO_PRIOR))
 
1276
      my_pthread_setprio(pthread_self(),WAIT_PRIOR);
 
1277
    DBUG_PRINT("info",("query ready"));
 
1278
    break;
 
1279
  }
 
1280
  case COM_FIELD_LIST:                          // This isn't actually needed
 
1281
#ifdef DONT_ALLOW_SHOW_COMMANDS
 
1282
    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
 
1283
               MYF(0)); /* purecov: inspected */
 
1284
    break;
 
1285
#else
 
1286
  {
 
1287
    char *fields, *packet_end= packet + packet_length, *arg_end;
 
1288
    /* Locked closure of all tables */
 
1289
    TABLE_LIST table_list;
 
1290
    LEX_STRING conv_name;
 
1291
 
 
1292
    /* used as fields initializator */
 
1293
    lex_start(thd);
 
1294
 
 
1295
    status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
 
1296
    bzero((char*) &table_list,sizeof(table_list));
 
1297
    if (thd->copy_db_to(&table_list.db, &table_list.db_length))
 
1298
      break;
 
1299
    /*
 
1300
      We have name + wildcard in packet, separated by endzero
 
1301
    */
 
1302
    arg_end= strend(packet);
 
1303
    thd->convert_string(&conv_name, system_charset_info,
 
1304
                        packet, (uint) (arg_end - packet), thd->charset());
 
1305
    table_list.alias= table_list.table_name= conv_name.str;
 
1306
    packet= arg_end + 1;
 
1307
 
 
1308
    if (is_schema_db(table_list.db, table_list.db_length))
 
1309
    {
 
1310
      ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
 
1311
      if (schema_table)
 
1312
        table_list.schema_table= schema_table;
 
1313
    }
 
1314
 
 
1315
    uint query_length= (uint) (packet_end - packet); // Don't count end \0
 
1316
    if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
 
1317
      break;
 
1318
    thd->set_query(fields, query_length);
 
1319
    general_log_print(thd, command, "%s %s", table_list.table_name, fields);
 
1320
    if (lower_case_table_names)
 
1321
      my_casedn_str(files_charset_info, table_list.table_name);
 
1322
 
 
1323
    if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
 
1324
                     0, 0, test(table_list.schema_table)))
 
1325
      break;
 
1326
    if (check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0))
 
1327
      break;
 
1328
    /* init structures for VIEW processing */
 
1329
    table_list.select_lex= &(thd->lex->select_lex);
 
1330
 
 
1331
    lex_start(thd);
 
1332
    mysql_reset_thd_for_next_command(thd);
 
1333
 
 
1334
    thd->lex->
 
1335
      select_lex.table_list.link_in_list((uchar*) &table_list,
 
1336
                                         (uchar**) &table_list.next_local);
 
1337
    thd->lex->add_to_query_tables(&table_list);
 
1338
 
 
1339
    /* switch on VIEW optimisation: do not fill temporary tables */
 
1340
    thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
 
1341
    mysqld_list_fields(thd,&table_list,fields);
 
1342
    thd->lex->unit.cleanup();
 
1343
    thd->cleanup_after_query();
 
1344
    break;
 
1345
  }
 
1346
#endif
 
1347
  case COM_QUIT:
 
1348
    /* We don't calculate statistics for this command */
 
1349
    general_log_print(thd, command, NullS);
 
1350
    net->error=0;                               // Don't give 'abort' message
 
1351
    thd->main_da.disable_status();              // Don't send anything back
 
1352
    error=TRUE;                                 // End server
 
1353
    break;
 
1354
 
 
1355
#ifdef REMOVED
 
1356
  case COM_CREATE_DB:                           // QQ: To be removed
 
1357
    {
 
1358
      LEX_STRING db, alias;
 
1359
      HA_CREATE_INFO create_info;
 
1360
 
 
1361
      status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
 
1362
      if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
 
1363
          thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
 
1364
          check_db_name(&db))
 
1365
      {
 
1366
        my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
 
1367
        break;
 
1368
      }
 
1369
      if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
 
1370
                       is_schema_db(db.str, db.length)))
 
1371
        break;
 
1372
      general_log_print(thd, command, "%.*s", db.length, db.str);
 
1373
      bzero(&create_info, sizeof(create_info));
 
1374
      mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
 
1375
                      &create_info, 0);
 
1376
      break;
 
1377
    }
 
1378
  case COM_DROP_DB:                             // QQ: To be removed
 
1379
    {
 
1380
      status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
 
1381
      LEX_STRING db;
 
1382
 
 
1383
      if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
 
1384
          check_db_name(&db))
 
1385
      {
 
1386
        my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
 
1387
        break;
 
1388
      }
 
1389
      if (check_access(thd, DROP_ACL, db.str, 0, 1, 0,
 
1390
                            is_schema_db(db.str, db.length)))
 
1391
        break;
 
1392
      if (thd->locked_tables || thd->active_transaction())
 
1393
      {
 
1394
        my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
1395
                   ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
1396
        break;
 
1397
      }
 
1398
      general_log_write(thd, command, "%.*s", db.length, db.str);
 
1399
      mysql_rm_db(thd, db.str, 0, 0);
 
1400
      break;
 
1401
    }
 
1402
#endif
 
1403
#ifndef EMBEDDED_LIBRARY
 
1404
  case COM_BINLOG_DUMP:
 
1405
    {
 
1406
      ulong pos;
 
1407
      ushort flags;
 
1408
      uint32 slave_server_id;
 
1409
 
 
1410
      status_var_increment(thd->status_var.com_other);
 
1411
      thd->enable_slow_log= opt_log_slow_admin_statements;
 
1412
      if (check_global_access(thd, REPL_SLAVE_ACL))
 
1413
        break;
 
1414
 
 
1415
      /* TODO: The following has to be changed to an 8 byte integer */
 
1416
      pos = uint4korr(packet);
 
1417
      flags = uint2korr(packet + 4);
 
1418
      thd->server_id=0; /* avoid suicide */
 
1419
      if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
 
1420
        kill_zombie_dump_threads(slave_server_id);
 
1421
      thd->server_id = slave_server_id;
 
1422
 
 
1423
      general_log_print(thd, command, "Log: '%s'  Pos: %ld", packet+10,
 
1424
                      (long) pos);
 
1425
      mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
 
1426
      unregister_slave(thd,1,1);
 
1427
      /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
 
1428
      error = TRUE;
 
1429
      break;
 
1430
    }
 
1431
#endif
 
1432
  case COM_REFRESH:
 
1433
  {
 
1434
    bool not_used;
 
1435
    status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
 
1436
    ulong options= (ulong) (uchar) packet[0];
 
1437
    if (check_global_access(thd,RELOAD_ACL))
 
1438
      break;
 
1439
    general_log_print(thd, command, NullS);
 
1440
#ifndef DBUG_OFF
 
1441
    bool debug_simulate= FALSE;
 
1442
    DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
 
1443
    if (debug_simulate)
 
1444
    {
 
1445
      /*
 
1446
        Simulate a reload without a attached thread session.
 
1447
        Provides a environment similar to that of when the
 
1448
        server receives a SIGHUP signal and reloads caches
 
1449
        and flushes tables.
 
1450
      */
 
1451
      bool res;
 
1452
      my_pthread_setspecific_ptr(THR_THD, NULL);
 
1453
      res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
 
1454
                                NULL, &not_used);
 
1455
      my_pthread_setspecific_ptr(THR_THD, thd);
 
1456
      if (!res)
 
1457
        my_ok(thd);
 
1458
      break;
 
1459
    }
 
1460
#endif
 
1461
    if (!reload_acl_and_cache(thd, options, NULL, &not_used))
 
1462
      my_ok(thd);
 
1463
    break;
 
1464
  }
 
1465
#ifndef EMBEDDED_LIBRARY
 
1466
  case COM_SHUTDOWN:
 
1467
  {
 
1468
    status_var_increment(thd->status_var.com_other);
 
1469
    if (check_global_access(thd,SHUTDOWN_ACL))
 
1470
      break; /* purecov: inspected */
 
1471
    /*
 
1472
      If the client is < 4.1.3, it is going to send us no argument; then
 
1473
      packet_length is 0, packet[0] is the end 0 of the packet. Note that
 
1474
      SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
 
1475
      packet[0].
 
1476
    */
 
1477
    enum mysql_enum_shutdown_level level=
 
1478
      (enum mysql_enum_shutdown_level) (uchar) packet[0];
 
1479
    if (level == SHUTDOWN_DEFAULT)
 
1480
      level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
 
1481
    else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
 
1482
    {
 
1483
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
 
1484
      break;
 
1485
    }
 
1486
    DBUG_PRINT("quit",("Got shutdown command for level %u", level));
 
1487
    general_log_print(thd, command, NullS);
 
1488
    my_eof(thd);
 
1489
    close_thread_tables(thd);                   // Free before kill
 
1490
    kill_mysql();
 
1491
    error=TRUE;
 
1492
    break;
 
1493
  }
 
1494
#endif
 
1495
  case COM_STATISTICS:
 
1496
  {
 
1497
    STATUS_VAR current_global_status_var;
 
1498
    ulong uptime;
 
1499
    uint length;
 
1500
    ulonglong queries_per_second1000;
 
1501
    char buff[250];
 
1502
    uint buff_len= sizeof(buff);
 
1503
 
 
1504
    general_log_print(thd, command, NullS);
 
1505
    status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
 
1506
    calc_sum_of_all_status(&current_global_status_var);
 
1507
    if (!(uptime= (ulong) (thd->start_time - server_start_time)))
 
1508
      queries_per_second1000= 0;
 
1509
    else
 
1510
      queries_per_second1000= thd->query_id * LL(1000) / uptime;
 
1511
 
 
1512
    length= my_snprintf((char*) buff, buff_len - 1,
 
1513
                        "Uptime: %lu  Threads: %d  Questions: %lu  "
 
1514
                        "Slow queries: %lu  Opens: %lu  Flush tables: %lu  "
 
1515
                        "Open tables: %u  Queries per second avg: %u.%u",
 
1516
                        uptime,
 
1517
                        (int) thread_count, (ulong) thd->query_id,
 
1518
                        current_global_status_var.long_query_count,
 
1519
                        current_global_status_var.opened_tables,
 
1520
                        refresh_version,
 
1521
                        cached_open_tables(),
 
1522
                        (uint) (queries_per_second1000 / 1000),
 
1523
                        (uint) (queries_per_second1000 % 1000));
 
1524
#ifdef EMBEDDED_LIBRARY
 
1525
    /* Store the buffer in permanent memory */
 
1526
    my_ok(thd, 0, 0, buff);
 
1527
#endif
 
1528
#ifdef SAFEMALLOC
 
1529
    if (sf_malloc_cur_memory)                           // Using SAFEMALLOC
 
1530
    {
 
1531
      char *end= buff + length;
 
1532
      length+= my_snprintf(end, buff_len - length - 1,
 
1533
                           end,"  Memory in use: %ldK  Max memory used: %ldK",
 
1534
                           (sf_malloc_cur_memory+1023L)/1024L,
 
1535
                           (sf_malloc_max_memory+1023L)/1024L);
 
1536
    }
 
1537
#endif
 
1538
#ifndef EMBEDDED_LIBRARY
 
1539
    VOID(my_net_write(net, (uchar*) buff, length));
 
1540
    VOID(net_flush(net));
 
1541
    thd->main_da.disable_status();
 
1542
#endif
 
1543
    break;
 
1544
  }
 
1545
  case COM_PING:
 
1546
    status_var_increment(thd->status_var.com_other);
 
1547
    my_ok(thd);                         // Tell client we are alive
 
1548
    break;
 
1549
  case COM_PROCESS_INFO:
 
1550
    status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
 
1551
    if (!thd->security_ctx->priv_user[0] &&
 
1552
        check_global_access(thd, PROCESS_ACL))
 
1553
      break;
 
1554
    general_log_print(thd, command, NullS);
 
1555
    mysqld_list_processes(thd,
 
1556
                          thd->security_ctx->master_access & PROCESS_ACL ? 
 
1557
                          NullS : thd->security_ctx->priv_user, 0);
 
1558
    break;
 
1559
  case COM_PROCESS_KILL:
 
1560
  {
 
1561
    status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
 
1562
    ulong id=(ulong) uint4korr(packet);
 
1563
    sql_kill(thd,id,false);
 
1564
    break;
 
1565
  }
 
1566
  case COM_SET_OPTION:
 
1567
  {
 
1568
    status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
 
1569
    uint opt_command= uint2korr(packet);
 
1570
 
 
1571
    switch (opt_command) {
 
1572
    case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
 
1573
      thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
 
1574
      my_eof(thd);
 
1575
      break;
 
1576
    case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
 
1577
      thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
 
1578
      my_eof(thd);
 
1579
      break;
 
1580
    default:
 
1581
      my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1582
      break;
 
1583
    }
 
1584
    break;
 
1585
  }
 
1586
  case COM_DEBUG:
 
1587
    status_var_increment(thd->status_var.com_other);
 
1588
    if (check_global_access(thd, SUPER_ACL))
 
1589
      break;                                    /* purecov: inspected */
 
1590
    mysql_print_status();
 
1591
    general_log_print(thd, command, NullS);
 
1592
    my_eof(thd);
 
1593
    break;
 
1594
  case COM_SLEEP:
 
1595
  case COM_CONNECT:                             // Impossible here
 
1596
  case COM_TIME:                                // Impossible from client
 
1597
  case COM_DELAYED_INSERT:
 
1598
  case COM_END:
 
1599
  default:
 
1600
    my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
1601
    break;
 
1602
  }
 
1603
 
 
1604
  /* report error issued during command execution */
 
1605
  if (thd->killed_errno())
 
1606
  {
 
1607
    if (! thd->main_da.is_set())
 
1608
      thd->send_kill_message();
 
1609
  }
 
1610
  if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
 
1611
  {
 
1612
    thd->killed= THD::NOT_KILLED;
 
1613
    thd->mysys_var->abort= 0;
 
1614
  }
 
1615
 
 
1616
  /* If commit fails, we should be able to reset the OK status. */
 
1617
  thd->main_da.can_overwrite_status= TRUE;
 
1618
  ha_autocommit_or_rollback(thd, thd->is_error());
 
1619
  thd->main_da.can_overwrite_status= FALSE;
 
1620
 
 
1621
  thd->transaction.stmt.reset();
 
1622
 
 
1623
  net_end_statement(thd);
 
1624
  query_cache_end_of_result(thd);
 
1625
 
 
1626
  thd->proc_info= "closing tables";
 
1627
  /* Free tables */
 
1628
  close_thread_tables(thd);
 
1629
 
 
1630
  log_slow_statement(thd);
 
1631
 
 
1632
  thd_proc_info(thd, "cleaning up");
 
1633
  thd->set_query(NULL, 0);
 
1634
  thd->command=COM_SLEEP;
 
1635
  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
 
1636
  thread_running--;
 
1637
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
1638
  thd_proc_info(thd, 0);
 
1639
  thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
 
1640
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
1641
  DBUG_RETURN(error);
 
1642
}
 
1643
 
 
1644
 
 
1645
void log_slow_statement(THD *thd)
 
1646
{
 
1647
  DBUG_ENTER("log_slow_statement");
 
1648
 
 
1649
  /*
 
1650
    The following should never be true with our current code base,
 
1651
    but better to keep this here so we don't accidently try to log a
 
1652
    statement in a trigger or stored function
 
1653
  */
 
1654
  if (unlikely(thd->in_sub_stmt))
 
1655
    DBUG_VOID_RETURN;                           // Don't set time for sub stmt
 
1656
 
 
1657
  /*
 
1658
    Do not log administrative statements unless the appropriate option is
 
1659
    set.
 
1660
  */
 
1661
  if (thd->enable_slow_log)
 
1662
  {
 
1663
    ulonglong end_utime_of_query= thd->current_utime();
 
1664
    thd_proc_info(thd, "logging slow query");
 
1665
 
 
1666
    if (((end_utime_of_query - thd->utime_after_lock) >
 
1667
         thd->variables.long_query_time ||
 
1668
         ((thd->server_status &
 
1669
           (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
 
1670
          opt_log_queries_not_using_indexes &&
 
1671
           !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
 
1672
        thd->examined_row_count >= thd->variables.min_examined_row_limit)
 
1673
    {
 
1674
      thd_proc_info(thd, "logging slow query");
 
1675
      thd->status_var.long_query_count++;
 
1676
      slow_log_print(thd, thd->query(), thd->query_length(), 
 
1677
                     end_utime_of_query);
 
1678
    }
 
1679
  }
 
1680
  DBUG_VOID_RETURN;
 
1681
}
 
1682
 
 
1683
 
 
1684
/**
 
1685
  Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
 
1686
 
 
1687
    This function is used in the parser to convert a SHOW or DESCRIBE
 
1688
    table_name command to a SELECT from INFORMATION_SCHEMA.
 
1689
    It prepares a SELECT_LEX and a TABLE_LIST object to represent the
 
1690
    given command as a SELECT parse tree.
 
1691
 
 
1692
  @param thd              thread handle
 
1693
  @param lex              current lex
 
1694
  @param table_ident      table alias if it's used
 
1695
  @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
 
1696
                          created
 
1697
 
 
1698
  @note
 
1699
    Due to the way this function works with memory and LEX it cannot
 
1700
    be used outside the parser (parse tree transformations outside
 
1701
    the parser break PS and SP).
 
1702
 
 
1703
  @retval
 
1704
    0                 success
 
1705
  @retval
 
1706
    1                 out of memory or SHOW commands are not allowed
 
1707
                      in this version of the server.
 
1708
*/
 
1709
 
 
1710
int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
 
1711
                         enum enum_schema_tables schema_table_idx)
 
1712
{
 
1713
  SELECT_LEX *schema_select_lex= NULL;
 
1714
  DBUG_ENTER("prepare_schema_table");
 
1715
 
 
1716
  switch (schema_table_idx) {
 
1717
  case SCH_SCHEMATA:
 
1718
#if defined(DONT_ALLOW_SHOW_COMMANDS)
 
1719
    my_message(ER_NOT_ALLOWED_COMMAND,
 
1720
               ER(ER_NOT_ALLOWED_COMMAND), MYF(0));   /* purecov: inspected */
 
1721
    DBUG_RETURN(1);
 
1722
#else
 
1723
    break;
 
1724
#endif
 
1725
 
 
1726
  case SCH_TABLE_NAMES:
 
1727
  case SCH_TABLES:
 
1728
  case SCH_VIEWS:
 
1729
  case SCH_TRIGGERS:
 
1730
  case SCH_EVENTS:
 
1731
#ifdef DONT_ALLOW_SHOW_COMMANDS
 
1732
    my_message(ER_NOT_ALLOWED_COMMAND,
 
1733
               ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
 
1734
    DBUG_RETURN(1);
 
1735
#else
 
1736
    {
 
1737
      LEX_STRING db;
 
1738
      size_t dummy;
 
1739
      if (lex->select_lex.db == NULL &&
 
1740
          lex->copy_db_to(&lex->select_lex.db, &dummy))
 
1741
      {
 
1742
        DBUG_RETURN(1);
 
1743
      }
 
1744
      schema_select_lex= new SELECT_LEX();
 
1745
      db.str= schema_select_lex->db= lex->select_lex.db;
 
1746
      schema_select_lex->table_list.first= NULL;
 
1747
      db.length= strlen(db.str);
 
1748
 
 
1749
      if (check_db_name(&db))
 
1750
      {
 
1751
        my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
1752
        DBUG_RETURN(1);
 
1753
      }
 
1754
      break;
 
1755
    }
 
1756
#endif
 
1757
  case SCH_COLUMNS:
 
1758
  case SCH_STATISTICS:
 
1759
  {
 
1760
#ifdef DONT_ALLOW_SHOW_COMMANDS
 
1761
    my_message(ER_NOT_ALLOWED_COMMAND,
 
1762
               ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
 
1763
    DBUG_RETURN(1);
 
1764
#else
 
1765
    DBUG_ASSERT(table_ident);
 
1766
    TABLE_LIST **query_tables_last= lex->query_tables_last;
 
1767
    schema_select_lex= new SELECT_LEX();
 
1768
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
1769
    schema_select_lex->parent_lex= lex;
 
1770
    schema_select_lex->init_query();
 
1771
    if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
 
1772
      DBUG_RETURN(1);
 
1773
    lex->query_tables_last= query_tables_last;
 
1774
    break;
 
1775
  }
 
1776
#endif
 
1777
  case SCH_PROFILES:
 
1778
    /* 
 
1779
      Mark this current profiling record to be discarded.  We don't
 
1780
      wish to have SHOW commands show up in profiling.
 
1781
    */
 
1782
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
1783
    thd->profiling.discard_current_query();
 
1784
#endif
 
1785
    break;
 
1786
  case SCH_OPEN_TABLES:
 
1787
  case SCH_VARIABLES:
 
1788
  case SCH_STATUS:
 
1789
  case SCH_PROCEDURES:
 
1790
  case SCH_CHARSETS:
 
1791
  case SCH_ENGINES:
 
1792
  case SCH_COLLATIONS:
 
1793
  case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
 
1794
  case SCH_USER_PRIVILEGES:
 
1795
  case SCH_SCHEMA_PRIVILEGES:
 
1796
  case SCH_TABLE_PRIVILEGES:
 
1797
  case SCH_COLUMN_PRIVILEGES:
 
1798
  case SCH_TABLE_CONSTRAINTS:
 
1799
  case SCH_KEY_COLUMN_USAGE:
 
1800
  default:
 
1801
    break;
 
1802
  }
 
1803
  
 
1804
  SELECT_LEX *select_lex= lex->current_select;
 
1805
  if (make_schema_select(thd, select_lex, schema_table_idx))
 
1806
  {
 
1807
    DBUG_RETURN(1);
 
1808
  }
 
1809
  TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
 
1810
  table_list->schema_select_lex= schema_select_lex;
 
1811
  table_list->schema_table_reformed= 1;
 
1812
  DBUG_RETURN(0);
 
1813
}
 
1814
 
 
1815
 
 
1816
/**
 
1817
  Read query from packet and store in thd->query.
 
1818
  Used in COM_QUERY and COM_STMT_PREPARE.
 
1819
 
 
1820
    Sets the following THD variables:
 
1821
  - query
 
1822
  - query_length
 
1823
 
 
1824
  @retval
 
1825
    FALSE ok
 
1826
  @retval
 
1827
    TRUE  error;  In this case thd->fatal_error is set
 
1828
*/
 
1829
 
 
1830
bool alloc_query(THD *thd, const char *packet, uint packet_length)
 
1831
{
 
1832
  char *query;
 
1833
  /* Remove garbage at start and end of query */
 
1834
  while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
 
1835
  {
 
1836
    packet++;
 
1837
    packet_length--;
 
1838
  }
 
1839
  const char *pos= packet + packet_length;     // Point at end null
 
1840
  while (packet_length > 0 &&
 
1841
         (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
 
1842
  {
 
1843
    pos--;
 
1844
    packet_length--;
 
1845
  }
 
1846
  /* We must allocate some extra memory for query cache */
 
1847
  if (! (query= (char*) thd->memdup_w_gap(packet,
 
1848
                                          packet_length,
 
1849
                                          1 + thd->db_length +
 
1850
                                          QUERY_CACHE_FLAGS_SIZE)))
 
1851
      return TRUE;
 
1852
  query[packet_length]= '\0';
 
1853
  thd->set_query(query, packet_length);
 
1854
 
 
1855
  /* Reclaim some memory */
 
1856
  thd->packet.shrink(thd->variables.net_buffer_length);
 
1857
  thd->convert_buffer.shrink(thd->variables.net_buffer_length);
 
1858
 
 
1859
  return FALSE;
 
1860
}
 
1861
 
 
1862
static void reset_one_shot_variables(THD *thd) 
 
1863
{
 
1864
  thd->variables.character_set_client=
 
1865
    global_system_variables.character_set_client;
 
1866
  thd->variables.collation_connection=
 
1867
    global_system_variables.collation_connection;
 
1868
  thd->variables.collation_database=
 
1869
    global_system_variables.collation_database;
 
1870
  thd->variables.collation_server=
 
1871
    global_system_variables.collation_server;
 
1872
  thd->update_charset();
 
1873
  thd->variables.time_zone=
 
1874
    global_system_variables.time_zone;
 
1875
  thd->variables.lc_time_names= &my_locale_en_US;
 
1876
  thd->one_shot_set= 0;
 
1877
}
 
1878
 
 
1879
 
 
1880
static
 
1881
bool sp_process_definer(THD *thd)
 
1882
{
 
1883
  DBUG_ENTER("sp_process_definer");
 
1884
 
 
1885
  LEX *lex= thd->lex;
 
1886
 
 
1887
  /*
 
1888
    If the definer is not specified, this means that CREATE-statement missed
 
1889
    DEFINER-clause. DEFINER-clause can be missed in two cases:
 
1890
 
 
1891
      - The user submitted a statement w/o the clause. This is a normal
 
1892
        case, we should assign CURRENT_USER as definer.
 
1893
 
 
1894
      - Our slave received an updated from the master, that does not
 
1895
        replicate definer for stored rountines. We should also assign
 
1896
        CURRENT_USER as definer here, but also we should mark this routine
 
1897
        as NON-SUID. This is essential for the sake of backward
 
1898
        compatibility.
 
1899
 
 
1900
        The problem is the slave thread is running under "special" user (@),
 
1901
        that actually does not exist. In the older versions we do not fail
 
1902
        execution of a stored routine if its definer does not exist and
 
1903
        continue the execution under the authorization of the invoker
 
1904
        (BUG#13198). And now if we try to switch to slave-current-user (@),
 
1905
        we will fail.
 
1906
 
 
1907
        Actually, this leads to the inconsistent state of master and
 
1908
        slave (different definers, different SUID behaviour), but it seems,
 
1909
        this is the best we can do.
 
1910
  */
 
1911
 
 
1912
  if (!lex->definer)
 
1913
  {
 
1914
    Query_arena original_arena;
 
1915
    Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
 
1916
 
 
1917
    lex->definer= create_default_definer(thd);
 
1918
 
 
1919
    if (ps_arena)
 
1920
      thd->restore_active_arena(ps_arena, &original_arena);
 
1921
 
 
1922
    /* Error has been already reported. */
 
1923
    if (lex->definer == NULL)
 
1924
      DBUG_RETURN(TRUE);
 
1925
 
 
1926
    if (thd->slave_thread && lex->sphead)
 
1927
      lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
 
1928
  }
 
1929
  else
 
1930
  {
 
1931
    /*
 
1932
      If the specified definer differs from the current user, we
 
1933
      should check that the current user has SUPER privilege (in order
 
1934
      to create a stored routine under another user one must have
 
1935
      SUPER privilege).
 
1936
    */
 
1937
    if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
 
1938
         my_strcasecmp(system_charset_info, lex->definer->host.str,
 
1939
                       thd->security_ctx->priv_host)) &&
 
1940
        check_global_access(thd, SUPER_ACL))
 
1941
    {
 
1942
      my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
 
1943
      DBUG_RETURN(TRUE);
 
1944
    }
 
1945
  }
 
1946
 
 
1947
  /* Check that the specified definer exists. Emit a warning if not. */
 
1948
 
 
1949
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
1950
  if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
 
1951
  {
 
1952
    push_warning_printf(thd,
 
1953
                        MYSQL_ERROR::WARN_LEVEL_NOTE,
 
1954
                        ER_NO_SUCH_USER,
 
1955
                        ER(ER_NO_SUCH_USER),
 
1956
                        lex->definer->user.str,
 
1957
                        lex->definer->host.str);
 
1958
  }
 
1959
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
 
1960
 
 
1961
  DBUG_RETURN(FALSE);
 
1962
}
 
1963
 
 
1964
 
 
1965
/**
 
1966
  Execute command saved in thd and lex->sql_command.
 
1967
 
 
1968
    Before every operation that can request a write lock for a table
 
1969
    wait if a global read lock exists. However do not wait if this
 
1970
    thread has locked tables already. No new locks can be requested
 
1971
    until the other locks are released. The thread that requests the
 
1972
    global read lock waits for write locked tables to become unlocked.
 
1973
 
 
1974
    Note that wait_if_global_read_lock() sets a protection against a new
 
1975
    global read lock when it succeeds. This needs to be released by
 
1976
    start_waiting_global_read_lock() after the operation.
 
1977
 
 
1978
  @param thd                       Thread handle
 
1979
 
 
1980
  @todo
 
1981
    - Invalidate the table in the query cache if something changed
 
1982
    after unlocking when changes become visible.
 
1983
    TODO: this is workaround. right way will be move invalidating in
 
1984
    the unlock procedure.
 
1985
    - TODO: use check_change_password()
 
1986
    - JOIN is not supported yet. TODO
 
1987
    - SUSPEND and FOR MIGRATE are not supported yet. TODO
 
1988
 
 
1989
  @retval
 
1990
    FALSE       OK
 
1991
  @retval
 
1992
    TRUE        Error
 
1993
*/
 
1994
 
 
1995
int
 
1996
mysql_execute_command(THD *thd)
 
1997
{
 
1998
  int res= FALSE;
 
1999
  bool need_start_waiting= FALSE; // have protection against global read lock
 
2000
  int  up_result= 0;
 
2001
  LEX  *lex= thd->lex;
 
2002
  /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
 
2003
  SELECT_LEX *select_lex= &lex->select_lex;
 
2004
  /* first table of first SELECT_LEX */
 
2005
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
 
2006
  /* list of all tables in query */
 
2007
  TABLE_LIST *all_tables;
 
2008
  /* most outer SELECT_LEX_UNIT of query */
 
2009
  SELECT_LEX_UNIT *unit= &lex->unit;
 
2010
#ifdef HAVE_REPLICATION
 
2011
  /* have table map for update for multi-update statement (BUG#37051) */
 
2012
  bool have_table_map_for_update= FALSE;
 
2013
#endif
 
2014
  /* Saved variable value */
 
2015
  DBUG_ENTER("mysql_execute_command");
 
2016
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
2017
  thd->work_part_info= 0;
 
2018
#endif
 
2019
 
 
2020
  /*
 
2021
    In many cases first table of main SELECT_LEX have special meaning =>
 
2022
    check that it is first table in global list and relink it first in 
 
2023
    queries_tables list if it is necessary (we need such relinking only
 
2024
    for queries with subqueries in select list, in this case tables of
 
2025
    subqueries will go to global list first)
 
2026
 
 
2027
    all_tables will differ from first_table only if most upper SELECT_LEX
 
2028
    do not contain tables.
 
2029
 
 
2030
    Because of above in place where should be at least one table in most
 
2031
    outer SELECT_LEX we have following check:
 
2032
    DBUG_ASSERT(first_table == all_tables);
 
2033
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2034
  */
 
2035
  lex->first_lists_tables_same();
 
2036
  /* should be assigned after making first tables same */
 
2037
  all_tables= lex->query_tables;
 
2038
  /* set context for commands which do not use setup_tables */
 
2039
  select_lex->
 
2040
    context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
 
2041
                                       table_list.first);
 
2042
 
 
2043
  /*
 
2044
    Reset warning count for each query that uses tables
 
2045
    A better approach would be to reset this for any commands
 
2046
    that is not a SHOW command or a select that only access local
 
2047
    variables, but for now this is probably good enough.
 
2048
    Don't reset warnings when executing a stored routine.
 
2049
  */
 
2050
  if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont)
 
2051
    mysql_reset_errors(thd, 0);
 
2052
 
 
2053
#ifdef HAVE_REPLICATION
 
2054
  if (unlikely(thd->slave_thread))
 
2055
  {
 
2056
    if (lex->sql_command == SQLCOM_DROP_TRIGGER)
 
2057
    {
 
2058
      /*
 
2059
        When dropping a trigger, we need to load its table name
 
2060
        before checking slave filter rules.
 
2061
      */
 
2062
      add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
 
2063
      
 
2064
      if (!all_tables)
 
2065
      {
 
2066
        /*
 
2067
          If table name cannot be loaded,
 
2068
          it means the trigger does not exists possibly because
 
2069
          CREATE TRIGGER was previously skipped for this trigger
 
2070
          according to slave filtering rules.
 
2071
          Returning success without producing any errors in this case.
 
2072
        */
 
2073
        DBUG_RETURN(0);
 
2074
      }
 
2075
      
 
2076
      // force searching in slave.cc:tables_ok() 
 
2077
      all_tables->updating= 1;
 
2078
    }
 
2079
 
 
2080
    /*
 
2081
      For fix of BUG#37051, the master stores the table map for update
 
2082
      in the Query_log_event, and the value is assigned to
 
2083
      thd->variables.table_map_for_update before executing the update
 
2084
      query.
 
2085
 
 
2086
      If thd->variables.table_map_for_update is set, then we are
 
2087
      replicating from a new master, we can use this value to apply
 
2088
      filter rules without opening all the tables. However If
 
2089
      thd->variables.table_map_for_update is not set, then we are
 
2090
      replicating from an old master, so we just skip this and
 
2091
      continue with the old method. And of course, the bug would still
 
2092
      exist for old masters.
 
2093
    */
 
2094
    if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
 
2095
        thd->table_map_for_update)
 
2096
    {
 
2097
      have_table_map_for_update= TRUE;
 
2098
      table_map table_map_for_update= thd->table_map_for_update;
 
2099
      uint nr= 0;
 
2100
      TABLE_LIST *table;
 
2101
      for (table=all_tables; table; table=table->next_global, nr++)
 
2102
      {
 
2103
        if (table_map_for_update & ((table_map)1 << nr))
 
2104
          table->updating= TRUE;
 
2105
        else
 
2106
          table->updating= FALSE;
 
2107
      }
 
2108
 
 
2109
      if (all_tables_not_ok(thd, all_tables))
 
2110
      {
 
2111
        /* we warn the slave SQL thread */
 
2112
        my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
2113
        if (thd->one_shot_set)
 
2114
          reset_one_shot_variables(thd);
 
2115
        DBUG_RETURN(0);
 
2116
      }
 
2117
      
 
2118
      for (table=all_tables; table; table=table->next_global)
 
2119
        table->updating= TRUE;
 
2120
    }
 
2121
    
 
2122
    /*
 
2123
      Check if statment should be skipped because of slave filtering
 
2124
      rules
 
2125
 
 
2126
      Exceptions are:
 
2127
      - UPDATE MULTI: For this statement, we want to check the filtering
 
2128
        rules later in the code
 
2129
      - SET: we always execute it (Not that many SET commands exists in
 
2130
        the binary log anyway -- only 4.1 masters write SET statements,
 
2131
        in 5.0 there are no SET statements in the binary log)
 
2132
      - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
 
2133
        have stale files on slave caused by exclusion of one tmp table).
 
2134
    */
 
2135
    if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
 
2136
        !(lex->sql_command == SQLCOM_SET_OPTION) &&
 
2137
        !(lex->sql_command == SQLCOM_DROP_TABLE &&
 
2138
          lex->drop_temporary && lex->drop_if_exists) &&
 
2139
        all_tables_not_ok(thd, all_tables))
 
2140
    {
 
2141
      /* we warn the slave SQL thread */
 
2142
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
2143
      if (thd->one_shot_set)
 
2144
      {
 
2145
        /*
 
2146
          It's ok to check thd->one_shot_set here:
 
2147
 
 
2148
          The charsets in a MySQL 5.0 slave can change by both a binlogged
 
2149
          SET ONE_SHOT statement and the event-internal charset setting, 
 
2150
          and these two ways to change charsets do not seems to work
 
2151
          together.
 
2152
 
 
2153
          At least there seems to be problems in the rli cache for
 
2154
          charsets if we are using ONE_SHOT.  Note that this is normally no
 
2155
          problem because either the >= 5.0 slave reads a 4.1 binlog (with
 
2156
          ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
 
2157
        */
 
2158
        reset_one_shot_variables(thd);
 
2159
      }
 
2160
      DBUG_RETURN(0);
 
2161
    }
 
2162
  }
 
2163
  else
 
2164
  {
 
2165
#endif /* HAVE_REPLICATION */
 
2166
    /*
 
2167
      When option readonly is set deny operations which change non-temporary
 
2168
      tables. Except for the replication thread and the 'super' users.
 
2169
    */
 
2170
    if (deny_updates_if_read_only_option(thd, all_tables))
 
2171
    {
 
2172
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
 
2173
      DBUG_RETURN(-1);
 
2174
    }
 
2175
#ifdef HAVE_REPLICATION
 
2176
  } /* endif unlikely slave */
 
2177
#endif
 
2178
  status_var_increment(thd->status_var.com_stat[lex->sql_command]);
 
2179
 
 
2180
  DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
 
2181
  
 
2182
  switch (lex->sql_command) {
 
2183
 
 
2184
  case SQLCOM_SHOW_EVENTS:
 
2185
#ifndef HAVE_EVENT_SCHEDULER
 
2186
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
 
2187
    break;
 
2188
#endif
 
2189
  case SQLCOM_SHOW_STATUS_PROC:
 
2190
  case SQLCOM_SHOW_STATUS_FUNC:
 
2191
    if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
 
2192
      res= execute_sqlcom_select(thd, all_tables);
 
2193
    break;
 
2194
  case SQLCOM_SHOW_STATUS:
 
2195
  {
 
2196
    system_status_var old_status_var= thd->status_var;
 
2197
    thd->initial_status_var= &old_status_var;
 
2198
    if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
 
2199
      res= execute_sqlcom_select(thd, all_tables);
 
2200
    /* Don't log SHOW STATUS commands to slow query log */
 
2201
    thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
 
2202
                           SERVER_QUERY_NO_GOOD_INDEX_USED);
 
2203
    /*
 
2204
      restore status variables, as we don't want 'show status' to cause
 
2205
      changes
 
2206
    */
 
2207
    pthread_mutex_lock(&LOCK_status);
 
2208
    add_diff_to_status(&global_status_var, &thd->status_var,
 
2209
                       &old_status_var);
 
2210
    thd->status_var= old_status_var;
 
2211
    pthread_mutex_unlock(&LOCK_status);
 
2212
    break;
 
2213
  }
 
2214
  case SQLCOM_SHOW_DATABASES:
 
2215
  case SQLCOM_SHOW_TABLES:
 
2216
  case SQLCOM_SHOW_TRIGGERS:
 
2217
  case SQLCOM_SHOW_TABLE_STATUS:
 
2218
  case SQLCOM_SHOW_OPEN_TABLES:
 
2219
  case SQLCOM_SHOW_PLUGINS:
 
2220
  case SQLCOM_SHOW_FIELDS:
 
2221
  case SQLCOM_SHOW_KEYS:
 
2222
  case SQLCOM_SHOW_VARIABLES:
 
2223
  case SQLCOM_SHOW_CHARSETS:
 
2224
  case SQLCOM_SHOW_COLLATIONS:
 
2225
  case SQLCOM_SHOW_STORAGE_ENGINES:
 
2226
  case SQLCOM_SHOW_PROFILE:
 
2227
  case SQLCOM_SELECT:
 
2228
    thd->status_var.last_query_cost= 0.0;
 
2229
    if (all_tables)
 
2230
    {
 
2231
      res= check_table_access(thd,
 
2232
                              lex->exchange ? SELECT_ACL | FILE_ACL :
 
2233
                              SELECT_ACL,
 
2234
                              all_tables, UINT_MAX, FALSE);
 
2235
    }
 
2236
    else
 
2237
      res= check_access(thd,
 
2238
                        lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
 
2239
                        any_db, 0, 0, 0, 0);
 
2240
 
 
2241
    if (res)
 
2242
      break;
 
2243
 
 
2244
    if (!thd->locked_tables && lex->protect_against_global_read_lock &&
 
2245
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
2246
      break;
 
2247
 
 
2248
    res= execute_sqlcom_select(thd, all_tables);
 
2249
    break;
 
2250
  case SQLCOM_PREPARE:
 
2251
  {
 
2252
    mysql_sql_stmt_prepare(thd);
 
2253
    break;
 
2254
  }
 
2255
  case SQLCOM_EXECUTE:
 
2256
  {
 
2257
    mysql_sql_stmt_execute(thd);
 
2258
    break;
 
2259
  }
 
2260
  case SQLCOM_DEALLOCATE_PREPARE:
 
2261
  {
 
2262
    mysql_sql_stmt_close(thd);
 
2263
    break;
 
2264
  }
 
2265
  case SQLCOM_DO:
 
2266
    if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
 
2267
        open_and_lock_tables(thd, all_tables))
 
2268
      goto error;
 
2269
 
 
2270
    res= mysql_do(thd, *lex->insert_list);
 
2271
    break;
 
2272
 
 
2273
  case SQLCOM_EMPTY_QUERY:
 
2274
    my_ok(thd);
 
2275
    break;
 
2276
 
 
2277
  case SQLCOM_HELP:
 
2278
    res= mysqld_help(thd,lex->help_arg);
 
2279
    break;
 
2280
 
 
2281
#ifndef EMBEDDED_LIBRARY
 
2282
  case SQLCOM_PURGE:
 
2283
  {
 
2284
    if (check_global_access(thd, SUPER_ACL))
 
2285
      goto error;
 
2286
    /* PURGE MASTER LOGS TO 'file' */
 
2287
    res = purge_master_logs(thd, lex->to_log);
 
2288
    break;
 
2289
  }
 
2290
  case SQLCOM_PURGE_BEFORE:
 
2291
  {
 
2292
    Item *it;
 
2293
 
 
2294
    if (check_global_access(thd, SUPER_ACL))
 
2295
      goto error;
 
2296
    /* PURGE MASTER LOGS BEFORE 'data' */
 
2297
    it= (Item *)lex->value_list.head();
 
2298
    if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
 
2299
        it->check_cols(1))
 
2300
    {
 
2301
      my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
 
2302
      goto error;
 
2303
    }
 
2304
    it= new Item_func_unix_timestamp(it);
 
2305
    /*
 
2306
      it is OK only emulate fix_fieds, because we need only
 
2307
      value of constant
 
2308
    */
 
2309
    it->quick_fix_field();
 
2310
    res = purge_master_logs_before_date(thd, (ulong)it->val_int());
 
2311
    break;
 
2312
  }
 
2313
#endif
 
2314
  case SQLCOM_SHOW_WARNS:
 
2315
  {
 
2316
    res= mysqld_show_warnings(thd, (ulong)
 
2317
                              ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) |
 
2318
                               (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) |
 
2319
                               (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)
 
2320
                               ));
 
2321
    break;
 
2322
  }
 
2323
  case SQLCOM_SHOW_ERRORS:
 
2324
  {
 
2325
    res= mysqld_show_warnings(thd, (ulong)
 
2326
                              (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
 
2327
    break;
 
2328
  }
 
2329
  case SQLCOM_SHOW_PROFILES:
 
2330
  {
 
2331
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
 
2332
    thd->profiling.discard_current_query();
 
2333
    res= thd->profiling.show_profiles();
 
2334
    if (res)
 
2335
      goto error;
 
2336
#else
 
2337
    my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
 
2338
    goto error;
 
2339
#endif
 
2340
    break;
 
2341
  }
 
2342
  case SQLCOM_SHOW_NEW_MASTER:
 
2343
  {
 
2344
    if (check_global_access(thd, REPL_SLAVE_ACL))
 
2345
      goto error;
 
2346
    /* This query don't work now. See comment in repl_failsafe.cc */
 
2347
#ifndef WORKING_NEW_MASTER
 
2348
    my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER");
 
2349
    goto error;
 
2350
#else
 
2351
    res = show_new_master(thd);
 
2352
    break;
 
2353
#endif
 
2354
  }
 
2355
 
 
2356
#ifdef HAVE_REPLICATION
 
2357
  case SQLCOM_SHOW_SLAVE_HOSTS:
 
2358
  {
 
2359
    if (check_global_access(thd, REPL_SLAVE_ACL))
 
2360
      goto error;
 
2361
    res = show_slave_hosts(thd);
 
2362
    break;
 
2363
  }
 
2364
  case SQLCOM_SHOW_BINLOG_EVENTS:
 
2365
  {
 
2366
    if (check_global_access(thd, REPL_SLAVE_ACL))
 
2367
      goto error;
 
2368
    res = mysql_show_binlog_events(thd);
 
2369
    break;
 
2370
  }
 
2371
#endif
 
2372
 
 
2373
  case SQLCOM_BACKUP_TABLE:
 
2374
  {
 
2375
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2376
    if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
 
2377
        check_global_access(thd, FILE_ACL))
 
2378
      goto error; /* purecov: inspected */
 
2379
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
2380
    res = mysql_backup_table(thd, first_table);
 
2381
    select_lex->table_list.first= (uchar*) first_table;
 
2382
    lex->query_tables=all_tables;
 
2383
    break;
 
2384
  }
 
2385
  case SQLCOM_RESTORE_TABLE:
 
2386
  {
 
2387
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2388
    if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) ||
 
2389
        check_global_access(thd, FILE_ACL))
 
2390
      goto error; /* purecov: inspected */
 
2391
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
2392
    res = mysql_restore_table(thd, first_table);
 
2393
    select_lex->table_list.first= (uchar*) first_table;
 
2394
    lex->query_tables=all_tables;
 
2395
    break;
 
2396
  }
 
2397
  case SQLCOM_ASSIGN_TO_KEYCACHE:
 
2398
  {
 
2399
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2400
    if (check_access(thd, INDEX_ACL, first_table->db,
 
2401
                     &first_table->grant.privilege, 0, 0,
 
2402
                     test(first_table->schema_table)))
 
2403
      goto error;
 
2404
    res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
 
2405
    break;
 
2406
  }
 
2407
  case SQLCOM_PRELOAD_KEYS:
 
2408
  {
 
2409
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2410
    if (check_access(thd, INDEX_ACL, first_table->db,
 
2411
                     &first_table->grant.privilege, 0, 0,
 
2412
                     test(first_table->schema_table)))
 
2413
      goto error;
 
2414
    res = mysql_preload_keys(thd, first_table);
 
2415
    break;
 
2416
  }
 
2417
#ifdef HAVE_REPLICATION
 
2418
  case SQLCOM_CHANGE_MASTER:
 
2419
  {
 
2420
    if (check_global_access(thd, SUPER_ACL))
 
2421
      goto error;
 
2422
    pthread_mutex_lock(&LOCK_active_mi);
 
2423
    res = change_master(thd,active_mi);
 
2424
    pthread_mutex_unlock(&LOCK_active_mi);
 
2425
    break;
 
2426
  }
 
2427
  case SQLCOM_SHOW_SLAVE_STAT:
 
2428
  {
 
2429
    /* Accept one of two privileges */
 
2430
    if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
 
2431
      goto error;
 
2432
    pthread_mutex_lock(&LOCK_active_mi);
 
2433
    if (active_mi != NULL)
 
2434
    {
 
2435
      res = show_master_info(thd, active_mi);
 
2436
    }
 
2437
    else
 
2438
    {
 
2439
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2440
                   WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
 
2441
      my_ok(thd);
 
2442
    }
 
2443
    pthread_mutex_unlock(&LOCK_active_mi);
 
2444
    break;
 
2445
  }
 
2446
  case SQLCOM_SHOW_MASTER_STAT:
 
2447
  {
 
2448
    /* Accept one of two privileges */
 
2449
    if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
 
2450
      goto error;
 
2451
    res = show_binlog_info(thd);
 
2452
    break;
 
2453
  }
 
2454
 
 
2455
  case SQLCOM_LOAD_MASTER_DATA: // sync with master
 
2456
    if (check_global_access(thd, SUPER_ACL))
 
2457
      goto error;
 
2458
    if (end_active_trans(thd))
 
2459
      goto error;
 
2460
    res = load_master_data(thd);
 
2461
    break;
 
2462
#endif /* HAVE_REPLICATION */
 
2463
  case SQLCOM_SHOW_ENGINE_STATUS:
 
2464
    {
 
2465
      if (check_global_access(thd, PROCESS_ACL))
 
2466
        goto error;
 
2467
      res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
 
2468
      break;
 
2469
    }
 
2470
  case SQLCOM_SHOW_ENGINE_MUTEX:
 
2471
    {
 
2472
      if (check_global_access(thd, PROCESS_ACL))
 
2473
        goto error;
 
2474
      res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
 
2475
      break;
 
2476
    }
 
2477
#ifdef HAVE_REPLICATION
 
2478
  case SQLCOM_LOAD_MASTER_TABLE:
 
2479
  {
 
2480
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2481
    DBUG_ASSERT(first_table->db); /* Must be set in the parser */
 
2482
 
 
2483
    if (check_access(thd, CREATE_ACL, first_table->db,
 
2484
                     &first_table->grant.privilege, 0, 0,
 
2485
                     test(first_table->schema_table)))
 
2486
      goto error;                               /* purecov: inspected */
 
2487
    /* Check that the first table has CREATE privilege */
 
2488
    if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
 
2489
      goto error;
 
2490
 
 
2491
    pthread_mutex_lock(&LOCK_active_mi);
 
2492
    /*
 
2493
      fetch_master_table will send the error to the client on failure.
 
2494
      Give error if the table already exists.
 
2495
    */
 
2496
    if (!fetch_master_table(thd, first_table->db, first_table->table_name,
 
2497
                            active_mi, 0, 0))
 
2498
    {
 
2499
      my_ok(thd);
 
2500
    }
 
2501
    pthread_mutex_unlock(&LOCK_active_mi);
 
2502
    break;
 
2503
  }
 
2504
#endif /* HAVE_REPLICATION */
 
2505
 
 
2506
  case SQLCOM_CREATE_TABLE:
 
2507
  {
 
2508
    /* If CREATE TABLE of non-temporary table, do implicit commit */
 
2509
    if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
2510
    {
 
2511
      if (end_active_trans(thd))
 
2512
      {
 
2513
        res= -1;
 
2514
        break;
 
2515
      }
 
2516
    }
 
2517
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2518
    bool link_to_local;
 
2519
    // Skip first table, which is the table we are creating
 
2520
    TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
 
2521
    TABLE_LIST *select_tables= lex->query_tables;
 
2522
    /*
 
2523
      Code below (especially in mysql_create_table() and select_create
 
2524
      methods) may modify HA_CREATE_INFO structure in LEX, so we have to
 
2525
      use a copy of this structure to make execution prepared statement-
 
2526
      safe. A shallow copy is enough as this code won't modify any memory
 
2527
      referenced from this structure.
 
2528
    */
 
2529
    HA_CREATE_INFO create_info(lex->create_info);
 
2530
    /*
 
2531
      We need to copy alter_info for the same reasons of re-execution
 
2532
      safety, only in case of Alter_info we have to do (almost) a deep
 
2533
      copy.
 
2534
    */
 
2535
    Alter_info alter_info(lex->alter_info, thd->mem_root);
 
2536
 
 
2537
    if (thd->is_fatal_error)
 
2538
    {
 
2539
      /* If out of memory when creating a copy of alter_info. */
 
2540
      res= 1;
 
2541
      goto end_with_restore_list;
 
2542
    }
 
2543
 
 
2544
    if ((res= create_table_precheck(thd, select_tables, create_table)))
 
2545
      goto end_with_restore_list;
 
2546
 
 
2547
    /* Might have been updated in create_table_precheck */
 
2548
    create_info.alias= create_table->alias;
 
2549
 
 
2550
#ifdef HAVE_READLINK
 
2551
    /* Fix names if symlinked tables */
 
2552
    if (append_file_to_dir(thd, &create_info.data_file_name,
 
2553
                           create_table->table_name) ||
 
2554
        append_file_to_dir(thd, &create_info.index_file_name,
 
2555
                           create_table->table_name))
 
2556
      goto end_with_restore_list;
 
2557
#endif
 
2558
    /*
 
2559
      If we are using SET CHARSET without DEFAULT, add an implicit
 
2560
      DEFAULT to not confuse old users. (This may change).
 
2561
    */
 
2562
    if ((create_info.used_fields &
 
2563
         (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
 
2564
        HA_CREATE_USED_CHARSET)
 
2565
    {
 
2566
      create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
 
2567
      create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
 
2568
      create_info.default_table_charset= create_info.table_charset;
 
2569
      create_info.table_charset= 0;
 
2570
    }
 
2571
    /*
 
2572
      The create-select command will open and read-lock the select table
 
2573
      and then create, open and write-lock the new table. If a global
 
2574
      read lock steps in, we get a deadlock. The write lock waits for
 
2575
      the global read lock, while the global read lock waits for the
 
2576
      select table to be closed. So we wait until the global readlock is
 
2577
      gone before starting both steps. Note that
 
2578
      wait_if_global_read_lock() sets a protection against a new global
 
2579
      read lock when it succeeds. This needs to be released by
 
2580
      start_waiting_global_read_lock(). We protect the normal CREATE
 
2581
      TABLE in the same way. That way we avoid that a new table is
 
2582
      created during a gobal read lock.
 
2583
    */
 
2584
    if (!thd->locked_tables &&
 
2585
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
2586
    {
 
2587
      res= 1;
 
2588
      goto end_with_restore_list;
 
2589
    }
 
2590
#ifdef WITH_PARTITION_STORAGE_ENGINE
 
2591
    {
 
2592
      partition_info *part_info= thd->lex->part_info;
 
2593
      if (part_info && !(part_info= thd->lex->part_info->get_clone()))
 
2594
      {
 
2595
        res= -1;
 
2596
        goto end_with_restore_list;
 
2597
      }
 
2598
      thd->work_part_info= part_info;
 
2599
    }
 
2600
#endif
 
2601
    if (select_lex->item_list.elements)         // With select
 
2602
    {
 
2603
      select_result *result;
 
2604
 
 
2605
      /*
 
2606
        If:
 
2607
        a) we inside an SP and there was NAME_CONST substitution,
 
2608
        b) binlogging is on (STMT mode),
 
2609
        c) we log the SP as separate statements
 
2610
        raise a warning, as it may cause problems
 
2611
        (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
 
2612
       */
 
2613
      if (thd->query_name_consts && 
 
2614
          mysql_bin_log.is_open() &&
 
2615
          thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
 
2616
          !mysql_bin_log.is_query_in_union(thd, thd->query_id))
 
2617
      {
 
2618
        List_iterator_fast<Item> it(select_lex->item_list);
 
2619
        Item *item;
 
2620
        uint splocal_refs= 0;
 
2621
        /* Count SP local vars in the top-level SELECT list */
 
2622
        while ((item= it++))
 
2623
        {
 
2624
          if (item->is_splocal())
 
2625
            splocal_refs++;
 
2626
        }
 
2627
        /*
 
2628
          If it differs from number of NAME_CONST substitution applied,
 
2629
          we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
 
2630
          that may cause a problem with binary log (see BUG#35383),
 
2631
          raise a warning. 
 
2632
        */
 
2633
        if (splocal_refs != thd->query_name_consts)
 
2634
          push_warning(thd, 
 
2635
                       MYSQL_ERROR::WARN_LEVEL_WARN,
 
2636
                       ER_UNKNOWN_ERROR,
 
2637
"Invoked routine ran a statement that may cause problems with "
 
2638
"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
 
2639
"section of the manual.");
 
2640
      }
 
2641
      
 
2642
      select_lex->options|= SELECT_NO_UNLOCK;
 
2643
      unit->set_limit(select_lex);
 
2644
 
 
2645
      /*
 
2646
        Disable non-empty MERGE tables with CREATE...SELECT. Too
 
2647
        complicated. See Bug #26379. Empty MERGE tables are read-only
 
2648
        and don't allow CREATE...SELECT anyway.
 
2649
      */
 
2650
      if (create_info.used_fields & HA_CREATE_USED_UNION)
 
2651
      {
 
2652
        my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
 
2653
                 create_table->table_name, "BASE TABLE");
 
2654
        res= 1;
 
2655
        goto end_with_restore_list;
 
2656
      }
 
2657
 
 
2658
      if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
2659
      {
 
2660
        lex->link_first_table_back(create_table, link_to_local);
 
2661
        create_table->create= TRUE;
 
2662
        /* Base table and temporary table are not in the same name space. */
 
2663
        create_table->skip_temporary= 1;
 
2664
      }
 
2665
 
 
2666
      if (!(res= open_and_lock_tables(thd, lex->query_tables)))
 
2667
      {
 
2668
        /*
 
2669
          Is table which we are changing used somewhere in other parts
 
2670
          of query
 
2671
        */
 
2672
        if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
2673
        {
 
2674
          TABLE_LIST *duplicate;
 
2675
          create_table= lex->unlink_first_table(&link_to_local);
 
2676
          if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
 
2677
          {
 
2678
            update_non_unique_table_error(create_table, "CREATE", duplicate);
 
2679
            res= 1;
 
2680
            goto end_with_restore_list;
 
2681
          }
 
2682
        }
 
2683
        /* If we create merge table, we have to test tables in merge, too */
 
2684
        if (create_info.used_fields & HA_CREATE_USED_UNION)
 
2685
        {
 
2686
          TABLE_LIST *tab;
 
2687
          for (tab= (TABLE_LIST*) create_info.merge_list.first;
 
2688
               tab;
 
2689
               tab= tab->next_local)
 
2690
          {
 
2691
            TABLE_LIST *duplicate;
 
2692
            if ((duplicate= unique_table(thd, tab, select_tables, 0)))
 
2693
            {
 
2694
              update_non_unique_table_error(tab, "CREATE", duplicate);
 
2695
              res= 1;
 
2696
              goto end_with_restore_list;
 
2697
            }
 
2698
          }
 
2699
        }
 
2700
 
 
2701
        /*
 
2702
          select_create is currently not re-execution friendly and
 
2703
          needs to be created for every execution of a PS/SP.
 
2704
        */
 
2705
        if ((result= new select_create(create_table,
 
2706
                                       &create_info,
 
2707
                                       &alter_info,
 
2708
                                       select_lex->item_list,
 
2709
                                       lex->duplicates,
 
2710
                                       lex->ignore,
 
2711
                                       select_tables)))
 
2712
        {
 
2713
          /*
 
2714
            CREATE from SELECT give its SELECT_LEX for SELECT,
 
2715
            and item_list belong to SELECT
 
2716
          */
 
2717
          res= handle_select(thd, lex, result, 0);
 
2718
          delete result;
 
2719
        }
 
2720
      }
 
2721
      else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
 
2722
        create_table= lex->unlink_first_table(&link_to_local);
 
2723
 
 
2724
    }
 
2725
    else
 
2726
    {
 
2727
      /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
 
2728
      if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
 
2729
        thd->options|= OPTION_KEEP_LOG;
 
2730
      /* regular create */
 
2731
      if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
 
2732
        res= mysql_create_like_table(thd, create_table, select_tables,
 
2733
                                     &create_info);
 
2734
      else
 
2735
      {
 
2736
        res= mysql_create_table(thd, create_table->db,
 
2737
                                create_table->table_name, &create_info,
 
2738
                                &alter_info, 0, 0);
 
2739
      }
 
2740
      if (!res)
 
2741
        my_ok(thd);
 
2742
    }
 
2743
 
 
2744
    /* put tables back for PS rexecuting */
 
2745
end_with_restore_list:
 
2746
    lex->link_first_table_back(create_table, link_to_local);
 
2747
    break;
 
2748
  }
 
2749
  case SQLCOM_CREATE_INDEX:
 
2750
    /* Fall through */
 
2751
  case SQLCOM_DROP_INDEX:
 
2752
  /*
 
2753
    CREATE INDEX and DROP INDEX are implemented by calling ALTER
 
2754
    TABLE with proper arguments.
 
2755
 
 
2756
    In the future ALTER TABLE will notice that the request is to
 
2757
    only add indexes and create these one by one for the existing
 
2758
    table without having to do a full rebuild.
 
2759
  */
 
2760
  {
 
2761
    /* Prepare stack copies to be re-execution safe */
 
2762
    HA_CREATE_INFO create_info;
 
2763
    Alter_info alter_info(lex->alter_info, thd->mem_root);
 
2764
 
 
2765
    if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
 
2766
      goto error;
 
2767
 
 
2768
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2769
    if (check_one_table_access(thd, INDEX_ACL, all_tables))
 
2770
      goto error; /* purecov: inspected */
 
2771
    if (end_active_trans(thd))
 
2772
      goto error;
 
2773
    /*
 
2774
      Currently CREATE INDEX or DROP INDEX cause a full table rebuild
 
2775
      and thus classify as slow administrative statements just like
 
2776
      ALTER TABLE.
 
2777
    */
 
2778
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
2779
 
 
2780
    bzero((char*) &create_info, sizeof(create_info));
 
2781
    create_info.db_type= 0;
 
2782
    create_info.row_type= ROW_TYPE_NOT_USED;
 
2783
    create_info.default_table_charset= thd->variables.collation_database;
 
2784
 
 
2785
    res= mysql_alter_table(thd, first_table->db, first_table->table_name,
 
2786
                           &create_info, first_table, &alter_info,
 
2787
                           0, (ORDER*) 0, 0);
 
2788
    break;
 
2789
  }
 
2790
#ifdef HAVE_REPLICATION
 
2791
  case SQLCOM_SLAVE_START:
 
2792
  {
 
2793
    pthread_mutex_lock(&LOCK_active_mi);
 
2794
    start_slave(thd,active_mi,1 /* net report*/);
 
2795
    pthread_mutex_unlock(&LOCK_active_mi);
 
2796
    break;
 
2797
  }
 
2798
  case SQLCOM_SLAVE_STOP:
 
2799
  /*
 
2800
    If the client thread has locked tables, a deadlock is possible.
 
2801
    Assume that
 
2802
    - the client thread does LOCK TABLE t READ.
 
2803
    - then the master updates t.
 
2804
    - then the SQL slave thread wants to update t,
 
2805
      so it waits for the client thread because t is locked by it.
 
2806
    - then the client thread does SLAVE STOP.
 
2807
      SLAVE STOP waits for the SQL slave thread to terminate its
 
2808
      update t, which waits for the client thread because t is locked by it.
 
2809
    To prevent that, refuse SLAVE STOP if the
 
2810
    client thread has locked tables
 
2811
  */
 
2812
  if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
 
2813
  {
 
2814
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
2815
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
2816
    goto error;
 
2817
  }
 
2818
  {
 
2819
    pthread_mutex_lock(&LOCK_active_mi);
 
2820
    stop_slave(thd,active_mi,1/* net report*/);
 
2821
    pthread_mutex_unlock(&LOCK_active_mi);
 
2822
    break;
 
2823
  }
 
2824
#endif /* HAVE_REPLICATION */
 
2825
 
 
2826
  case SQLCOM_ALTER_TABLE:
 
2827
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2828
    {
 
2829
      ulong priv=0;
 
2830
      ulong priv_needed= ALTER_ACL;
 
2831
      /*
 
2832
        Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
 
2833
        so we have to use a copy of this structure to make execution
 
2834
        prepared statement- safe. A shallow copy is enough as no memory
 
2835
        referenced from this structure will be modified.
 
2836
      */
 
2837
      HA_CREATE_INFO create_info(lex->create_info);
 
2838
      Alter_info alter_info(lex->alter_info, thd->mem_root);
 
2839
 
 
2840
      if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
 
2841
        goto error;
 
2842
      /*
 
2843
        We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well
 
2844
        as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
 
2845
      */
 
2846
      if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME))
 
2847
        priv_needed|= DROP_ACL;
 
2848
 
 
2849
      /* Must be set in the parser */
 
2850
      DBUG_ASSERT(select_lex->db);
 
2851
      if (check_access(thd, priv_needed, first_table->db,
 
2852
                       &first_table->grant.privilege, 0, 0,
 
2853
                       test(first_table->schema_table)) ||
 
2854
          check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
 
2855
                       is_schema_db(select_lex->db))||
 
2856
          check_merge_table_access(thd, first_table->db,
 
2857
                                   (TABLE_LIST *)
 
2858
                                   create_info.merge_list.first))
 
2859
        goto error;                             /* purecov: inspected */
 
2860
      if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
 
2861
        goto error;
 
2862
      if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
 
2863
      { // Rename of table
 
2864
          TABLE_LIST tmp_table;
 
2865
          bzero((char*) &tmp_table,sizeof(tmp_table));
 
2866
          tmp_table.table_name= lex->name.str;
 
2867
          tmp_table.db=select_lex->db;
 
2868
          tmp_table.grant.privilege=priv;
 
2869
          if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
 
2870
              UINT_MAX, 0))
 
2871
            goto error;
 
2872
      }
 
2873
 
 
2874
      /* Don't yet allow changing of symlinks with ALTER TABLE */
 
2875
      if (create_info.data_file_name)
 
2876
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2877
                            WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
 
2878
                            "DATA DIRECTORY");
 
2879
      if (create_info.index_file_name)
 
2880
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
2881
                            WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
 
2882
                            "INDEX DIRECTORY");
 
2883
      create_info.data_file_name= create_info.index_file_name= NULL;
 
2884
      /* ALTER TABLE ends previous transaction */
 
2885
      if (end_active_trans(thd))
 
2886
        goto error;
 
2887
 
 
2888
      if (!thd->locked_tables &&
 
2889
          !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
2890
      {
 
2891
        res= 1;
 
2892
        break;
 
2893
      }
 
2894
 
 
2895
      thd->enable_slow_log= opt_log_slow_admin_statements;
 
2896
      res= mysql_alter_table(thd, select_lex->db, lex->name.str,
 
2897
                             &create_info,
 
2898
                             first_table,
 
2899
                             &alter_info,
 
2900
                             select_lex->order_list.elements,
 
2901
                             (ORDER *) select_lex->order_list.first,
 
2902
                             lex->ignore);
 
2903
      break;
 
2904
    }
 
2905
  case SQLCOM_RENAME_TABLE:
 
2906
  {
 
2907
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2908
    TABLE_LIST *table;
 
2909
    for (table= first_table; table; table= table->next_local->next_local)
 
2910
    {
 
2911
      if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
 
2912
                       &table->grant.privilege,0,0, test(table->schema_table)) ||
 
2913
          check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
 
2914
                       &table->next_local->grant.privilege, 0, 0,
 
2915
                       test(table->next_local->schema_table)))
 
2916
        goto error;
 
2917
      TABLE_LIST old_list, new_list;
 
2918
      /*
 
2919
        we do not need initialize old_list and new_list because we will
 
2920
        come table[0] and table->next[0] there
 
2921
      */
 
2922
      old_list= table[0];
 
2923
      new_list= table->next_local[0];
 
2924
      if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
 
2925
         (!test_all_bits(table->next_local->grant.privilege,
 
2926
                         INSERT_ACL | CREATE_ACL) &&
 
2927
          check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
 
2928
        goto error;
 
2929
    }
 
2930
 
 
2931
    if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
 
2932
      goto error;
 
2933
    break;
 
2934
  }
 
2935
#ifndef EMBEDDED_LIBRARY
 
2936
  case SQLCOM_SHOW_BINLOGS:
 
2937
#ifdef DONT_ALLOW_SHOW_COMMANDS
 
2938
    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
 
2939
               MYF(0)); /* purecov: inspected */
 
2940
    goto error;
 
2941
#else
 
2942
    {
 
2943
      if (check_global_access(thd, SUPER_ACL))
 
2944
        goto error;
 
2945
      res = show_binlogs(thd);
 
2946
      break;
 
2947
    }
 
2948
#endif
 
2949
#endif /* EMBEDDED_LIBRARY */
 
2950
  case SQLCOM_SHOW_CREATE:
 
2951
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2952
#ifdef DONT_ALLOW_SHOW_COMMANDS
 
2953
    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
 
2954
               MYF(0)); /* purecov: inspected */
 
2955
    goto error;
 
2956
#else
 
2957
    {
 
2958
      /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
 
2959
      if (lex->only_view)
 
2960
        first_table->skip_temporary= 1;
 
2961
      if (check_show_create_table_access(thd, first_table))
 
2962
        goto error;
 
2963
      res= mysqld_show_create(thd, first_table);
 
2964
      break;
 
2965
    }
 
2966
#endif
 
2967
  case SQLCOM_CHECKSUM:
 
2968
  {
 
2969
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2970
    if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables,
 
2971
                           UINT_MAX, FALSE))
 
2972
      goto error; /* purecov: inspected */
 
2973
    res = mysql_checksum_table(thd, first_table, &lex->check_opt);
 
2974
    break;
 
2975
  }
 
2976
  case SQLCOM_REPAIR:
 
2977
  {
 
2978
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2979
    if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
 
2980
                           UINT_MAX, FALSE))
 
2981
      goto error; /* purecov: inspected */
 
2982
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
2983
    res= mysql_repair_table(thd, first_table, &lex->check_opt);
 
2984
    /* ! we write after unlocking the table */
 
2985
    if (!res && !lex->no_write_to_binlog)
 
2986
    {
 
2987
      /*
 
2988
        Presumably, REPAIR and binlog writing doesn't require synchronization
 
2989
      */
 
2990
      res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
2991
    }
 
2992
    select_lex->table_list.first= (uchar*) first_table;
 
2993
    lex->query_tables=all_tables;
 
2994
    break;
 
2995
  }
 
2996
  case SQLCOM_CHECK:
 
2997
  {
 
2998
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
2999
    if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables,
 
3000
                           UINT_MAX, FALSE))
 
3001
      goto error; /* purecov: inspected */
 
3002
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
3003
    res = mysql_check_table(thd, first_table, &lex->check_opt);
 
3004
    select_lex->table_list.first= (uchar*) first_table;
 
3005
    lex->query_tables=all_tables;
 
3006
    break;
 
3007
  }
 
3008
  case SQLCOM_ANALYZE:
 
3009
  {
 
3010
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3011
    if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
 
3012
                           UINT_MAX, FALSE))
 
3013
      goto error; /* purecov: inspected */
 
3014
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
3015
    res= mysql_analyze_table(thd, first_table, &lex->check_opt);
 
3016
    /* ! we write after unlocking the table */
 
3017
    if (!res && !lex->no_write_to_binlog)
 
3018
    {
 
3019
      /*
 
3020
        Presumably, ANALYZE and binlog writing doesn't require synchronization
 
3021
      */
 
3022
      res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
3023
    }
 
3024
    select_lex->table_list.first= (uchar*) first_table;
 
3025
    lex->query_tables=all_tables;
 
3026
    break;
 
3027
  }
 
3028
 
 
3029
  case SQLCOM_OPTIMIZE:
 
3030
  {
 
3031
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3032
    if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
 
3033
                           UINT_MAX, FALSE))
 
3034
      goto error; /* purecov: inspected */
 
3035
    thd->enable_slow_log= opt_log_slow_admin_statements;
 
3036
    res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
 
3037
      mysql_recreate_table(thd, first_table) :
 
3038
      mysql_optimize_table(thd, first_table, &lex->check_opt);
 
3039
    /* ! we write after unlocking the table */
 
3040
    if (!res && !lex->no_write_to_binlog)
 
3041
    {
 
3042
      /*
 
3043
        Presumably, OPTIMIZE and binlog writing doesn't require synchronization
 
3044
      */
 
3045
      res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
3046
    }
 
3047
    select_lex->table_list.first= (uchar*) first_table;
 
3048
    lex->query_tables=all_tables;
 
3049
    break;
 
3050
  }
 
3051
  case SQLCOM_UPDATE:
 
3052
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3053
    if (update_precheck(thd, all_tables))
 
3054
      break;
 
3055
    if (!thd->locked_tables &&
 
3056
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3057
      goto error;
 
3058
    DBUG_ASSERT(select_lex->offset_limit == 0);
 
3059
    unit->set_limit(select_lex);
 
3060
    res= (up_result= mysql_update(thd, all_tables,
 
3061
                                  select_lex->item_list,
 
3062
                                  lex->value_list,
 
3063
                                  select_lex->where,
 
3064
                                  select_lex->order_list.elements,
 
3065
                                  (ORDER *) select_lex->order_list.first,
 
3066
                                  unit->select_limit_cnt,
 
3067
                                  lex->duplicates, lex->ignore));
 
3068
    /* mysql_update return 2 if we need to switch to multi-update */
 
3069
    if (up_result != 2)
 
3070
      break;
 
3071
    /* Fall through */
 
3072
  case SQLCOM_UPDATE_MULTI:
 
3073
  {
 
3074
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3075
    /* if we switched from normal update, rights are checked */
 
3076
    if (up_result != 2)
 
3077
    {
 
3078
      if ((res= multi_update_precheck(thd, all_tables)))
 
3079
        break;
 
3080
    }
 
3081
    else
 
3082
      res= 0;
 
3083
 
 
3084
    /*
 
3085
      Protection might have already been risen if its a fall through
 
3086
      from the SQLCOM_UPDATE case above.
 
3087
    */
 
3088
    if (!thd->locked_tables &&
 
3089
        lex->sql_command == SQLCOM_UPDATE_MULTI &&
 
3090
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3091
      goto error;
 
3092
 
 
3093
    res= mysql_multi_update_prepare(thd);
 
3094
 
 
3095
#ifdef HAVE_REPLICATION
 
3096
    /* Check slave filtering rules */
 
3097
    if (unlikely(thd->slave_thread && !have_table_map_for_update))
 
3098
    {
 
3099
      if (all_tables_not_ok(thd, all_tables))
 
3100
      {
 
3101
        if (res!= 0)
 
3102
        {
 
3103
          res= 0;             /* don't care of prev failure  */
 
3104
          thd->clear_error(); /* filters are of highest prior */
 
3105
        }
 
3106
        /* we warn the slave SQL thread */
 
3107
        my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
 
3108
        break;
 
3109
      }
 
3110
      if (res)
 
3111
        break;
 
3112
    }
 
3113
    else
 
3114
    {
 
3115
#endif /* HAVE_REPLICATION */
 
3116
      if (res)
 
3117
        break;
 
3118
      if (opt_readonly &&
 
3119
          !(thd->security_ctx->master_access & SUPER_ACL) &&
 
3120
          some_non_temp_table_to_be_updated(thd, all_tables))
 
3121
      {
 
3122
        my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
 
3123
        break;
 
3124
      }
 
3125
#ifdef HAVE_REPLICATION
 
3126
    }  /* unlikely */
 
3127
#endif
 
3128
 
 
3129
    res= mysql_multi_update(thd, all_tables,
 
3130
                            &select_lex->item_list,
 
3131
                            &lex->value_list,
 
3132
                            select_lex->where,
 
3133
                            select_lex->options,
 
3134
                            lex->duplicates, lex->ignore, unit, select_lex);
 
3135
    break;
 
3136
  }
 
3137
  case SQLCOM_REPLACE:
 
3138
#ifndef DBUG_OFF
 
3139
    if (mysql_bin_log.is_open())
 
3140
    {
 
3141
      /*
 
3142
        Generate an incident log event before writing the real event
 
3143
        to the binary log.  We put this event is before the statement
 
3144
        since that makes it simpler to check that the statement was
 
3145
        not executed on the slave (since incidents usually stop the
 
3146
        slave).
 
3147
 
 
3148
        Observe that any row events that are generated will be
 
3149
        generated before.
 
3150
 
 
3151
        This is only for testing purposes and will not be present in a
 
3152
        release build.
 
3153
      */
 
3154
 
 
3155
      Incident incident= INCIDENT_NONE;
 
3156
      DBUG_PRINT("debug", ("Just before generate_incident()"));
 
3157
      DBUG_EXECUTE_IF("incident_database_resync_on_replace",
 
3158
                      incident= INCIDENT_LOST_EVENTS;);
 
3159
      if (incident)
 
3160
      {
 
3161
        Incident_log_event ev(thd, incident);
 
3162
        (void) mysql_bin_log.write(&ev);        /* error is ignored */
 
3163
        mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
 
3164
      }
 
3165
      DBUG_PRINT("debug", ("Just after generate_incident()"));
 
3166
    }
 
3167
#endif
 
3168
  case SQLCOM_INSERT:
 
3169
  {
 
3170
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3171
    if ((res= insert_precheck(thd, all_tables)))
 
3172
      break;
 
3173
 
 
3174
    if (!thd->locked_tables &&
 
3175
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3176
    {
 
3177
      res= 1;
 
3178
      break;
 
3179
    }
 
3180
 
 
3181
    res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
 
3182
                      lex->update_list, lex->value_list,
 
3183
                      lex->duplicates, lex->ignore);
 
3184
 
 
3185
    /*
 
3186
      If we have inserted into a VIEW, and the base table has
 
3187
      AUTO_INCREMENT column, but this column is not accessible through
 
3188
      a view, then we should restore LAST_INSERT_ID to the value it
 
3189
      had before the statement.
 
3190
    */
 
3191
    if (first_table->view && !first_table->contain_auto_increment)
 
3192
      thd->first_successful_insert_id_in_cur_stmt=
 
3193
        thd->first_successful_insert_id_in_prev_stmt;
 
3194
 
 
3195
    break;
 
3196
  }
 
3197
  case SQLCOM_REPLACE_SELECT:
 
3198
  case SQLCOM_INSERT_SELECT:
 
3199
  {
 
3200
    select_result *sel_result;
 
3201
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3202
    if ((res= insert_precheck(thd, all_tables)))
 
3203
      break;
 
3204
 
 
3205
    /* Fix lock for first table */
 
3206
    if (first_table->lock_type == TL_WRITE_DELAYED)
 
3207
      first_table->lock_type= TL_WRITE;
 
3208
 
 
3209
    /* Don't unlock tables until command is written to binary log */
 
3210
    select_lex->options|= SELECT_NO_UNLOCK;
 
3211
 
 
3212
    unit->set_limit(select_lex);
 
3213
 
 
3214
    if (! thd->locked_tables &&
 
3215
        ! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
 
3216
    {
 
3217
      res= 1;
 
3218
      break;
 
3219
    }
 
3220
 
 
3221
    if (!(res= open_and_lock_tables(thd, all_tables)))
 
3222
    {
 
3223
      /* Skip first table, which is the table we are inserting in */
 
3224
      TABLE_LIST *second_table= first_table->next_local;
 
3225
      select_lex->table_list.first= (uchar*) second_table;
 
3226
      select_lex->context.table_list= 
 
3227
        select_lex->context.first_name_resolution_table= second_table;
 
3228
      res= mysql_insert_select_prepare(thd);
 
3229
      if (!res && (sel_result= new select_insert(first_table,
 
3230
                                                 first_table->table,
 
3231
                                                 &lex->field_list,
 
3232
                                                 &lex->update_list,
 
3233
                                                 &lex->value_list,
 
3234
                                                 lex->duplicates,
 
3235
                                                 lex->ignore)))
 
3236
      {
 
3237
        res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
 
3238
        /*
 
3239
          Invalidate the table in the query cache if something changed
 
3240
          after unlocking when changes become visible.
 
3241
          TODO: this is workaround. right way will be move invalidating in
 
3242
          the unlock procedure.
 
3243
        */
 
3244
        if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
 
3245
            thd->lock)
 
3246
        {
 
3247
          /* INSERT ... SELECT should invalidate only the very first table */
 
3248
          TABLE_LIST *save_table= first_table->next_local;
 
3249
          first_table->next_local= 0;
 
3250
          query_cache_invalidate3(thd, first_table, 1);
 
3251
          first_table->next_local= save_table;
 
3252
        }
 
3253
        delete sel_result;
 
3254
      }
 
3255
      /* revert changes for SP */
 
3256
      select_lex->table_list.first= (uchar*) first_table;
 
3257
    }
 
3258
 
 
3259
    /*
 
3260
      If we have inserted into a VIEW, and the base table has
 
3261
      AUTO_INCREMENT column, but this column is not accessible through
 
3262
      a view, then we should restore LAST_INSERT_ID to the value it
 
3263
      had before the statement.
 
3264
    */
 
3265
    if (first_table->view && !first_table->contain_auto_increment)
 
3266
      thd->first_successful_insert_id_in_cur_stmt=
 
3267
        thd->first_successful_insert_id_in_prev_stmt;
 
3268
 
 
3269
    break;
 
3270
  }
 
3271
  case SQLCOM_TRUNCATE:
 
3272
    if (end_active_trans(thd))
 
3273
    {
 
3274
      res= -1;
 
3275
      break;
 
3276
    }
 
3277
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3278
    if (check_one_table_access(thd, DROP_ACL, all_tables))
 
3279
      goto error;
 
3280
    /*
 
3281
      Don't allow this within a transaction because we want to use
 
3282
      re-generate table
 
3283
    */
 
3284
    if (thd->locked_tables || thd->active_transaction())
 
3285
    {
 
3286
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
3287
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
3288
      goto error;
 
3289
    }
 
3290
    if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3291
      goto error;
 
3292
    res= mysql_truncate(thd, first_table, 0);
 
3293
    break;
 
3294
  case SQLCOM_DELETE:
 
3295
  {
 
3296
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3297
    if ((res= delete_precheck(thd, all_tables)))
 
3298
      break;
 
3299
    DBUG_ASSERT(select_lex->offset_limit == 0);
 
3300
    unit->set_limit(select_lex);
 
3301
 
 
3302
    if (!thd->locked_tables &&
 
3303
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3304
    {
 
3305
      res= 1;
 
3306
      break;
 
3307
    }
 
3308
 
 
3309
    res = mysql_delete(thd, all_tables, select_lex->where,
 
3310
                       &select_lex->order_list,
 
3311
                       unit->select_limit_cnt, select_lex->options,
 
3312
                       FALSE);
 
3313
    break;
 
3314
  }
 
3315
  case SQLCOM_DELETE_MULTI:
 
3316
  {
 
3317
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3318
    TABLE_LIST *aux_tables=
 
3319
      (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
 
3320
    multi_delete *del_result;
 
3321
 
 
3322
    if (!thd->locked_tables &&
 
3323
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3324
    {
 
3325
      res= 1;
 
3326
      break;
 
3327
    }
 
3328
 
 
3329
    if ((res= multi_delete_precheck(thd, all_tables)))
 
3330
      break;
 
3331
 
 
3332
    /* condition will be TRUE on SP re-excuting */
 
3333
    if (select_lex->item_list.elements != 0)
 
3334
      select_lex->item_list.empty();
 
3335
    if (add_item_to_list(thd, new Item_null()))
 
3336
      goto error;
 
3337
 
 
3338
    thd_proc_info(thd, "init");
 
3339
    if ((res= open_and_lock_tables(thd, all_tables)))
 
3340
      break;
 
3341
 
 
3342
    if ((res= mysql_multi_delete_prepare(thd)))
 
3343
      goto error;
 
3344
 
 
3345
    if (!thd->is_fatal_error &&
 
3346
        (del_result= new multi_delete(aux_tables, lex->table_count)))
 
3347
    {
 
3348
      res= mysql_select(thd, &select_lex->ref_pointer_array,
 
3349
                        select_lex->get_table_list(),
 
3350
                        select_lex->with_wild,
 
3351
                        select_lex->item_list,
 
3352
                        select_lex->where,
 
3353
                        0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
 
3354
                        (ORDER *)NULL,
 
3355
                        (select_lex->options | thd->options |
 
3356
                        SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
 
3357
                        OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
 
3358
                        del_result, unit, select_lex);
 
3359
      res|= thd->is_error();
 
3360
      if (res)
 
3361
        del_result->abort();
 
3362
      delete del_result;
 
3363
    }
 
3364
    else
 
3365
      res= TRUE;                                // Error
 
3366
    break;
 
3367
  }
 
3368
  case SQLCOM_DROP_TABLE:
 
3369
  {
 
3370
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3371
    if (!lex->drop_temporary)
 
3372
    {
 
3373
      if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE))
 
3374
        goto error;                             /* purecov: inspected */
 
3375
      if (end_active_trans(thd))
 
3376
        goto error;
 
3377
    }
 
3378
    else
 
3379
    {
 
3380
      /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
 
3381
      thd->options|= OPTION_KEEP_LOG;
 
3382
    }
 
3383
    /* DDL and binlog write order protected by LOCK_open */
 
3384
    res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
 
3385
                        lex->drop_temporary);
 
3386
  }
 
3387
  break;
 
3388
  case SQLCOM_SHOW_PROCESSLIST:
 
3389
    if (!thd->security_ctx->priv_user[0] &&
 
3390
        check_global_access(thd,PROCESS_ACL))
 
3391
      break;
 
3392
    mysqld_list_processes(thd,
 
3393
                          (thd->security_ctx->master_access & PROCESS_ACL ?
 
3394
                           NullS :
 
3395
                           thd->security_ctx->priv_user),
 
3396
                          lex->verbose);
 
3397
    break;
 
3398
  case SQLCOM_SHOW_AUTHORS:
 
3399
    res= mysqld_show_authors(thd);
 
3400
    break;
 
3401
  case SQLCOM_SHOW_CONTRIBUTORS:
 
3402
    res= mysqld_show_contributors(thd);
 
3403
    break;
 
3404
  case SQLCOM_SHOW_PRIVILEGES:
 
3405
    res= mysqld_show_privileges(thd);
 
3406
    break;
 
3407
  case SQLCOM_SHOW_COLUMN_TYPES:
 
3408
    res= mysqld_show_column_types(thd);
 
3409
    break;
 
3410
  case SQLCOM_SHOW_ENGINE_LOGS:
 
3411
#ifdef DONT_ALLOW_SHOW_COMMANDS
 
3412
    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
 
3413
               MYF(0)); /* purecov: inspected */
 
3414
    goto error;
 
3415
#else
 
3416
    {
 
3417
      if (check_access(thd, FILE_ACL, any_db,0,0,0,0))
 
3418
        goto error;
 
3419
      res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
 
3420
      break;
 
3421
    }
 
3422
#endif
 
3423
  case SQLCOM_CHANGE_DB:
 
3424
  {
 
3425
    LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
 
3426
 
 
3427
    if (!mysql_change_db(thd, &db_str, FALSE))
 
3428
      my_ok(thd);
 
3429
 
 
3430
    break;
 
3431
  }
 
3432
 
 
3433
  case SQLCOM_LOAD:
 
3434
  {
 
3435
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
3436
    uint privilege= (lex->duplicates == DUP_REPLACE ?
 
3437
                     INSERT_ACL | DELETE_ACL : INSERT_ACL) |
 
3438
                    (lex->local_file ? 0 : FILE_ACL);
 
3439
 
 
3440
    if (lex->local_file)
 
3441
    {
 
3442
      if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
 
3443
          !opt_local_infile)
 
3444
      {
 
3445
        my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
 
3446
        goto error;
 
3447
      }
 
3448
    }
 
3449
 
 
3450
    if (check_one_table_access(thd, privilege, all_tables))
 
3451
      goto error;
 
3452
 
 
3453
    if (!thd->locked_tables &&
 
3454
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3455
      goto error;
 
3456
 
 
3457
    res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
 
3458
                    lex->update_list, lex->value_list, lex->duplicates,
 
3459
                    lex->ignore, (bool) lex->local_file);
 
3460
    break;
 
3461
  }
 
3462
 
 
3463
  case SQLCOM_SET_OPTION:
 
3464
  {
 
3465
    List<set_var_base> *lex_var_list= &lex->var_list;
 
3466
 
 
3467
    if (lex->autocommit && end_active_trans(thd))
 
3468
      goto error;
 
3469
 
 
3470
    if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
 
3471
         open_and_lock_tables(thd, all_tables)))
 
3472
      goto error;
 
3473
    if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
 
3474
    {
 
3475
      my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
 
3476
      goto error;
 
3477
    }
 
3478
    if (!(res= sql_set_variables(thd, lex_var_list)))
 
3479
    {
 
3480
      /*
 
3481
        If the previous command was a SET ONE_SHOT, we don't want to forget
 
3482
        about the ONE_SHOT property of that SET. So we use a |= instead of = .
 
3483
      */
 
3484
      thd->one_shot_set|= lex->one_shot_set;
 
3485
      my_ok(thd);
 
3486
    }
 
3487
    else
 
3488
    {
 
3489
      /*
 
3490
        We encountered some sort of error, but no message was sent.
 
3491
        Send something semi-generic here since we don't know which
 
3492
        assignment in the list caused the error.
 
3493
      */
 
3494
      if (!thd->is_error())
 
3495
        my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
 
3496
      goto error;
 
3497
    }
 
3498
 
 
3499
    break;
 
3500
  }
 
3501
 
 
3502
  case SQLCOM_UNLOCK_TABLES:
 
3503
    /*
 
3504
      It is critical for mysqldump --single-transaction --master-data that
 
3505
      UNLOCK TABLES does not implicitely commit a connection which has only
 
3506
      done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
 
3507
      false, mysqldump will not work.
 
3508
    */
 
3509
    unlock_locked_tables(thd);
 
3510
    if (thd->options & OPTION_TABLE_LOCK)
 
3511
    {
 
3512
      end_active_trans(thd);
 
3513
      thd->options&= ~(OPTION_TABLE_LOCK);
 
3514
    }
 
3515
    if (thd->global_read_lock)
 
3516
      unlock_global_read_lock(thd);
 
3517
    my_ok(thd);
 
3518
    break;
 
3519
  case SQLCOM_LOCK_TABLES:
 
3520
    unlock_locked_tables(thd);
 
3521
    /* we must end the trasaction first, regardless of anything */
 
3522
    if (end_active_trans(thd))
 
3523
      goto error;
 
3524
    if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
 
3525
                           UINT_MAX, FALSE))
 
3526
      goto error;
 
3527
    if (lex->protect_against_global_read_lock &&
 
3528
        !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
 
3529
      goto error;
 
3530
    thd->in_lock_tables=1;
 
3531
    thd->options|= OPTION_TABLE_LOCK;
 
3532
 
 
3533
    if (!(res= simple_open_n_lock_tables(thd, all_tables)))
 
3534
    {
 
3535
#ifdef HAVE_QUERY_CACHE
 
3536
      if (thd->variables.query_cache_wlock_invalidate)
 
3537
        query_cache.invalidate_locked_for_write(first_table);
 
3538
#endif /*HAVE_QUERY_CACHE*/
 
3539
      thd->locked_tables=thd->lock;
 
3540
      thd->lock=0;
 
3541
      my_ok(thd);
 
3542
    }
 
3543
    else
 
3544
    {
 
3545
      /* 
 
3546
        Need to end the current transaction, so the storage engine (InnoDB)
 
3547
        can free its locks if LOCK TABLES locked some tables before finding
 
3548
        that it can't lock a table in its list
 
3549
      */
 
3550
      ha_autocommit_or_rollback(thd, 1);
 
3551
      end_active_trans(thd);
 
3552
      thd->options&= ~(OPTION_TABLE_LOCK);
 
3553
    }
 
3554
    thd->in_lock_tables=0;
 
3555
    break;
 
3556
  case SQLCOM_CREATE_DB:
 
3557
  {
 
3558
    /*
 
3559
      As mysql_create_db() may modify HA_CREATE_INFO structure passed to
 
3560
      it, we need to use a copy of LEX::create_info to make execution
 
3561
      prepared statement- safe.
 
3562
    */
 
3563
    HA_CREATE_INFO create_info(lex->create_info);
 
3564
    if (end_active_trans(thd))
 
3565
    {
 
3566
      res= -1;
 
3567
      break;
 
3568
    }
 
3569
    char *alias;
 
3570
    if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
 
3571
        check_db_name(&lex->name))
 
3572
    {
 
3573
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
3574
      break;
 
3575
    }
 
3576
    /*
 
3577
      If in a slave thread :
 
3578
      CREATE DATABASE DB was certainly not preceded by USE DB.
 
3579
      For that reason, db_ok() in sql/slave.cc did not check the
 
3580
      do_db/ignore_db. And as this query involves no tables, tables_ok()
 
3581
      above was not called. So we have to check rules again here.
 
3582
    */
 
3583
#ifdef HAVE_REPLICATION
 
3584
    if (thd->slave_thread && 
 
3585
        (!rpl_filter->db_ok(lex->name.str) ||
 
3586
         !rpl_filter->db_ok_with_wild_table(lex->name.str)))
 
3587
    {
 
3588
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
3589
      break;
 
3590
    }
 
3591
#endif
 
3592
    if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
 
3593
                     is_schema_db(lex->name.str, lex->name.length)))
 
3594
      break;
 
3595
    res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
 
3596
                              lex->name.str), &create_info, 0);
 
3597
    break;
 
3598
  }
 
3599
  case SQLCOM_DROP_DB:
 
3600
  {
 
3601
    if (end_active_trans(thd))
 
3602
    {
 
3603
      res= -1;
 
3604
      break;
 
3605
    }
 
3606
    if (check_db_name(&lex->name))
 
3607
    {
 
3608
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
3609
      break;
 
3610
    }
 
3611
    /*
 
3612
      If in a slave thread :
 
3613
      DROP DATABASE DB may not be preceded by USE DB.
 
3614
      For that reason, maybe db_ok() in sql/slave.cc did not check the 
 
3615
      do_db/ignore_db. And as this query involves no tables, tables_ok()
 
3616
      above was not called. So we have to check rules again here.
 
3617
    */
 
3618
#ifdef HAVE_REPLICATION
 
3619
    if (thd->slave_thread && 
 
3620
        (!rpl_filter->db_ok(lex->name.str) ||
 
3621
         !rpl_filter->db_ok_with_wild_table(lex->name.str)))
 
3622
    {
 
3623
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
3624
      break;
 
3625
    }
 
3626
#endif
 
3627
    if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
 
3628
                     is_schema_db(lex->name.str, lex->name.length)))
 
3629
      break;
 
3630
    if (thd->locked_tables || thd->active_transaction())
 
3631
    {
 
3632
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
3633
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
3634
      goto error;
 
3635
    }
 
3636
    res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
 
3637
    break;
 
3638
  }
 
3639
  case SQLCOM_ALTER_DB_UPGRADE:
 
3640
  {
 
3641
    LEX_STRING *db= & lex->name;
 
3642
    if (end_active_trans(thd))
 
3643
    {
 
3644
      res= 1;
 
3645
      break;
 
3646
    }
 
3647
#ifdef HAVE_REPLICATION
 
3648
    if (thd->slave_thread && 
 
3649
       (!rpl_filter->db_ok(db->str) ||
 
3650
        !rpl_filter->db_ok_with_wild_table(db->str)))
 
3651
    {
 
3652
      res= 1;
 
3653
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
3654
      break;
 
3655
    }
 
3656
#endif
 
3657
    if (check_db_name(db))
 
3658
    {
 
3659
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
3660
      break;
 
3661
    }
 
3662
    if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
 
3663
                     is_schema_db(db->str, db->length)) ||
 
3664
        check_access(thd, DROP_ACL, db->str, 0, 1, 0,
 
3665
                     is_schema_db(db->str, db->length)) ||
 
3666
        check_access(thd, CREATE_ACL, db->str, 0, 1, 0,
 
3667
                     is_schema_db(db->str, db->length)))
 
3668
    {
 
3669
      res= 1;
 
3670
      break;
 
3671
    }
 
3672
    if (thd->locked_tables || thd->active_transaction())
 
3673
    {
 
3674
      res= 1;
 
3675
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
3676
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
3677
      goto error;
 
3678
    }
 
3679
 
 
3680
    res= mysql_upgrade_db(thd, db);
 
3681
    if (!res)
 
3682
      my_ok(thd);
 
3683
    break;
 
3684
  }
 
3685
  case SQLCOM_ALTER_DB:
 
3686
  {
 
3687
    LEX_STRING *db= &lex->name;
 
3688
    HA_CREATE_INFO create_info(lex->create_info);
 
3689
    if (check_db_name(db))
 
3690
    {
 
3691
      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
 
3692
      break;
 
3693
    }
 
3694
    /*
 
3695
      If in a slave thread :
 
3696
      ALTER DATABASE DB may not be preceded by USE DB.
 
3697
      For that reason, maybe db_ok() in sql/slave.cc did not check the
 
3698
      do_db/ignore_db. And as this query involves no tables, tables_ok()
 
3699
      above was not called. So we have to check rules again here.
 
3700
    */
 
3701
#ifdef HAVE_REPLICATION
 
3702
    if (thd->slave_thread &&
 
3703
        (!rpl_filter->db_ok(db->str) ||
 
3704
         !rpl_filter->db_ok_with_wild_table(db->str)))
 
3705
    {
 
3706
      my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
 
3707
      break;
 
3708
    }
 
3709
#endif
 
3710
    if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
 
3711
                     is_schema_db(db->str, db->length)))
 
3712
      break;
 
3713
    if (thd->locked_tables || thd->active_transaction())
 
3714
    {
 
3715
      my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
 
3716
                 ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
3717
      goto error;
 
3718
    }
 
3719
    res= mysql_alter_db(thd, db->str, &create_info);
 
3720
    break;
 
3721
  }
 
3722
  case SQLCOM_SHOW_CREATE_DB:
 
3723
  {
 
3724
    DBUG_EXECUTE_IF("4x_server_emul",
 
3725
                    my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
 
3726
    if (check_db_name(&lex->name))
 
3727
    {
 
3728
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
 
3729
      break;
 
3730
    }
 
3731
    res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
 
3732
    break;
 
3733
  }
 
3734
  case SQLCOM_CREATE_EVENT:
 
3735
  case SQLCOM_ALTER_EVENT:
 
3736
  #ifdef HAVE_EVENT_SCHEDULER
 
3737
  do
 
3738
  {
 
3739
    DBUG_ASSERT(lex->event_parse_data);
 
3740
    if (lex->table_or_sp_used())
 
3741
    {
 
3742
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
 
3743
               "function calls as part of this statement");
 
3744
      break;
 
3745
    }
 
3746
 
 
3747
    res= sp_process_definer(thd);
 
3748
    if (res)
 
3749
      break;
 
3750
 
 
3751
    switch (lex->sql_command) {
 
3752
    case SQLCOM_CREATE_EVENT:
 
3753
    {
 
3754
      bool if_not_exists= (lex->create_info.options &
 
3755
                           HA_LEX_CREATE_IF_NOT_EXISTS);
 
3756
      res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
 
3757
      break;
 
3758
    }
 
3759
    case SQLCOM_ALTER_EVENT:
 
3760
      res= Events::update_event(thd, lex->event_parse_data,
 
3761
                                lex->spname ? &lex->spname->m_db : NULL,
 
3762
                                lex->spname ? &lex->spname->m_name : NULL);
 
3763
      break;
 
3764
    default:
 
3765
      DBUG_ASSERT(0);
 
3766
    }
 
3767
    DBUG_PRINT("info",("DDL error code=%d", res));
 
3768
    if (!res)
 
3769
      my_ok(thd);
 
3770
 
 
3771
  } while (0);
 
3772
  /* Don't do it, if we are inside a SP */
 
3773
  if (!thd->spcont)
 
3774
  {
 
3775
    delete lex->sphead;
 
3776
    lex->sphead= NULL;
 
3777
  }
 
3778
  /* lex->unit.cleanup() is called outside, no need to call it here */
 
3779
  break;
 
3780
  case SQLCOM_SHOW_CREATE_EVENT:
 
3781
    res= Events::show_create_event(thd, lex->spname->m_db,
 
3782
                                   lex->spname->m_name);
 
3783
    break;
 
3784
  case SQLCOM_DROP_EVENT:
 
3785
    if (!(res= Events::drop_event(thd,
 
3786
                                  lex->spname->m_db, lex->spname->m_name,
 
3787
                                  lex->drop_if_exists)))
 
3788
      my_ok(thd);
 
3789
    break;
 
3790
#else
 
3791
    my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
 
3792
    break;
 
3793
#endif
 
3794
  case SQLCOM_CREATE_FUNCTION:                  // UDF function
 
3795
  {
 
3796
    if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
 
3797
      break;
 
3798
#ifdef HAVE_DLOPEN
 
3799
    if (!(res = mysql_create_function(thd, &lex->udf)))
 
3800
      my_ok(thd);
 
3801
#else
 
3802
    my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
 
3803
    res= TRUE;
 
3804
#endif
 
3805
    break;
 
3806
  }
 
3807
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
3808
  case SQLCOM_CREATE_USER:
 
3809
  {
 
3810
    if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
 
3811
        check_global_access(thd,CREATE_USER_ACL))
 
3812
      break;
 
3813
    if (end_active_trans(thd))
 
3814
      goto error;
 
3815
    /* Conditionally writes to binlog */
 
3816
    if (!(res= mysql_create_user(thd, lex->users_list)))
 
3817
      my_ok(thd);
 
3818
    break;
 
3819
  }
 
3820
  case SQLCOM_DROP_USER:
 
3821
  {
 
3822
    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
 
3823
        check_global_access(thd,CREATE_USER_ACL))
 
3824
      break;
 
3825
    if (end_active_trans(thd))
 
3826
      goto error;
 
3827
    /* Conditionally writes to binlog */
 
3828
    if (!(res= mysql_drop_user(thd, lex->users_list)))
 
3829
      my_ok(thd);
 
3830
    break;
 
3831
  }
 
3832
  case SQLCOM_RENAME_USER:
 
3833
  {
 
3834
    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
 
3835
        check_global_access(thd,CREATE_USER_ACL))
 
3836
      break;
 
3837
    if (end_active_trans(thd))
 
3838
      goto error;
 
3839
    /* Conditionally writes to binlog */
 
3840
    if (!(res= mysql_rename_user(thd, lex->users_list)))
 
3841
      my_ok(thd);
 
3842
    break;
 
3843
  }
 
3844
  case SQLCOM_REVOKE_ALL:
 
3845
  {
 
3846
    if (end_active_trans(thd))
 
3847
      goto error;
 
3848
    if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
 
3849
        check_global_access(thd,CREATE_USER_ACL))
 
3850
      break;
 
3851
    /* Conditionally writes to binlog */
 
3852
    if (!(res = mysql_revoke_all(thd, lex->users_list)))
 
3853
      my_ok(thd);
 
3854
    break;
 
3855
  }
 
3856
  case SQLCOM_REVOKE:
 
3857
  case SQLCOM_GRANT:
 
3858
  {
 
3859
    if (end_active_trans(thd))
 
3860
      goto error;
 
3861
 
 
3862
    if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
 
3863
                     first_table ?  first_table->db : select_lex->db,
 
3864
                     first_table ? &first_table->grant.privilege : 0,
 
3865
                     first_table ? 0 : 1, 0,
 
3866
                     first_table ? (bool) first_table->schema_table :
 
3867
                     select_lex->db ?
 
3868
                     is_schema_db(select_lex->db) : 0))
 
3869
      goto error;
 
3870
 
 
3871
    if (thd->security_ctx->user)              // If not replication
 
3872
    {
 
3873
      LEX_USER *user, *tmp_user;
 
3874
 
 
3875
      List_iterator <LEX_USER> user_list(lex->users_list);
 
3876
      while ((tmp_user= user_list++))
 
3877
      {
 
3878
        if (!(user= get_current_user(thd, tmp_user)))
 
3879
          goto error;
 
3880
        if (specialflag & SPECIAL_NO_RESOLVE &&
 
3881
            hostname_requires_resolving(user->host.str))
 
3882
          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
3883
                              ER_WARN_HOSTNAME_WONT_WORK,
 
3884
                              ER(ER_WARN_HOSTNAME_WONT_WORK),
 
3885
                              user->host.str);
 
3886
        // Are we trying to change a password of another user
 
3887
        DBUG_ASSERT(user->host.str != 0);
 
3888
        if (strcmp(thd->security_ctx->user, user->user.str) ||
 
3889
            my_strcasecmp(system_charset_info,
 
3890
                          user->host.str, thd->security_ctx->host_or_ip))
 
3891
        {
 
3892
          // TODO: use check_change_password()
 
3893
          if (is_acl_user(user->host.str, user->user.str) &&
 
3894
              user->password.str &&
 
3895
              check_access(thd, UPDATE_ACL,"mysql",0,1,1,0))
 
3896
          {
 
3897
            my_message(ER_PASSWORD_NOT_ALLOWED,
 
3898
                       ER(ER_PASSWORD_NOT_ALLOWED), MYF(0));
 
3899
            goto error;
 
3900
          }
 
3901
        }
 
3902
      }
 
3903
    }
 
3904
    if (first_table)
 
3905
    {
 
3906
      if (lex->type == TYPE_ENUM_PROCEDURE ||
 
3907
          lex->type == TYPE_ENUM_FUNCTION)
 
3908
      {
 
3909
        uint grants= lex->all_privileges 
 
3910
                   ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
 
3911
                   : lex->grant;
 
3912
        if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
 
3913
                                lex->type == TYPE_ENUM_PROCEDURE, 0))
 
3914
          goto error;
 
3915
        /* Conditionally writes to binlog */
 
3916
        res= mysql_routine_grant(thd, all_tables,
 
3917
                                 lex->type == TYPE_ENUM_PROCEDURE, 
 
3918
                                 lex->users_list, grants,
 
3919
                                 lex->sql_command == SQLCOM_REVOKE, TRUE);
 
3920
        if (!res)
 
3921
          my_ok(thd);
 
3922
      }
 
3923
      else
 
3924
      {
 
3925
        if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
 
3926
                        all_tables, 0, UINT_MAX, 0))
 
3927
          goto error;
 
3928
        /* Conditionally writes to binlog */
 
3929
        res= mysql_table_grant(thd, all_tables, lex->users_list,
 
3930
                               lex->columns, lex->grant,
 
3931
                               lex->sql_command == SQLCOM_REVOKE);
 
3932
      }
 
3933
    }
 
3934
    else
 
3935
    {
 
3936
      if (lex->columns.elements || lex->type)
 
3937
      {
 
3938
        my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
 
3939
                   MYF(0));
 
3940
        goto error;
 
3941
      }
 
3942
      else
 
3943
        /* Conditionally writes to binlog */
 
3944
        res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
 
3945
                          lex->sql_command == SQLCOM_REVOKE);
 
3946
      if (!res)
 
3947
      {
 
3948
        if (lex->sql_command == SQLCOM_GRANT)
 
3949
        {
 
3950
          List_iterator <LEX_USER> str_list(lex->users_list);
 
3951
          LEX_USER *user, *tmp_user;
 
3952
          while ((tmp_user=str_list++))
 
3953
          {
 
3954
            if (!(user= get_current_user(thd, tmp_user)))
 
3955
              goto error;
 
3956
            reset_mqh(user, 0);
 
3957
          }
 
3958
        }
 
3959
      }
 
3960
    }
 
3961
    break;
 
3962
  }
 
3963
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
 
3964
  case SQLCOM_RESET:
 
3965
    /*
 
3966
      RESET commands are never written to the binary log, so we have to
 
3967
      initialize this variable because RESET shares the same code as FLUSH
 
3968
    */
 
3969
    lex->no_write_to_binlog= 1;
 
3970
  case SQLCOM_FLUSH:
 
3971
  {
 
3972
    bool write_to_binlog;
 
3973
    if (check_global_access(thd,RELOAD_ACL))
 
3974
      goto error;
 
3975
 
 
3976
    /*
 
3977
      reload_acl_and_cache() will tell us if we are allowed to write to the
 
3978
      binlog or not.
 
3979
    */
 
3980
    if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
 
3981
    {
 
3982
      /*
 
3983
        We WANT to write and we CAN write.
 
3984
        ! we write after unlocking the table.
 
3985
      */
 
3986
      /*
 
3987
        Presumably, RESET and binlog writing doesn't require synchronization
 
3988
      */
 
3989
      if (!lex->no_write_to_binlog && write_to_binlog)
 
3990
      {
 
3991
        if ((res= write_bin_log(thd, FALSE, thd->query(), thd->query_length())))
 
3992
          break;
 
3993
      }
 
3994
      my_ok(thd);
 
3995
    } 
 
3996
    
 
3997
    break;
 
3998
  }
 
3999
  case SQLCOM_KILL:
 
4000
  {
 
4001
    Item *it= (Item *)lex->value_list.head();
 
4002
 
 
4003
    if (lex->table_or_sp_used())
 
4004
    {
 
4005
      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
 
4006
               "function calls as part of this statement");
 
4007
      break;
 
4008
    }
 
4009
 
 
4010
    if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
 
4011
    {
 
4012
      my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
 
4013
                 MYF(0));
 
4014
      goto error;
 
4015
    }
 
4016
    sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
 
4017
    break;
 
4018
  }
 
4019
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
4020
  case SQLCOM_SHOW_GRANTS:
 
4021
  {
 
4022
    LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
 
4023
    if (!grant_user)
 
4024
      goto error;
 
4025
    if ((thd->security_ctx->priv_user &&
 
4026
         !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
 
4027
        !check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
 
4028
    {
 
4029
      res = mysql_show_grants(thd, grant_user);
 
4030
    }
 
4031
    break;
 
4032
  }
 
4033
#endif
 
4034
  case SQLCOM_HA_OPEN:
 
4035
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
4036
    if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))
 
4037
      goto error;
 
4038
    res= mysql_ha_open(thd, first_table, 0);
 
4039
    break;
 
4040
  case SQLCOM_HA_CLOSE:
 
4041
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
4042
    res= mysql_ha_close(thd, first_table);
 
4043
    break;
 
4044
  case SQLCOM_HA_READ:
 
4045
    DBUG_ASSERT(first_table == all_tables && first_table != 0);
 
4046
    /*
 
4047
      There is no need to check for table permissions here, because
 
4048
      if a user has no permissions to read a table, he won't be
 
4049
      able to open it (with SQLCOM_HA_OPEN) in the first place.
 
4050
    */
 
4051
    unit->set_limit(select_lex);
 
4052
    res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
 
4053
                       lex->insert_list, lex->ha_rkey_mode, select_lex->where,
 
4054
                       unit->select_limit_cnt, unit->offset_limit_cnt);
 
4055
    break;
 
4056
 
 
4057
  case SQLCOM_BEGIN:
 
4058
    if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
4059
    {
 
4060
      my_error(ER_XAER_RMFAIL, MYF(0),
 
4061
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
4062
      break;
 
4063
    }
 
4064
    if (begin_trans(thd))
 
4065
      goto error;
 
4066
    if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
 
4067
    {
 
4068
      if (ha_start_consistent_snapshot(thd))
 
4069
        goto error;
 
4070
    }
 
4071
    my_ok(thd);
 
4072
    break;
 
4073
  case SQLCOM_COMMIT:
 
4074
    if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
 
4075
                              lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
 
4076
      goto error;
 
4077
    my_ok(thd);
 
4078
    break;
 
4079
  case SQLCOM_ROLLBACK:
 
4080
    if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
 
4081
                              lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
 
4082
      goto error;
 
4083
    my_ok(thd);
 
4084
    break;
 
4085
  case SQLCOM_RELEASE_SAVEPOINT:
 
4086
  {
 
4087
    SAVEPOINT *sv;
 
4088
    for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
 
4089
    {
 
4090
      if (my_strnncoll(system_charset_info,
 
4091
                       (uchar *)lex->ident.str, lex->ident.length,
 
4092
                       (uchar *)sv->name, sv->length) == 0)
 
4093
        break;
 
4094
    }
 
4095
    if (sv)
 
4096
    {
 
4097
      if (ha_release_savepoint(thd, sv))
 
4098
        res= TRUE; // cannot happen
 
4099
      else
 
4100
        my_ok(thd);
 
4101
      thd->transaction.savepoints=sv->prev;
 
4102
    }
 
4103
    else
 
4104
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
4105
    break;
 
4106
  }
 
4107
  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
 
4108
  {
 
4109
    SAVEPOINT *sv;
 
4110
    for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
 
4111
    {
 
4112
      if (my_strnncoll(system_charset_info,
 
4113
                       (uchar *)lex->ident.str, lex->ident.length,
 
4114
                       (uchar *)sv->name, sv->length) == 0)
 
4115
        break;
 
4116
    }
 
4117
    if (sv)
 
4118
    {
 
4119
      if (ha_rollback_to_savepoint(thd, sv))
 
4120
        res= TRUE; // cannot happen
 
4121
      else
 
4122
      {
 
4123
        if (((thd->options & OPTION_KEEP_LOG) || 
 
4124
             thd->transaction.all.modified_non_trans_table) &&
 
4125
            !thd->slave_thread)
 
4126
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
4127
                       ER_WARNING_NOT_COMPLETE_ROLLBACK,
 
4128
                       ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
 
4129
        my_ok(thd);
 
4130
      }
 
4131
      thd->transaction.savepoints=sv;
 
4132
    }
 
4133
    else
 
4134
      my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
 
4135
    break;
 
4136
  }
 
4137
  case SQLCOM_SAVEPOINT:
 
4138
    if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
 
4139
          thd->in_sub_stmt) || !opt_using_transactions)
 
4140
      my_ok(thd);
 
4141
    else
 
4142
    {
 
4143
      SAVEPOINT **sv, *newsv;
 
4144
      for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
 
4145
      {
 
4146
        if (my_strnncoll(system_charset_info,
 
4147
                         (uchar *)lex->ident.str, lex->ident.length,
 
4148
                         (uchar *)(*sv)->name, (*sv)->length) == 0)
 
4149
          break;
 
4150
      }
 
4151
      if (*sv) /* old savepoint of the same name exists */
 
4152
      {
 
4153
        newsv=*sv;
 
4154
        ha_release_savepoint(thd, *sv); // it cannot fail
 
4155
        *sv=(*sv)->prev;
 
4156
      }
 
4157
      else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
 
4158
                                               savepoint_alloc_size)) == 0)
 
4159
      {
 
4160
        my_error(ER_OUT_OF_RESOURCES, MYF(0));
 
4161
        break;
 
4162
      }
 
4163
      newsv->name=strmake_root(&thd->transaction.mem_root,
 
4164
                               lex->ident.str, lex->ident.length);
 
4165
      newsv->length=lex->ident.length;
 
4166
      /*
 
4167
        if we'll get an error here, don't add new savepoint to the list.
 
4168
        we'll lose a little bit of memory in transaction mem_root, but it'll
 
4169
        be free'd when transaction ends anyway
 
4170
      */
 
4171
      if (ha_savepoint(thd, newsv))
 
4172
        res= TRUE;
 
4173
      else
 
4174
      {
 
4175
        newsv->prev=thd->transaction.savepoints;
 
4176
        thd->transaction.savepoints=newsv;
 
4177
        my_ok(thd);
 
4178
      }
 
4179
    }
 
4180
    break;
 
4181
  case SQLCOM_CREATE_PROCEDURE:
 
4182
  case SQLCOM_CREATE_SPFUNCTION:
 
4183
  {
 
4184
    uint namelen;
 
4185
    char *name;
 
4186
    int sp_result= SP_INTERNAL_ERROR;
 
4187
 
 
4188
    DBUG_ASSERT(lex->sphead != 0);
 
4189
    DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
 
4190
    /*
 
4191
      Verify that the database name is allowed, optionally
 
4192
      lowercase it.
 
4193
    */
 
4194
    if (check_db_name(&lex->sphead->m_db))
 
4195
    {
 
4196
      my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
 
4197
      goto create_sp_error;
 
4198
    }
 
4199
 
 
4200
    /*
 
4201
      Check that a database directory with this name
 
4202
      exists. Design note: This won't work on virtual databases
 
4203
      like information_schema.
 
4204
    */
 
4205
    if (check_db_dir_existence(lex->sphead->m_db.str))
 
4206
    {
 
4207
      my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
 
4208
      goto create_sp_error;
 
4209
    }
 
4210
 
 
4211
    if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
 
4212
                     is_schema_db(lex->sphead->m_db.str,
 
4213
                                  lex->sphead->m_db.length)))
 
4214
      goto create_sp_error;
 
4215
 
 
4216
    if (end_active_trans(thd))
 
4217
      goto create_sp_error;
 
4218
 
 
4219
    name= lex->sphead->name(&namelen);
 
4220
#ifdef HAVE_DLOPEN
 
4221
    if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
 
4222
    {
 
4223
      udf_func *udf = find_udf(name, namelen);
 
4224
 
 
4225
      if (udf)
 
4226
      {
 
4227
        my_error(ER_UDF_EXISTS, MYF(0), name);
 
4228
        goto create_sp_error;
 
4229
      }
 
4230
    }
 
4231
#endif
 
4232
 
 
4233
    if (sp_process_definer(thd))
 
4234
      goto create_sp_error;
 
4235
 
 
4236
    res= (sp_result= lex->sphead->create(thd));
 
4237
    switch (sp_result) {
 
4238
    case SP_OK: {
 
4239
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
4240
      /* only add privileges if really neccessary */
 
4241
 
 
4242
      Security_context security_context;
 
4243
      bool restore_backup_context= false;
 
4244
      Security_context *backup= NULL;
 
4245
      LEX_USER *definer= thd->lex->definer;
 
4246
      /*
 
4247
        Check if the definer exists on slave, 
 
4248
        then use definer privilege to insert routine privileges to mysql.procs_priv.
 
4249
 
 
4250
        For current user of SQL thread has GLOBAL_ACL privilege, 
 
4251
        which doesn't any check routine privileges, 
 
4252
        so no routine privilege record  will insert into mysql.procs_priv.
 
4253
      */
 
4254
      if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
 
4255
      {
 
4256
        security_context.change_security_context(thd, 
 
4257
                                                 &thd->lex->definer->user,
 
4258
                                                 &thd->lex->definer->host,
 
4259
                                                 &thd->lex->sphead->m_db,
 
4260
                                                 &backup);
 
4261
        restore_backup_context= true;
 
4262
      }
 
4263
 
 
4264
      if (sp_automatic_privileges && !opt_noacl &&
 
4265
          check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
 
4266
                               lex->sphead->m_db.str, name,
 
4267
                               lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
 
4268
      {
 
4269
        if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
 
4270
                                lex->sql_command == SQLCOM_CREATE_PROCEDURE))
 
4271
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
4272
                       ER_PROC_AUTO_GRANT_FAIL,
 
4273
                       ER(ER_PROC_AUTO_GRANT_FAIL));
 
4274
      }
 
4275
 
 
4276
      /*
 
4277
        Restore current user with GLOBAL_ACL privilege of SQL thread
 
4278
      */ 
 
4279
      if (restore_backup_context)
 
4280
      {
 
4281
        DBUG_ASSERT(thd->slave_thread == 1);
 
4282
        thd->security_ctx->restore_security_context(thd, backup);
 
4283
      }
 
4284
 
 
4285
#endif
 
4286
    break;
 
4287
    }
 
4288
    case SP_WRITE_ROW_FAILED:
 
4289
      my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
 
4290
    break;
 
4291
    case SP_BAD_IDENTIFIER:
 
4292
      my_error(ER_TOO_LONG_IDENT, MYF(0), name);
 
4293
    break;
 
4294
    case SP_BODY_TOO_LONG:
 
4295
      my_error(ER_TOO_LONG_BODY, MYF(0), name);
 
4296
    break;
 
4297
    case SP_FLD_STORE_FAILED:
 
4298
      my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
 
4299
      break;
 
4300
    default:
 
4301
      my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
 
4302
    break;
 
4303
    } /* end switch */
 
4304
 
 
4305
    /*
 
4306
      Capture all errors within this CASE and
 
4307
      clean up the environment.
 
4308
    */
 
4309
create_sp_error:
 
4310
    if (sp_result != SP_OK )
 
4311
      goto error;
 
4312
    my_ok(thd);
 
4313
    break; /* break super switch */
 
4314
  } /* end case group bracket */
 
4315
  case SQLCOM_CALL:
 
4316
    {
 
4317
      sp_head *sp;
 
4318
 
 
4319
      /*
 
4320
        This will cache all SP and SF and open and lock all tables
 
4321
        required for execution.
 
4322
      */
 
4323
      if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
 
4324
          open_and_lock_tables(thd, all_tables))
 
4325
       goto error;
 
4326
 
 
4327
      /*
 
4328
        By this moment all needed SPs should be in cache so no need to look 
 
4329
        into DB. 
 
4330
      */
 
4331
      if (!(sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
 
4332
                                &thd->sp_proc_cache, TRUE)))
 
4333
      {
 
4334
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
 
4335
                 lex->spname->m_qname.str);
 
4336
        goto error;
 
4337
      }
 
4338
      else
 
4339
      {
 
4340
        ha_rows select_limit;
 
4341
        /* bits that should be cleared in thd->server_status */
 
4342
        uint bits_to_be_cleared= 0;
 
4343
        /*
 
4344
          Check that the stored procedure doesn't contain Dynamic SQL
 
4345
          and doesn't return result sets: such stored procedures can't
 
4346
          be called from a function or trigger.
 
4347
        */
 
4348
        if (thd->in_sub_stmt)
 
4349
        {
 
4350
          const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
 
4351
                              "trigger" : "function");
 
4352
          if (sp->is_not_allowed_in_function(where))
 
4353
            goto error;
 
4354
        }
 
4355
 
 
4356
        if (sp->m_flags & sp_head::MULTI_RESULTS)
 
4357
        {
 
4358
          if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
 
4359
          {
 
4360
            /*
 
4361
              The client does not support multiple result sets being sent
 
4362
              back
 
4363
            */
 
4364
            my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
 
4365
            goto error;
 
4366
          }
 
4367
          /*
 
4368
            If SERVER_MORE_RESULTS_EXISTS is not set,
 
4369
            then remember that it should be cleared
 
4370
          */
 
4371
          bits_to_be_cleared= (~thd->server_status &
 
4372
                               SERVER_MORE_RESULTS_EXISTS);
 
4373
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
 
4374
        }
 
4375
 
 
4376
        if (check_routine_access(thd, EXECUTE_ACL,
 
4377
                                 sp->m_db.str, sp->m_name.str, TRUE, FALSE))
 
4378
        {
 
4379
          goto error;
 
4380
        }
 
4381
        select_limit= thd->variables.select_limit;
 
4382
        thd->variables.select_limit= HA_POS_ERROR;
 
4383
 
 
4384
        /* 
 
4385
          We never write CALL statements into binlog:
 
4386
           - If the mode is non-prelocked, each statement will be logged
 
4387
             separately.
 
4388
           - If the mode is prelocked, the invoking statement will care
 
4389
             about writing into binlog.
 
4390
          So just execute the statement.
 
4391
        */
 
4392
        res= sp->execute_procedure(thd, &lex->value_list);
 
4393
        /*
 
4394
          If warnings have been cleared, we have to clear total_warn_count
 
4395
          too, otherwise the clients get confused.
 
4396
         */
 
4397
        if (thd->warn_list.is_empty())
 
4398
          thd->total_warn_count= 0;
 
4399
 
 
4400
        thd->variables.select_limit= select_limit;
 
4401
 
 
4402
        thd->server_status&= ~bits_to_be_cleared;
 
4403
 
 
4404
        if (!res)
 
4405
          my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
 
4406
                              thd->row_count_func));
 
4407
        else
 
4408
        {
 
4409
          DBUG_ASSERT(thd->is_error() || thd->killed);
 
4410
          goto error;           // Substatement should already have sent error
 
4411
        }
 
4412
      }
 
4413
      break;
 
4414
    }
 
4415
  case SQLCOM_ALTER_PROCEDURE:
 
4416
  case SQLCOM_ALTER_FUNCTION:
 
4417
    {
 
4418
      int sp_result;
 
4419
      sp_head *sp;
 
4420
      st_sp_chistics chistics;
 
4421
 
 
4422
      memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
 
4423
      if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
 
4424
        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
 
4425
                            &thd->sp_proc_cache, FALSE);
 
4426
      else
 
4427
        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
 
4428
                            &thd->sp_func_cache, FALSE);
 
4429
      mysql_reset_errors(thd, 0);
 
4430
      if (! sp)
 
4431
      {
 
4432
        if (lex->spname->m_db.str)
 
4433
          sp_result= SP_KEY_NOT_FOUND;
 
4434
        else
 
4435
        {
 
4436
          my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
4437
          goto error;
 
4438
        }
 
4439
      }
 
4440
      else
 
4441
      {
 
4442
        if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str, 
 
4443
                                 sp->m_name.str,
 
4444
                                 lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
 
4445
          goto error;
 
4446
 
 
4447
        if (end_active_trans(thd)) 
 
4448
          goto error;
 
4449
        memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
 
4450
        if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
 
4451
            !trust_function_creators &&  mysql_bin_log.is_open() &&
 
4452
            !sp->m_chistics->detistic &&
 
4453
            (chistics.daccess == SP_CONTAINS_SQL ||
 
4454
             chistics.daccess == SP_MODIFIES_SQL_DATA))
 
4455
        {
 
4456
          my_message(ER_BINLOG_UNSAFE_ROUTINE,
 
4457
                     ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
 
4458
          sp_result= SP_INTERNAL_ERROR;
 
4459
        }
 
4460
        else
 
4461
        {
 
4462
          /*
 
4463
            Note that if you implement the capability of ALTER FUNCTION to
 
4464
            alter the body of the function, this command should be made to
 
4465
            follow the restrictions that log-bin-trust-function-creators=0
 
4466
            already puts on CREATE FUNCTION.
 
4467
          */
 
4468
          /* Conditionally writes to binlog */
 
4469
 
 
4470
          int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
 
4471
                    TYPE_ENUM_PROCEDURE :
 
4472
                    TYPE_ENUM_FUNCTION;
 
4473
 
 
4474
          sp_result= sp_update_routine(thd,
 
4475
                                       type,
 
4476
                                       lex->spname,
 
4477
                                       &lex->sp_chistics);
 
4478
        }
 
4479
      }
 
4480
      switch (sp_result)
 
4481
      {
 
4482
      case SP_OK:
 
4483
        my_ok(thd);
 
4484
        break;
 
4485
      case SP_KEY_NOT_FOUND:
 
4486
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
 
4487
                 SP_COM_STRING(lex), lex->spname->m_qname.str);
 
4488
        goto error;
 
4489
      default:
 
4490
        my_error(ER_SP_CANT_ALTER, MYF(0),
 
4491
                 SP_COM_STRING(lex), lex->spname->m_qname.str);
 
4492
        goto error;
 
4493
      }
 
4494
      break;
 
4495
    }
 
4496
  case SQLCOM_DROP_PROCEDURE:
 
4497
  case SQLCOM_DROP_FUNCTION:
 
4498
    {
 
4499
      int sp_result;
 
4500
      int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
 
4501
                 TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
 
4502
 
 
4503
      sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
 
4504
      mysql_reset_errors(thd, 0);
 
4505
      if (sp_result == SP_OK)
 
4506
      {
 
4507
        char *db= lex->spname->m_db.str;
 
4508
        char *name= lex->spname->m_name.str;
 
4509
 
 
4510
        if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
 
4511
                                 lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
 
4512
          goto error;
 
4513
 
 
4514
        if (end_active_trans(thd)) 
 
4515
          goto error;
 
4516
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
4517
        if (sp_automatic_privileges && !opt_noacl &&
 
4518
            sp_revoke_privileges(thd, db, name, 
 
4519
                                 lex->sql_command == SQLCOM_DROP_PROCEDURE))
 
4520
        {
 
4521
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
 
4522
                       ER_PROC_AUTO_REVOKE_FAIL,
 
4523
                       ER(ER_PROC_AUTO_REVOKE_FAIL));
 
4524
        }
 
4525
#endif
 
4526
        /* Conditionally writes to binlog */
 
4527
 
 
4528
        int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ?
 
4529
                  TYPE_ENUM_PROCEDURE :
 
4530
                  TYPE_ENUM_FUNCTION;
 
4531
 
 
4532
        sp_result= sp_drop_routine(thd, type, lex->spname);
 
4533
      }
 
4534
      else
 
4535
      {
 
4536
#ifdef HAVE_DLOPEN
 
4537
        if (lex->sql_command == SQLCOM_DROP_FUNCTION)
 
4538
        {
 
4539
          udf_func *udf = find_udf(lex->spname->m_name.str,
 
4540
                                   lex->spname->m_name.length);
 
4541
          if (udf)
 
4542
          {
 
4543
            if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
 
4544
              goto error;
 
4545
 
 
4546
            if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
 
4547
            {
 
4548
              my_ok(thd);
 
4549
              break;
 
4550
            }
 
4551
          }
 
4552
        }
 
4553
#endif
 
4554
        if (lex->spname->m_db.str)
 
4555
          sp_result= SP_KEY_NOT_FOUND;
 
4556
        else
 
4557
        {
 
4558
          my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
4559
          goto error;
 
4560
        }
 
4561
      }
 
4562
      res= sp_result;
 
4563
      switch (sp_result) {
 
4564
      case SP_OK:
 
4565
        my_ok(thd);
 
4566
        break;
 
4567
      case SP_KEY_NOT_FOUND:
 
4568
        if (lex->drop_if_exists)
 
4569
        {
 
4570
          res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
4571
          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
4572
                              ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
 
4573
                              SP_COM_STRING(lex), lex->spname->m_name.str);
 
4574
          if (!res)
 
4575
            my_ok(thd);
 
4576
          break;
 
4577
        }
 
4578
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
 
4579
                 SP_COM_STRING(lex), lex->spname->m_qname.str);
 
4580
        goto error;
 
4581
      default:
 
4582
        my_error(ER_SP_DROP_FAILED, MYF(0),
 
4583
                 SP_COM_STRING(lex), lex->spname->m_qname.str);
 
4584
        goto error;
 
4585
      }
 
4586
      break;
 
4587
    }
 
4588
  case SQLCOM_SHOW_CREATE_PROC:
 
4589
    {
 
4590
      if (sp_show_create_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname))
 
4591
      {
 
4592
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
 
4593
                 SP_COM_STRING(lex), lex->spname->m_name.str);
 
4594
        goto error;
 
4595
      }
 
4596
      break;
 
4597
    }
 
4598
  case SQLCOM_SHOW_CREATE_FUNC:
 
4599
    {
 
4600
      if (sp_show_create_routine(thd, TYPE_ENUM_FUNCTION, lex->spname))
 
4601
      {
 
4602
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
 
4603
                 SP_COM_STRING(lex), lex->spname->m_name.str);
 
4604
        goto error;
 
4605
      }
 
4606
      break;
 
4607
    }
 
4608
#ifndef DBUG_OFF
 
4609
  case SQLCOM_SHOW_PROC_CODE:
 
4610
  case SQLCOM_SHOW_FUNC_CODE:
 
4611
    {
 
4612
      sp_head *sp;
 
4613
 
 
4614
      if (lex->sql_command == SQLCOM_SHOW_PROC_CODE)
 
4615
        sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
 
4616
                            &thd->sp_proc_cache, FALSE);
 
4617
      else
 
4618
        sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
 
4619
                            &thd->sp_func_cache, FALSE);
 
4620
      if (!sp || sp->show_routine_code(thd))
 
4621
      {
 
4622
        /* We don't distinguish between errors for now */
 
4623
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
 
4624
                 SP_COM_STRING(lex), lex->spname->m_name.str);
 
4625
        goto error;
 
4626
      }
 
4627
      break;
 
4628
    }
 
4629
#endif // ifndef DBUG_OFF
 
4630
  case SQLCOM_SHOW_CREATE_TRIGGER:
 
4631
    {
 
4632
      if (lex->spname->m_name.length > NAME_LEN)
 
4633
      {
 
4634
        my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
 
4635
        goto error;
 
4636
      }
 
4637
 
 
4638
      if (show_create_trigger(thd, lex->spname))
 
4639
        goto error; /* Error has been already logged. */
 
4640
 
 
4641
      break;
 
4642
    }
 
4643
  case SQLCOM_CREATE_VIEW:
 
4644
    {
 
4645
      /*
 
4646
        Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
 
4647
        as specified through the thd->lex->create_view_mode flag.
 
4648
      */
 
4649
      if (end_active_trans(thd))
 
4650
        goto error;
 
4651
 
 
4652
      res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
 
4653
      break;
 
4654
    }
 
4655
  case SQLCOM_DROP_VIEW:
 
4656
    {
 
4657
      if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) ||
 
4658
          end_active_trans(thd))
 
4659
        goto error;
 
4660
      /* Conditionally writes to binlog. */
 
4661
      res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
 
4662
      break;
 
4663
    }
 
4664
  case SQLCOM_CREATE_TRIGGER:
 
4665
  {
 
4666
    if (end_active_trans(thd))
 
4667
      goto error;
 
4668
 
 
4669
    /* Conditionally writes to binlog. */
 
4670
    res= mysql_create_or_drop_trigger(thd, all_tables, 1);
 
4671
 
 
4672
    break;
 
4673
  }
 
4674
  case SQLCOM_DROP_TRIGGER:
 
4675
  {
 
4676
    if (end_active_trans(thd))
 
4677
      goto error;
 
4678
 
 
4679
    /* Conditionally writes to binlog. */
 
4680
    res= mysql_create_or_drop_trigger(thd, all_tables, 0);
 
4681
    break;
 
4682
  }
 
4683
  case SQLCOM_XA_START:
 
4684
    if (thd->transaction.xid_state.xa_state == XA_IDLE &&
 
4685
        thd->lex->xa_opt == XA_RESUME)
 
4686
    {
 
4687
      if (! thd->transaction.xid_state.xid.eq(thd->lex->xid))
 
4688
      {
 
4689
        my_error(ER_XAER_NOTA, MYF(0));
 
4690
        break;
 
4691
      }
 
4692
      thd->transaction.xid_state.xa_state=XA_ACTIVE;
 
4693
      my_ok(thd);
 
4694
      break;
 
4695
    }
 
4696
    if (thd->lex->xa_opt != XA_NONE)
 
4697
    { // JOIN is not supported yet. TODO
 
4698
      my_error(ER_XAER_INVAL, MYF(0));
 
4699
      break;
 
4700
    }
 
4701
    if (thd->transaction.xid_state.xa_state != XA_NOTR)
 
4702
    {
 
4703
      my_error(ER_XAER_RMFAIL, MYF(0),
 
4704
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
4705
      break;
 
4706
    }
 
4707
    if (thd->active_transaction() || thd->locked_tables)
 
4708
    {
 
4709
      my_error(ER_XAER_OUTSIDE, MYF(0));
 
4710
      break;
 
4711
    }
 
4712
    if (xid_cache_search(thd->lex->xid))
 
4713
    {
 
4714
      my_error(ER_XAER_DUPID, MYF(0));
 
4715
      break;
 
4716
    }
 
4717
    DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
 
4718
    thd->transaction.xid_state.xa_state=XA_ACTIVE;
 
4719
    thd->transaction.xid_state.rm_error= 0;
 
4720
    thd->transaction.xid_state.xid.set(thd->lex->xid);
 
4721
    xid_cache_insert(&thd->transaction.xid_state);
 
4722
    thd->transaction.all.modified_non_trans_table= FALSE;
 
4723
    thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
 
4724
    thd->server_status|= SERVER_STATUS_IN_TRANS;
 
4725
    my_ok(thd);
 
4726
    break;
 
4727
  case SQLCOM_XA_END:
 
4728
    /* fake it */
 
4729
    if (thd->lex->xa_opt != XA_NONE)
 
4730
    { // SUSPEND and FOR MIGRATE are not supported yet. TODO
 
4731
      my_error(ER_XAER_INVAL, MYF(0));
 
4732
      break;
 
4733
    }
 
4734
    if (thd->transaction.xid_state.xa_state != XA_ACTIVE)
 
4735
    {
 
4736
      my_error(ER_XAER_RMFAIL, MYF(0),
 
4737
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
4738
      break;
 
4739
    }
 
4740
    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
 
4741
    {
 
4742
      my_error(ER_XAER_NOTA, MYF(0));
 
4743
      break;
 
4744
    }
 
4745
    if (xa_trans_rolled_back(&thd->transaction.xid_state))
 
4746
      break;
 
4747
    thd->transaction.xid_state.xa_state=XA_IDLE;
 
4748
    my_ok(thd);
 
4749
    break;
 
4750
  case SQLCOM_XA_PREPARE:
 
4751
    if (thd->transaction.xid_state.xa_state != XA_IDLE)
 
4752
    {
 
4753
      my_error(ER_XAER_RMFAIL, MYF(0),
 
4754
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
4755
      break;
 
4756
    }
 
4757
    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
 
4758
    {
 
4759
      my_error(ER_XAER_NOTA, MYF(0));
 
4760
      break;
 
4761
    }
 
4762
    if (ha_prepare(thd))
 
4763
    {
 
4764
      my_error(ER_XA_RBROLLBACK, MYF(0));
 
4765
      xid_cache_delete(&thd->transaction.xid_state);
 
4766
      thd->transaction.xid_state.xa_state=XA_NOTR;
 
4767
      break;
 
4768
    }
 
4769
    thd->transaction.xid_state.xa_state=XA_PREPARED;
 
4770
    my_ok(thd);
 
4771
    break;
 
4772
  case SQLCOM_XA_COMMIT:
 
4773
    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
 
4774
    {
 
4775
      XID_STATE *xs=xid_cache_search(thd->lex->xid);
 
4776
      if (!xs || xs->in_thd)
 
4777
        my_error(ER_XAER_NOTA, MYF(0));
 
4778
      else if (xa_trans_rolled_back(xs))
 
4779
      {
 
4780
        ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
 
4781
        xid_cache_delete(xs);
 
4782
        break;
 
4783
      }
 
4784
      else
 
4785
      {
 
4786
        ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
 
4787
        xid_cache_delete(xs);
 
4788
        my_ok(thd);
 
4789
      }
 
4790
      break;
 
4791
    }
 
4792
    if (xa_trans_rolled_back(&thd->transaction.xid_state))
 
4793
    {
 
4794
      xa_trans_rollback(thd);
 
4795
      break;
 
4796
    }
 
4797
    if (thd->transaction.xid_state.xa_state == XA_IDLE &&
 
4798
        thd->lex->xa_opt == XA_ONE_PHASE)
 
4799
    {
 
4800
      int r;
 
4801
      if ((r= ha_commit(thd)))
 
4802
        my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
 
4803
      else
 
4804
        my_ok(thd);
 
4805
    }
 
4806
    else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
 
4807
             thd->lex->xa_opt == XA_NONE)
 
4808
    {
 
4809
      if (wait_if_global_read_lock(thd, 0, 0))
 
4810
      {
 
4811
        ha_rollback(thd);
 
4812
        my_error(ER_XAER_RMERR, MYF(0));
 
4813
      }
 
4814
      else
 
4815
      {
 
4816
        if (ha_commit_one_phase(thd, 1))
 
4817
          my_error(ER_XAER_RMERR, MYF(0));
 
4818
        else
 
4819
          my_ok(thd);
 
4820
        start_waiting_global_read_lock(thd);
 
4821
      }
 
4822
    }
 
4823
    else
 
4824
    {
 
4825
      my_error(ER_XAER_RMFAIL, MYF(0),
 
4826
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
4827
      break;
 
4828
    }
 
4829
    thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
 
4830
    thd->transaction.all.modified_non_trans_table= FALSE;
 
4831
    thd->server_status&= ~SERVER_STATUS_IN_TRANS;
 
4832
    xid_cache_delete(&thd->transaction.xid_state);
 
4833
    thd->transaction.xid_state.xa_state=XA_NOTR;
 
4834
    break;
 
4835
  case SQLCOM_XA_ROLLBACK:
 
4836
    if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
 
4837
    {
 
4838
      XID_STATE *xs=xid_cache_search(thd->lex->xid);
 
4839
      if (!xs || xs->in_thd)
 
4840
        my_error(ER_XAER_NOTA, MYF(0));
 
4841
      else
 
4842
      {
 
4843
        bool ok= !xa_trans_rolled_back(xs);
 
4844
        ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
 
4845
        xid_cache_delete(xs);
 
4846
        if (ok)
 
4847
          my_ok(thd);
 
4848
      }
 
4849
      break;
 
4850
    }
 
4851
    if (thd->transaction.xid_state.xa_state != XA_IDLE &&
 
4852
        thd->transaction.xid_state.xa_state != XA_PREPARED &&
 
4853
        thd->transaction.xid_state.xa_state != XA_ROLLBACK_ONLY)
 
4854
    {
 
4855
      my_error(ER_XAER_RMFAIL, MYF(0),
 
4856
               xa_state_names[thd->transaction.xid_state.xa_state]);
 
4857
      break;
 
4858
    }
 
4859
    if (xa_trans_rollback(thd))
 
4860
      my_error(ER_XAER_RMERR, MYF(0));
 
4861
    else
 
4862
      my_ok(thd);
 
4863
    break;
 
4864
  case SQLCOM_XA_RECOVER:
 
4865
    res= mysql_xa_recover(thd);
 
4866
    break;
 
4867
  case SQLCOM_ALTER_TABLESPACE:
 
4868
    if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0,
 
4869
                     thd->db ? is_schema_db(thd->db, thd->db_length) : 0))
 
4870
      break;
 
4871
    if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
 
4872
      my_ok(thd);
 
4873
    break;
 
4874
  case SQLCOM_INSTALL_PLUGIN:
 
4875
    if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
 
4876
                                     &thd->lex->ident)))
 
4877
      my_ok(thd);
 
4878
    break;
 
4879
  case SQLCOM_UNINSTALL_PLUGIN:
 
4880
    if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
 
4881
      my_ok(thd);
 
4882
    break;
 
4883
  case SQLCOM_BINLOG_BASE64_EVENT:
 
4884
  {
 
4885
#ifndef EMBEDDED_LIBRARY
 
4886
    mysql_client_binlog_statement(thd);
 
4887
#else /* EMBEDDED_LIBRARY */
 
4888
    my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
 
4889
#endif /* EMBEDDED_LIBRARY */
 
4890
    break;
 
4891
  }
 
4892
  case SQLCOM_CREATE_SERVER:
 
4893
  {
 
4894
    int error;
 
4895
    LEX *lex= thd->lex;
 
4896
    DBUG_PRINT("info", ("case SQLCOM_CREATE_SERVER"));
 
4897
 
 
4898
    if (check_global_access(thd, SUPER_ACL))
 
4899
      break;
 
4900
 
 
4901
    if ((error= create_server(thd, &lex->server_options)))
 
4902
    {
 
4903
      DBUG_PRINT("info", ("problem creating server <%s>",
 
4904
                          lex->server_options.server_name));
 
4905
      my_error(error, MYF(0), lex->server_options.server_name);
 
4906
      break;
 
4907
    }
 
4908
    my_ok(thd, 1);
 
4909
    break;
 
4910
  }
 
4911
  case SQLCOM_ALTER_SERVER:
 
4912
  {
 
4913
    int error;
 
4914
    LEX *lex= thd->lex;
 
4915
    DBUG_PRINT("info", ("case SQLCOM_ALTER_SERVER"));
 
4916
 
 
4917
    if (check_global_access(thd, SUPER_ACL))
 
4918
      break;
 
4919
 
 
4920
    if ((error= alter_server(thd, &lex->server_options)))
 
4921
    {
 
4922
      DBUG_PRINT("info", ("problem altering server <%s>",
 
4923
                          lex->server_options.server_name));
 
4924
      my_error(error, MYF(0), lex->server_options.server_name);
 
4925
      break;
 
4926
    }
 
4927
    my_ok(thd, 1);
 
4928
    break;
 
4929
  }
 
4930
  case SQLCOM_DROP_SERVER:
 
4931
  {
 
4932
    int err_code;
 
4933
    LEX *lex= thd->lex;
 
4934
    DBUG_PRINT("info", ("case SQLCOM_DROP_SERVER"));
 
4935
 
 
4936
    if (check_global_access(thd, SUPER_ACL))
 
4937
      break;
 
4938
 
 
4939
    if ((err_code= drop_server(thd, &lex->server_options)))
 
4940
    {
 
4941
      if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
 
4942
      {
 
4943
        DBUG_PRINT("info", ("problem dropping server %s",
 
4944
                            lex->server_options.server_name));
 
4945
        my_error(err_code, MYF(0), lex->server_options.server_name);
 
4946
      }
 
4947
      else
 
4948
      {
 
4949
        my_ok(thd, 0);
 
4950
      }
 
4951
      break;
 
4952
    }
 
4953
    my_ok(thd, 1);
 
4954
    break;
 
4955
  }
 
4956
  default:
 
4957
#ifndef EMBEDDED_LIBRARY
 
4958
    DBUG_ASSERT(0);                             /* Impossible */
 
4959
#endif
 
4960
    my_ok(thd);
 
4961
    break;
 
4962
  }
 
4963
  thd_proc_info(thd, "query end");
 
4964
 
 
4965
  /*
 
4966
    Binlog-related cleanup:
 
4967
    Reset system variables temporarily modified by SET ONE SHOT.
 
4968
 
 
4969
    Exception: If this is a SET, do nothing. This is to allow
 
4970
    mysqlbinlog to print many SET commands (in this case we want the
 
4971
    charset temp setting to live until the real query). This is also
 
4972
    needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
 
4973
    immediately.
 
4974
  */
 
4975
  if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
 
4976
    reset_one_shot_variables(thd);
 
4977
 
 
4978
  /*
 
4979
    The return value for ROW_COUNT() is "implementation dependent" if the
 
4980
    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
 
4981
    wants. We also keep the last value in case of SQLCOM_CALL or
 
4982
    SQLCOM_EXECUTE.
 
4983
  */
 
4984
  if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
 
4985
    thd->row_count_func= -1;
 
4986
 
 
4987
  goto finish;
 
4988
 
 
4989
error:
 
4990
  res= TRUE;
 
4991
 
 
4992
finish:
 
4993
  if (need_start_waiting)
 
4994
  {
 
4995
    /*
 
4996
      Release the protection against the global read lock and wake
 
4997
      everyone, who might want to set a global read lock.
 
4998
    */
 
4999
    start_waiting_global_read_lock(thd);
 
5000
  }
 
5001
  DBUG_RETURN(res || thd->is_error());
 
5002
}
 
5003
 
 
5004
 
 
5005
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
 
5006
{
 
5007
  LEX   *lex= thd->lex;
 
5008
  select_result *result=lex->result;
 
5009
  bool res;
 
5010
  /* assign global limit variable if limit is not given */
 
5011
  {
 
5012
    SELECT_LEX *param= lex->unit.global_parameters;
 
5013
    if (!param->explicit_limit)
 
5014
      param->select_limit=
 
5015
        new Item_int((ulonglong) thd->variables.select_limit);
 
5016
  }
 
5017
  if (!(res= open_and_lock_tables(thd, all_tables)))
 
5018
  {
 
5019
    if (lex->describe)
 
5020
    {
 
5021
      /*
 
5022
        We always use select_send for EXPLAIN, even if it's an EXPLAIN
 
5023
        for SELECT ... INTO OUTFILE: a user application should be able
 
5024
        to prepend EXPLAIN to any query and receive output for it,
 
5025
        even if the query itself redirects the output.
 
5026
      */
 
5027
      if (!(result= new select_send()))
 
5028
        return 1;                               /* purecov: inspected */
 
5029
      thd->send_explain_fields(result);
 
5030
      res= mysql_explain_union(thd, &thd->lex->unit, result);
 
5031
      if (lex->describe & DESCRIBE_EXTENDED)
 
5032
      {
 
5033
        char buff[1024];
 
5034
        String str(buff,(uint32) sizeof(buff), system_charset_info);
 
5035
        str.length(0);
 
5036
        thd->lex->unit.print(&str, QT_ORDINARY);
 
5037
        str.append('\0');
 
5038
        push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
5039
                     ER_YES, str.ptr());
 
5040
      }
 
5041
      if (res)
 
5042
        result->abort();
 
5043
      else
 
5044
        result->send_eof();
 
5045
      delete result;
 
5046
    }
 
5047
    else
 
5048
    {
 
5049
      if (!result && !(result= new select_send()))
 
5050
        return 1;                               /* purecov: inspected */
 
5051
      query_cache_store_query(thd, all_tables);
 
5052
      res= handle_select(thd, lex, result, 0);
 
5053
      if (result != lex->result)
 
5054
        delete result;
 
5055
    }
 
5056
  }
 
5057
  return res;
 
5058
}
 
5059
 
 
5060
 
 
5061
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
5062
/**
 
5063
  Check grants for commands which work only with one table.
 
5064
 
 
5065
  @param thd                    Thread handler
 
5066
  @param privilege              requested privilege
 
5067
  @param all_tables             global table list of query
 
5068
  @param no_errors              FALSE/TRUE - report/don't report error to
 
5069
                            the client (using my_error() call).
 
5070
 
 
5071
  @retval
 
5072
    0   OK
 
5073
  @retval
 
5074
    1   access denied, error is sent to client
 
5075
*/
 
5076
 
 
5077
bool check_single_table_access(THD *thd, ulong privilege, 
 
5078
                               TABLE_LIST *all_tables, bool no_errors)
 
5079
{
 
5080
  Security_context * backup_ctx= thd->security_ctx;
 
5081
 
 
5082
  /* we need to switch to the saved context (if any) */
 
5083
  if (all_tables->security_ctx)
 
5084
    thd->security_ctx= all_tables->security_ctx;
 
5085
 
 
5086
  const char *db_name;
 
5087
  if ((all_tables->view || all_tables->field_translation) &&
 
5088
      !all_tables->schema_table)
 
5089
    db_name= all_tables->view_db.str;
 
5090
  else
 
5091
    db_name= all_tables->db;
 
5092
 
 
5093
  if (check_access(thd, privilege, db_name,
 
5094
                   &all_tables->grant.privilege, 0, no_errors,
 
5095
                   test(all_tables->schema_table)))
 
5096
    goto deny;
 
5097
 
 
5098
  /* Show only 1 table for check_grant */
 
5099
  if (!(all_tables->belong_to_view &&
 
5100
        (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
 
5101
      check_grant(thd, privilege, all_tables, 0, 1, no_errors))
 
5102
    goto deny;
 
5103
 
 
5104
  thd->security_ctx= backup_ctx;
 
5105
  return 0;
 
5106
 
 
5107
deny:
 
5108
  thd->security_ctx= backup_ctx;
 
5109
  return 1;
 
5110
}
 
5111
 
 
5112
/**
 
5113
  Check grants for commands which work only with one table and all other
 
5114
  tables belonging to subselects or implicitly opened tables.
 
5115
 
 
5116
  @param thd                    Thread handler
 
5117
  @param privilege              requested privilege
 
5118
  @param all_tables             global table list of query
 
5119
 
 
5120
  @retval
 
5121
    0   OK
 
5122
  @retval
 
5123
    1   access denied, error is sent to client
 
5124
*/
 
5125
 
 
5126
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
 
5127
{
 
5128
  if (check_single_table_access (thd,privilege,all_tables, FALSE))
 
5129
    return 1;
 
5130
 
 
5131
  /* Check rights on tables of subselects and implictly opened tables */
 
5132
  TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
 
5133
  if ((subselects_tables= all_tables->next_global))
 
5134
  {
 
5135
    /*
 
5136
      Access rights asked for the first table of a view should be the same
 
5137
      as for the view
 
5138
    */
 
5139
    if (view && subselects_tables->belong_to_view == view)
 
5140
    {
 
5141
      if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
 
5142
        return 1;
 
5143
      subselects_tables= subselects_tables->next_global;
 
5144
    }
 
5145
    if (subselects_tables &&
 
5146
        (check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE)))
 
5147
      return 1;
 
5148
  }
 
5149
  return 0;
 
5150
}
 
5151
 
 
5152
 
 
5153
/**
 
5154
  Get the user (global) and database privileges for all used tables.
 
5155
 
 
5156
  @param save_priv    In this we store global and db level grants for the
 
5157
                      table. Note that we don't store db level grants if the
 
5158
                      global grants is enough to satisfy the request and the
 
5159
                      global grants contains a SELECT grant.
 
5160
 
 
5161
  @note
 
5162
    The idea of EXTRA_ACL is that one will be granted access to the table if
 
5163
    one has the asked privilege on any column combination of the table; For
 
5164
    example to be able to check a table one needs to have SELECT privilege on
 
5165
    any column of the table.
 
5166
 
 
5167
  @retval
 
5168
    0  ok
 
5169
  @retval
 
5170
    1  If we can't get the privileges and we don't use table/column
 
5171
    grants.
 
5172
*/
 
5173
bool
 
5174
check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
 
5175
             bool dont_check_global_grants, bool no_errors, bool schema_db)
 
5176
{
 
5177
  Security_context *sctx= thd->security_ctx;
 
5178
  ulong db_access;
 
5179
  /*
 
5180
    GRANT command:
 
5181
    In case of database level grant the database name may be a pattern,
 
5182
    in case of table|column level grant the database name can not be a pattern.
 
5183
    We use 'dont_check_global_grants' as a flag to determine
 
5184
    if it's database level grant command 
 
5185
    (see SQLCOM_GRANT case, mysql_execute_command() function) and
 
5186
    set db_is_pattern according to 'dont_check_global_grants' value.
 
5187
  */
 
5188
  bool  db_is_pattern= (test(want_access & GRANT_ACL) &&
 
5189
                        dont_check_global_grants);
 
5190
  ulong dummy;
 
5191
  DBUG_ENTER("check_access");
 
5192
  DBUG_PRINT("enter",("db: %s  want_access: %lu  master_access: %lu",
 
5193
                      db ? db : "", want_access, sctx->master_access));
 
5194
  if (save_priv)
 
5195
    *save_priv=0;
 
5196
  else
 
5197
    save_priv= &dummy;
 
5198
 
 
5199
  thd_proc_info(thd, "checking permissions");
 
5200
  if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
 
5201
  {
 
5202
    DBUG_PRINT("error",("No database"));
 
5203
    if (!no_errors)
 
5204
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
 
5205
                 MYF(0));                       /* purecov: tested */
 
5206
    DBUG_RETURN(TRUE);                          /* purecov: tested */
 
5207
  }
 
5208
 
 
5209
  if (schema_db)
 
5210
  {
 
5211
    if ((!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL)) ||
 
5212
        (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
 
5213
    {
 
5214
      if (!no_errors)
 
5215
      {
 
5216
        const char *db_name= db ? db : thd->db;
 
5217
        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
 
5218
                 sctx->priv_user, sctx->priv_host, db_name);
 
5219
      }
 
5220
      DBUG_RETURN(TRUE);
 
5221
    }
 
5222
    else
 
5223
    {
 
5224
      *save_priv= SELECT_ACL;
 
5225
      DBUG_RETURN(FALSE);
 
5226
    }
 
5227
  }
 
5228
 
 
5229
  if ((sctx->master_access & want_access) == want_access)
 
5230
  {
 
5231
    /*
 
5232
      If we don't have a global SELECT privilege, we have to get the database
 
5233
      specific access rights to be able to handle queries of type
 
5234
      UPDATE t1 SET a=1 WHERE b > 0
 
5235
    */
 
5236
    db_access= sctx->db_access;
 
5237
    if (!(sctx->master_access & SELECT_ACL) &&
 
5238
        (db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
 
5239
      db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
 
5240
                        db_is_pattern);
 
5241
    *save_priv=sctx->master_access | db_access;
 
5242
    DBUG_RETURN(FALSE);
 
5243
  }
 
5244
  if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
 
5245
      (! db && dont_check_global_grants))
 
5246
  {                                             // We can never grant this
 
5247
    DBUG_PRINT("error",("No possible access"));
 
5248
    if (!no_errors)
 
5249
      my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
 
5250
               sctx->priv_user,
 
5251
               sctx->priv_host,
 
5252
               (thd->password ?
 
5253
                ER(ER_YES) :
 
5254
                ER(ER_NO)));                    /* purecov: tested */
 
5255
    DBUG_RETURN(TRUE);                          /* purecov: tested */
 
5256
  }
 
5257
 
 
5258
  if (db == any_db)
 
5259
    DBUG_RETURN(FALSE);                         // Allow select on anything
 
5260
 
 
5261
  if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
 
5262
    db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
 
5263
                       db_is_pattern);
 
5264
  else
 
5265
    db_access= sctx->db_access;
 
5266
  DBUG_PRINT("info",("db_access: %lu", db_access));
 
5267
  /* Remove SHOW attribute and access rights we already have */
 
5268
  want_access &= ~(sctx->master_access | EXTRA_ACL);
 
5269
  DBUG_PRINT("info",("db_access: %lu  want_access: %lu",
 
5270
                     db_access, want_access));
 
5271
  db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
 
5272
 
 
5273
  if (db_access == want_access ||
 
5274
      (!dont_check_global_grants &&
 
5275
       !(want_access & ~(db_access | TABLE_ACLS | PROC_ACLS))))
 
5276
    DBUG_RETURN(FALSE);                         /* Ok */
 
5277
 
 
5278
  DBUG_PRINT("error",("Access denied"));
 
5279
  if (!no_errors)
 
5280
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
 
5281
             sctx->priv_user, sctx->priv_host,
 
5282
             (db ? db : (thd->db ?
 
5283
                         thd->db :
 
5284
                         "unknown")));          /* purecov: tested */
 
5285
  DBUG_RETURN(TRUE);                            /* purecov: tested */
 
5286
}
 
5287
 
 
5288
 
 
5289
static bool check_show_access(THD *thd, TABLE_LIST *table)
 
5290
{
 
5291
  switch (get_schema_table_idx(table->schema_table)) {
 
5292
  case SCH_SCHEMATA:
 
5293
    return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
 
5294
      check_global_access(thd, SHOW_DB_ACL);
 
5295
 
 
5296
  case SCH_TABLE_NAMES:
 
5297
  case SCH_TABLES:
 
5298
  case SCH_VIEWS:
 
5299
  case SCH_TRIGGERS:
 
5300
  case SCH_EVENTS:
 
5301
  {
 
5302
    const char *dst_db_name= table->schema_select_lex->db;
 
5303
 
 
5304
    DBUG_ASSERT(dst_db_name);
 
5305
 
 
5306
    if (check_access(thd, SELECT_ACL, dst_db_name,
 
5307
                     &thd->col_access, FALSE, FALSE,
 
5308
                     is_schema_db(dst_db_name)))
 
5309
      return TRUE;
 
5310
 
 
5311
    if (!thd->col_access && check_grant_db(thd, dst_db_name))
 
5312
    {
 
5313
      my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
 
5314
               thd->security_ctx->priv_user,
 
5315
               thd->security_ctx->priv_host,
 
5316
               dst_db_name);
 
5317
      return TRUE;
 
5318
    }
 
5319
 
 
5320
    return FALSE;
 
5321
  }
 
5322
 
 
5323
  case SCH_COLUMNS:
 
5324
  case SCH_STATISTICS:
 
5325
  {
 
5326
    TABLE_LIST *dst_table;
 
5327
    dst_table= (TABLE_LIST *) table->schema_select_lex->table_list.first;
 
5328
 
 
5329
    DBUG_ASSERT(dst_table);
 
5330
 
 
5331
    if (check_access(thd, SELECT_ACL | EXTRA_ACL,
 
5332
                     dst_table->db,
 
5333
                     &dst_table->grant.privilege,
 
5334
                     FALSE, FALSE,
 
5335
                     test(dst_table->schema_table)))
 
5336
      return FALSE;
 
5337
 
 
5338
    return (check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE));
 
5339
  }
 
5340
  default:
 
5341
    break;
 
5342
  }
 
5343
 
 
5344
  return FALSE;
 
5345
}
 
5346
 
 
5347
 
 
5348
/**
 
5349
  Check the privilege for all used tables.
 
5350
 
 
5351
  @param    thd          Thread context
 
5352
  @param    want_access  Privileges requested
 
5353
  @param    tables       List of tables to be checked
 
5354
  @param    number       Check at most this number of tables.
 
5355
  @param    no_errors    FALSE/TRUE - report/don't report error to
 
5356
                         the client (using my_error() call).
 
5357
 
 
5358
  @note
 
5359
    Table privileges are cached in the table list for GRANT checking.
 
5360
    This functions assumes that table list used and
 
5361
    thd->lex->query_tables_own_last value correspond to each other
 
5362
    (the latter should be either 0 or point to next_global member
 
5363
    of one of elements of this table list).
 
5364
 
 
5365
  @retval  FALSE   OK
 
5366
  @retval  TRUE    Access denied
 
5367
*/
 
5368
 
 
5369
bool
 
5370
check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
 
5371
                   uint number, bool no_errors)
 
5372
{
 
5373
  TABLE_LIST *org_tables= tables;
 
5374
  TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
 
5375
  uint i= 0;
 
5376
  Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
 
5377
  /*
 
5378
    The check that first_not_own_table is not reached is for the case when
 
5379
    the given table list refers to the list for prelocking (contains tables
 
5380
    of other queries). For simple queries first_not_own_table is 0.
 
5381
  */
 
5382
  for (; i < number && tables != first_not_own_table;
 
5383
       tables= tables->next_global, i++)
 
5384
  {
 
5385
    if (tables->security_ctx)
 
5386
      sctx= tables->security_ctx;
 
5387
    else
 
5388
      sctx= backup_ctx;
 
5389
 
 
5390
    if (tables->schema_table && 
 
5391
        (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
 
5392
    {
 
5393
      if (!no_errors)
 
5394
        my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
 
5395
                 sctx->priv_user, sctx->priv_host,
 
5396
                 INFORMATION_SCHEMA_NAME.str);
 
5397
      return TRUE;
 
5398
    }
 
5399
    /*
 
5400
       Register access for view underlying table.
 
5401
       Remove SHOW_VIEW_ACL, because it will be checked during making view
 
5402
     */
 
5403
    tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
 
5404
 
 
5405
    if (tables->schema_table_reformed)
 
5406
    {
 
5407
      if (check_show_access(thd, tables))
 
5408
        goto deny;
 
5409
 
 
5410
      continue;
 
5411
    }
 
5412
 
 
5413
    if (tables->is_anonymous_derived_table() ||
 
5414
        (tables->table && (int)tables->table->s->tmp_table))
 
5415
      continue;
 
5416
    thd->security_ctx= sctx;
 
5417
    if ((sctx->master_access & want_access) ==
 
5418
        (want_access & ~EXTRA_ACL) &&
 
5419
        thd->db)
 
5420
      tables->grant.privilege= want_access;
 
5421
    else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0)
 
5422
    {
 
5423
      if (check_access(thd, want_access, tables->get_db_name(),
 
5424
                       &tables->grant.privilege, 0, no_errors, 
 
5425
                       test(tables->schema_table)))
 
5426
        goto deny;                            // Access denied
 
5427
    }
 
5428
    else if (check_access(thd, want_access, tables->get_db_name(),
 
5429
                          &tables->grant.privilege, 0, no_errors, 
 
5430
                          test(tables->schema_table)))
 
5431
      goto deny;
 
5432
  }
 
5433
  thd->security_ctx= backup_ctx;
 
5434
  return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
 
5435
                       test(want_access & EXTRA_ACL), number, no_errors);
 
5436
deny:
 
5437
  thd->security_ctx= backup_ctx;
 
5438
  return TRUE;
 
5439
}
 
5440
 
 
5441
 
 
5442
bool
 
5443
check_routine_access(THD *thd, ulong want_access,char *db, char *name,
 
5444
                     bool is_proc, bool no_errors)
 
5445
{
 
5446
  TABLE_LIST tables[1];
 
5447
  
 
5448
  bzero((char *)tables, sizeof(TABLE_LIST));
 
5449
  tables->db= db;
 
5450
  tables->table_name= tables->alias= name;
 
5451
  
 
5452
  /*
 
5453
    The following test is just a shortcut for check_access() (to avoid
 
5454
    calculating db_access) under the assumption that it's common to
 
5455
    give persons global right to execute all stored SP (but not
 
5456
    necessary to create them).
 
5457
  */
 
5458
  if ((thd->security_ctx->master_access & want_access) == want_access)
 
5459
    tables->grant.privilege= want_access;
 
5460
  else if (check_access(thd,want_access,db,&tables->grant.privilege,
 
5461
                        0, no_errors, 0))
 
5462
    return TRUE;
 
5463
  
 
5464
    return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
 
5465
}
 
5466
 
 
5467
 
 
5468
/**
 
5469
  Check if the routine has any of the routine privileges.
 
5470
 
 
5471
  @param thd           Thread handler
 
5472
  @param db           Database name
 
5473
  @param name         Routine name
 
5474
 
 
5475
  @retval
 
5476
    0            ok
 
5477
  @retval
 
5478
    1            error
 
5479
*/
 
5480
 
 
5481
bool check_some_routine_access(THD *thd, const char *db, const char *name,
 
5482
                               bool is_proc)
 
5483
{
 
5484
  ulong save_priv;
 
5485
  if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
 
5486
    return FALSE;
 
5487
  /*
 
5488
    There are no routines in information_schema db. So we can safely
 
5489
    pass zero to last paramter of check_access function
 
5490
  */
 
5491
  if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1, 0) ||
 
5492
      (save_priv & SHOW_PROC_ACLS))
 
5493
    return FALSE;
 
5494
  return check_routine_level_acl(thd, db, name, is_proc);
 
5495
}
 
5496
 
 
5497
 
 
5498
/*
 
5499
  Check if the given table has any of the asked privileges
 
5500
 
 
5501
  @param thd             Thread handler
 
5502
  @param want_access     Bitmap of possible privileges to check for
 
5503
 
 
5504
  @retval
 
5505
    0  ok
 
5506
  @retval
 
5507
    1  error
 
5508
*/
 
5509
 
 
5510
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
 
5511
{
 
5512
  ulong access;
 
5513
  DBUG_ENTER("check_some_access");
 
5514
 
 
5515
  /* This loop will work as long as we have less than 32 privileges */
 
5516
  for (access= 1; access < want_access ; access<<= 1)
 
5517
  {
 
5518
    if (access & want_access)
 
5519
    {
 
5520
      if (!check_access(thd, access, table->db,
 
5521
                        &table->grant.privilege, 0, 1,
 
5522
                        test(table->schema_table)) &&
 
5523
           !check_grant(thd, access, table, 0, 1, 1))
 
5524
        DBUG_RETURN(0);
 
5525
    }
 
5526
  }
 
5527
  DBUG_PRINT("exit",("no matching access rights"));
 
5528
  DBUG_RETURN(1);
 
5529
}
 
5530
 
 
5531
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
 
5532
 
 
5533
 
 
5534
/**
 
5535
  check for global access and give descriptive error message if it fails.
 
5536
 
 
5537
  @param thd                    Thread handler
 
5538
  @param want_access            Use should have any of these global rights
 
5539
 
 
5540
  @warning
 
5541
    One gets access right if one has ANY of the rights in want_access.
 
5542
    This is useful as one in most cases only need one global right,
 
5543
    but in some case we want to check if the user has SUPER or
 
5544
    REPL_CLIENT_ACL rights.
 
5545
 
 
5546
  @retval
 
5547
    0   ok
 
5548
  @retval
 
5549
    1   Access denied.  In this case an error is sent to the client
 
5550
*/
 
5551
 
 
5552
bool check_global_access(THD *thd, ulong want_access)
 
5553
{
 
5554
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
5555
  char command[128];
 
5556
  if ((thd->security_ctx->master_access & want_access))
 
5557
    return 0;
 
5558
  get_privilege_desc(command, sizeof(command), want_access);
 
5559
  my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
 
5560
  return 1;
 
5561
#else
 
5562
  return 0;
 
5563
#endif
 
5564
}
 
5565
 
 
5566
/****************************************************************************
 
5567
        Check stack size; Send error if there isn't enough stack to continue
 
5568
****************************************************************************/
 
5569
 
 
5570
#ifndef EMBEDDED_LIBRARY
 
5571
 
 
5572
#if STACK_DIRECTION < 0
 
5573
#define used_stack(A,B) (long) (A - B)
 
5574
#else
 
5575
#define used_stack(A,B) (long) (B - A)
 
5576
#endif
 
5577
 
 
5578
#ifndef DBUG_OFF
 
5579
long max_stack_used;
 
5580
#endif
 
5581
 
 
5582
/**
 
5583
  @note
 
5584
  Note: The 'buf' parameter is necessary, even if it is unused here.
 
5585
  - fix_fields functions has a "dummy" buffer large enough for the
 
5586
    corresponding exec. (Thus we only have to check in fix_fields.)
 
5587
  - Passing to check_stack_overrun() prevents the compiler from removing it.
 
5588
*/
 
5589
bool check_stack_overrun(THD *thd, long margin,
 
5590
                         uchar *buf __attribute__((unused)))
 
5591
{
 
5592
  long stack_used;
 
5593
  DBUG_ASSERT(thd == current_thd);
 
5594
  if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
 
5595
      (long) (my_thread_stack_size - margin))
 
5596
  {
 
5597
    char ebuff[MYSQL_ERRMSG_SIZE];
 
5598
    my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
 
5599
                stack_used, my_thread_stack_size, margin);
 
5600
    my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
 
5601
    thd->fatal_error();
 
5602
    return 1;
 
5603
  }
 
5604
#ifndef DBUG_OFF
 
5605
  max_stack_used= max(max_stack_used, stack_used);
 
5606
#endif
 
5607
  return 0;
 
5608
}
 
5609
#endif /* EMBEDDED_LIBRARY */
 
5610
 
 
5611
#define MY_YACC_INIT 1000                       // Start with big alloc
 
5612
#define MY_YACC_MAX  32000                      // Because of 'short'
 
5613
 
 
5614
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
 
5615
{
 
5616
  Yacc_state *state= & current_thd->m_parser_state->m_yacc;
 
5617
  ulong old_info=0;
 
5618
  DBUG_ASSERT(state);
 
5619
  if ((uint) *yystacksize >= MY_YACC_MAX)
 
5620
    return 1;
 
5621
  if (!state->yacc_yyvs)
 
5622
    old_info= *yystacksize;
 
5623
  *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
 
5624
  if (!(state->yacc_yyvs= (uchar*)
 
5625
        my_realloc(state->yacc_yyvs,
 
5626
                   *yystacksize*sizeof(**yyvs),
 
5627
                   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
 
5628
      !(state->yacc_yyss= (uchar*)
 
5629
        my_realloc(state->yacc_yyss,
 
5630
                   *yystacksize*sizeof(**yyss),
 
5631
                   MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
 
5632
    return 1;
 
5633
  if (old_info)
 
5634
  {
 
5635
    /*
 
5636
      Only copy the old stack on the first call to my_yyoverflow(),
 
5637
      when replacing a static stack (YYINITDEPTH) by a dynamic stack.
 
5638
      For subsequent calls, my_realloc already did preserve the old stack.
 
5639
    */
 
5640
    memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
 
5641
    memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
 
5642
  }
 
5643
  *yyss= (short*) state->yacc_yyss;
 
5644
  *yyvs= (YYSTYPE*) state->yacc_yyvs;
 
5645
  return 0;
 
5646
}
 
5647
 
 
5648
 
 
5649
/**
 
5650
 Reset THD part responsible for command processing state.
 
5651
 
 
5652
   This needs to be called before execution of every statement
 
5653
   (prepared or conventional).
 
5654
   It is not called by substatements of routines.
 
5655
 
 
5656
  @todo
 
5657
   Make it a method of THD and align its name with the rest of
 
5658
   reset/end/start/init methods.
 
5659
  @todo
 
5660
   Call it after we use THD for queries, not before.
 
5661
*/
 
5662
 
 
5663
void mysql_reset_thd_for_next_command(THD *thd)
 
5664
{
 
5665
  DBUG_ENTER("mysql_reset_thd_for_next_command");
 
5666
  DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
 
5667
  DBUG_ASSERT(! thd->in_sub_stmt);
 
5668
  thd->free_list= 0;
 
5669
  thd->select_number= 1;
 
5670
  /*
 
5671
    Those two lines below are theoretically unneeded as
 
5672
    THD::cleanup_after_query() should take care of this already.
 
5673
  */
 
5674
  thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
 
5675
  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
 
5676
 
 
5677
  thd->query_start_used= 0;
 
5678
  thd->is_fatal_error= thd->time_zone_used= 0;
 
5679
  /*
 
5680
    Clear the status flag that are expected to be cleared at the
 
5681
    beginning of each SQL statement.
 
5682
  */
 
5683
  thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
 
5684
  /*
 
5685
    If in autocommit mode and not in a transaction, reset
 
5686
    OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
 
5687
    in ha_rollback_trans() about some tables couldn't be rolled back.
 
5688
  */
 
5689
  if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
 
5690
  {
 
5691
    thd->options&= ~OPTION_KEEP_LOG;
 
5692
    thd->transaction.all.modified_non_trans_table= FALSE;
 
5693
  }
 
5694
  DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
 
5695
  thd->thread_specific_used= FALSE;
 
5696
 
 
5697
  if (opt_bin_log)
 
5698
  {
 
5699
    reset_dynamic(&thd->user_var_events);
 
5700
    thd->user_var_events_alloc= thd->mem_root;
 
5701
  }
 
5702
  thd->clear_error();
 
5703
  thd->main_da.reset_diagnostics_area();
 
5704
  thd->total_warn_count=0;                      // Warnings for this query
 
5705
  thd->rand_used= 0;
 
5706
  thd->sent_row_count= thd->examined_row_count= 0;
 
5707
 
 
5708
  /*
 
5709
    Because we come here only for start of top-statements, binlog format is
 
5710
    constant inside a complex statement (using stored functions) etc.
 
5711
  */
 
5712
  thd->reset_current_stmt_binlog_row_based();
 
5713
 
 
5714
  DBUG_PRINT("debug",
 
5715
             ("current_stmt_binlog_row_based: %d",
 
5716
              thd->current_stmt_binlog_row_based));
 
5717
 
 
5718
  DBUG_VOID_RETURN;
 
5719
}
 
5720
 
 
5721
 
 
5722
/**
 
5723
  Resets the lex->current_select object.
 
5724
  @note It is assumed that lex->current_select != NULL
 
5725
 
 
5726
  This function is a wrapper around select_lex->init_select() with an added
 
5727
  check for the special situation when using INTO OUTFILE and LOAD DATA.
 
5728
*/
 
5729
 
 
5730
void
 
5731
mysql_init_select(LEX *lex)
 
5732
{
 
5733
  SELECT_LEX *select_lex= lex->current_select;
 
5734
  select_lex->init_select();
 
5735
  lex->wild= 0;
 
5736
  if (select_lex == &lex->select_lex)
 
5737
  {
 
5738
    DBUG_ASSERT(lex->result == 0);
 
5739
    lex->exchange= 0;
 
5740
  }
 
5741
}
 
5742
 
 
5743
 
 
5744
/**
 
5745
  Used to allocate a new SELECT_LEX object on the current thd mem_root and
 
5746
  link it into the relevant lists.
 
5747
 
 
5748
  This function is always followed by mysql_init_select.
 
5749
 
 
5750
  @see mysql_init_select
 
5751
 
 
5752
  @retval TRUE An error occurred
 
5753
  @retval FALSE The new SELECT_LEX was successfully allocated.
 
5754
*/
 
5755
 
 
5756
bool
 
5757
mysql_new_select(LEX *lex, bool move_down)
 
5758
{
 
5759
  SELECT_LEX *select_lex;
 
5760
  THD *thd= lex->thd;
 
5761
  DBUG_ENTER("mysql_new_select");
 
5762
 
 
5763
  if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
 
5764
    DBUG_RETURN(1);
 
5765
  select_lex->select_number= ++thd->select_number;
 
5766
  select_lex->parent_lex= lex; /* Used in init_query. */
 
5767
  select_lex->init_query();
 
5768
  select_lex->init_select();
 
5769
  lex->nest_level++;
 
5770
  if (lex->nest_level > (int) MAX_SELECT_NESTING)
 
5771
  {
 
5772
    my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
 
5773
    DBUG_RETURN(1);
 
5774
  }
 
5775
  select_lex->nest_level= lex->nest_level;
 
5776
  /*
 
5777
    Don't evaluate this subquery during statement prepare even if
 
5778
    it's a constant one. The flag is switched off in the end of
 
5779
    mysqld_stmt_prepare.
 
5780
  */
 
5781
  if (thd->stmt_arena->is_stmt_prepare())
 
5782
    select_lex->uncacheable|= UNCACHEABLE_PREPARE;
 
5783
  if (move_down)
 
5784
  {
 
5785
    SELECT_LEX_UNIT *unit;
 
5786
    lex->subqueries= TRUE;
 
5787
    /* first select_lex of subselect or derived table */
 
5788
    if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
 
5789
      DBUG_RETURN(1);
 
5790
 
 
5791
    unit->init_query();
 
5792
    unit->init_select();
 
5793
    unit->thd= thd;
 
5794
    unit->include_down(lex->current_select);
 
5795
    unit->link_next= 0;
 
5796
    unit->link_prev= 0;
 
5797
    unit->return_to= lex->current_select;
 
5798
    select_lex->include_down(unit);
 
5799
    /*
 
5800
      By default we assume that it is usual subselect and we have outer name
 
5801
      resolution context, if no we will assign it to 0 later
 
5802
    */
 
5803
    select_lex->context.outer_context= &select_lex->outer_select()->context;
 
5804
  }
 
5805
  else
 
5806
  {
 
5807
    if (lex->current_select->order_list.first && !lex->current_select->braces)
 
5808
    {
 
5809
      my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
 
5810
      DBUG_RETURN(1);
 
5811
    }
 
5812
    select_lex->include_neighbour(lex->current_select);
 
5813
    SELECT_LEX_UNIT *unit= select_lex->master_unit();                              
 
5814
    if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
 
5815
      DBUG_RETURN(1);
 
5816
    select_lex->context.outer_context= 
 
5817
                unit->first_select()->context.outer_context;
 
5818
  }
 
5819
 
 
5820
  select_lex->master_unit()->global_parameters= select_lex;
 
5821
  select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
 
5822
  lex->current_select= select_lex;
 
5823
  /*
 
5824
    in subquery is SELECT query and we allow resolution of names in SELECT
 
5825
    list
 
5826
  */
 
5827
  select_lex->context.resolve_in_select_list= TRUE;
 
5828
  DBUG_RETURN(0);
 
5829
}
 
5830
 
 
5831
/**
 
5832
  Create a select to return the same output as 'SELECT @@var_name'.
 
5833
 
 
5834
  Used for SHOW COUNT(*) [ WARNINGS | ERROR].
 
5835
 
 
5836
  This will crash with a core dump if the variable doesn't exists.
 
5837
 
 
5838
  @param var_name               Variable name
 
5839
*/
 
5840
 
 
5841
void create_select_for_variable(const char *var_name)
 
5842
{
 
5843
  THD *thd;
 
5844
  LEX *lex;
 
5845
  LEX_STRING tmp, null_lex_string;
 
5846
  Item *var;
 
5847
  char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
 
5848
  DBUG_ENTER("create_select_for_variable");
 
5849
 
 
5850
  thd= current_thd;
 
5851
  lex= thd->lex;
 
5852
  mysql_init_select(lex);
 
5853
  lex->sql_command= SQLCOM_SELECT;
 
5854
  tmp.str= (char*) var_name;
 
5855
  tmp.length=strlen(var_name);
 
5856
  bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
 
5857
  /*
 
5858
    We set the name of Item to @@session.var_name because that then is used
 
5859
    as the column name in the output.
 
5860
  */
 
5861
  if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
 
5862
  {
 
5863
    end= strxmov(buff, "@@session.", var_name, NullS);
 
5864
    var->set_name(buff, end-buff, system_charset_info);
 
5865
    add_item_to_list(thd, var);
 
5866
  }
 
5867
  DBUG_VOID_RETURN;
 
5868
}
 
5869
 
 
5870
 
 
5871
void mysql_init_multi_delete(LEX *lex)
 
5872
{
 
5873
  lex->sql_command=  SQLCOM_DELETE_MULTI;
 
5874
  mysql_init_select(lex);
 
5875
  lex->select_lex.select_limit= 0;
 
5876
  lex->unit.select_limit_cnt= HA_POS_ERROR;
 
5877
  lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
 
5878
  lex->lock_option= TL_READ_DEFAULT;
 
5879
  lex->query_tables= 0;
 
5880
  lex->query_tables_last= &lex->query_tables;
 
5881
}
 
5882
 
 
5883
 
 
5884
/*
 
5885
  When you modify mysql_parse(), you may need to mofify
 
5886
  mysql_test_parse_for_slave() in this same file.
 
5887
*/
 
5888
 
 
5889
/**
 
5890
  Parse a query.
 
5891
 
 
5892
  @param       thd     Current thread
 
5893
  @param       inBuf   Begining of the query text
 
5894
  @param       length  Length of the query text
 
5895
  @param[out]  found_semicolon For multi queries, position of the character of
 
5896
                               the next query in the query text.
 
5897
*/
 
5898
 
 
5899
void mysql_parse(THD *thd, const char *inBuf, uint length,
 
5900
                 const char ** found_semicolon)
 
5901
{
 
5902
  DBUG_ENTER("mysql_parse");
 
5903
 
 
5904
  DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
 
5905
 
 
5906
  /*
 
5907
    Warning.
 
5908
    The purpose of query_cache_send_result_to_client() is to lookup the
 
5909
    query in the query cache first, to avoid parsing and executing it.
 
5910
    So, the natural implementation would be to:
 
5911
    - first, call query_cache_send_result_to_client,
 
5912
    - second, if caching failed, initialise the lexical and syntactic parser.
 
5913
    The problem is that the query cache depends on a clean initialization
 
5914
    of (among others) lex->safe_to_cache_query and thd->server_status,
 
5915
    which are reset respectively in
 
5916
    - lex_start()
 
5917
    - mysql_reset_thd_for_next_command()
 
5918
    So, initializing the lexical analyser *before* using the query cache
 
5919
    is required for the cache to work properly.
 
5920
    FIXME: cleanup the dependencies in the code to simplify this.
 
5921
  */
 
5922
  lex_start(thd);
 
5923
  mysql_reset_thd_for_next_command(thd);
 
5924
 
 
5925
  if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
 
5926
  {
 
5927
    LEX *lex= thd->lex;
 
5928
 
 
5929
    sp_cache_flush_obsolete(&thd->sp_proc_cache);
 
5930
    sp_cache_flush_obsolete(&thd->sp_func_cache);
 
5931
 
 
5932
    Parser_state parser_state(thd, inBuf, length);
 
5933
 
 
5934
    bool err= parse_sql(thd, & parser_state, NULL);
 
5935
    *found_semicolon= parser_state.m_lip.found_semicolon;
 
5936
 
 
5937
    if (!err)
 
5938
    {
 
5939
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
5940
      if (mqh_used && thd->user_connect &&
 
5941
          check_mqh(thd, lex->sql_command))
 
5942
      {
 
5943
        thd->net.error = 0;
 
5944
      }
 
5945
      else
 
5946
#endif
 
5947
      {
 
5948
        if (! thd->is_error())
 
5949
        {
 
5950
          /*
 
5951
            Binlog logs a string starting from thd->query and having length
 
5952
            thd->query_length; so we set thd->query_length correctly (to not
 
5953
            log several statements in one event, when we executed only first).
 
5954
            We set it to not see the ';' (otherwise it would get into binlog
 
5955
            and Query_log_event::print() would give ';;' output).
 
5956
            This also helps display only the current query in SHOW
 
5957
            PROCESSLIST.
 
5958
            Note that we don't need LOCK_thread_count to modify query_length.
 
5959
          */
 
5960
          if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
 
5961
            thd->set_query_inner(thd->query(),
 
5962
                                 (uint32) (*found_semicolon -
 
5963
                                           thd->query() - 1));
 
5964
          /* Actually execute the query */
 
5965
          if (*found_semicolon)
 
5966
          {
 
5967
            lex->safe_to_cache_query= 0;
 
5968
            thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
 
5969
          }
 
5970
          lex->set_trg_event_type_for_tables();
 
5971
          mysql_execute_command(thd);
 
5972
        }
 
5973
      }
 
5974
    }
 
5975
    else
 
5976
    {
 
5977
      DBUG_ASSERT(thd->is_error());
 
5978
      DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
 
5979
                         thd->is_fatal_error));
 
5980
 
 
5981
      query_cache_abort(&thd->net);
 
5982
    }
 
5983
    if (thd->lex->sphead)
 
5984
    {
 
5985
      delete thd->lex->sphead;
 
5986
      thd->lex->sphead= 0;
 
5987
    }
 
5988
    lex->unit.cleanup();
 
5989
    thd_proc_info(thd, "freeing items");
 
5990
    thd->end_statement();
 
5991
    thd->cleanup_after_query();
 
5992
    DBUG_ASSERT(thd->change_list.is_empty());
 
5993
  }
 
5994
  else
 
5995
  {
 
5996
    /* There are no multi queries in the cache. */
 
5997
    *found_semicolon= NULL;
 
5998
  }
 
5999
 
 
6000
  DBUG_VOID_RETURN;
 
6001
}
 
6002
 
 
6003
 
 
6004
#ifdef HAVE_REPLICATION
 
6005
/*
 
6006
  Usable by the replication SQL thread only: just parse a query to know if it
 
6007
  can be ignored because of replicate-*-table rules.
 
6008
 
 
6009
  @retval
 
6010
    0   cannot be ignored
 
6011
  @retval
 
6012
    1   can be ignored
 
6013
*/
 
6014
 
 
6015
bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
 
6016
{
 
6017
  LEX *lex= thd->lex;
 
6018
  bool error= 0;
 
6019
  DBUG_ENTER("mysql_test_parse_for_slave");
 
6020
 
 
6021
  Parser_state parser_state(thd, inBuf, length);
 
6022
  lex_start(thd);
 
6023
  mysql_reset_thd_for_next_command(thd);
 
6024
 
 
6025
  if (!parse_sql(thd, & parser_state, NULL) &&
 
6026
      all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
 
6027
    error= 1;                  /* Ignore question */
 
6028
  thd->end_statement();
 
6029
  thd->cleanup_after_query();
 
6030
  DBUG_RETURN(error);
 
6031
}
 
6032
#endif
 
6033
 
 
6034
 
 
6035
 
 
6036
/**
 
6037
  Store field definition for create.
 
6038
 
 
6039
  @return
 
6040
    Return 0 if ok
 
6041
*/
 
6042
 
 
6043
bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
 
6044
                       char *length, char *decimals,
 
6045
                       uint type_modifier,
 
6046
                       Item *default_value, Item *on_update_value,
 
6047
                       LEX_STRING *comment,
 
6048
                       char *change,
 
6049
                       List<String> *interval_list, CHARSET_INFO *cs,
 
6050
                       uint uint_geom_type)
 
6051
{
 
6052
  register Create_field *new_field;
 
6053
  LEX  *lex= thd->lex;
 
6054
  DBUG_ENTER("add_field_to_list");
 
6055
 
 
6056
  if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
 
6057
                               system_charset_info, 1))
 
6058
  {
 
6059
    my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
 
6060
    DBUG_RETURN(1);                             /* purecov: inspected */
 
6061
  }
 
6062
  if (type_modifier & PRI_KEY_FLAG)
 
6063
  {
 
6064
    Key *key;
 
6065
    lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
 
6066
    key= new Key(Key::PRIMARY, NullS,
 
6067
                      &default_key_create_info,
 
6068
                      0, lex->col_list);
 
6069
    lex->alter_info.key_list.push_back(key);
 
6070
    lex->col_list.empty();
 
6071
  }
 
6072
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
 
6073
  {
 
6074
    Key *key;
 
6075
    lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
 
6076
    key= new Key(Key::UNIQUE, NullS,
 
6077
                 &default_key_create_info, 0,
 
6078
                 lex->col_list);
 
6079
    lex->alter_info.key_list.push_back(key);
 
6080
    lex->col_list.empty();
 
6081
  }
 
6082
 
 
6083
  if (default_value)
 
6084
  {
 
6085
    /* 
 
6086
      Default value should be literal => basic constants =>
 
6087
      no need fix_fields()
 
6088
      
 
6089
      We allow only one function as part of default value - 
 
6090
      NOW() as default for TIMESTAMP type.
 
6091
    */
 
6092
    if (default_value->type() == Item::FUNC_ITEM && 
 
6093
        !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
 
6094
         type == MYSQL_TYPE_TIMESTAMP))
 
6095
    {
 
6096
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
 
6097
      DBUG_RETURN(1);
 
6098
    }
 
6099
    else if (default_value->type() == Item::NULL_ITEM)
 
6100
    {
 
6101
      default_value= 0;
 
6102
      if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
 
6103
          NOT_NULL_FLAG)
 
6104
      {
 
6105
        my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
 
6106
        DBUG_RETURN(1);
 
6107
      }
 
6108
    }
 
6109
    else if (type_modifier & AUTO_INCREMENT_FLAG)
 
6110
    {
 
6111
      my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
 
6112
      DBUG_RETURN(1);
 
6113
    }
 
6114
  }
 
6115
 
 
6116
  if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
 
6117
  {
 
6118
    my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
 
6119
    DBUG_RETURN(1);
 
6120
  }
 
6121
 
 
6122
  if (type == MYSQL_TYPE_TIMESTAMP && length)
 
6123
  {
 
6124
    /* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1.
 
6125
       In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4),
 
6126
       and so on, the display width is ignored.
 
6127
    */
 
6128
    char buf[32];
 
6129
    my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
 
6130
    WARN_DEPRECATED(thd, "6.0", buf, "'TIMESTAMP'");
 
6131
  }
 
6132
 
 
6133
  if (!(new_field= new Create_field()) ||
 
6134
      new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
 
6135
                      default_value, on_update_value, comment, change,
 
6136
                      interval_list, cs, uint_geom_type))
 
6137
    DBUG_RETURN(1);
 
6138
 
 
6139
  lex->alter_info.create_list.push_back(new_field);
 
6140
  lex->last_field=new_field;
 
6141
  DBUG_RETURN(0);
 
6142
}
 
6143
 
 
6144
 
 
6145
/** Store position for column in ALTER TABLE .. ADD column. */
 
6146
 
 
6147
void store_position_for_column(const char *name)
 
6148
{
 
6149
  current_thd->lex->last_field->after=my_const_cast(char*) (name);
 
6150
}
 
6151
 
 
6152
bool
 
6153
add_proc_to_list(THD* thd, Item *item)
 
6154
{
 
6155
  ORDER *order;
 
6156
  Item  **item_ptr;
 
6157
 
 
6158
  if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
 
6159
    return 1;
 
6160
  item_ptr = (Item**) (order+1);
 
6161
  *item_ptr= item;
 
6162
  order->item=item_ptr;
 
6163
  order->free_me=0;
 
6164
  thd->lex->proc_list.link_in_list((uchar*) order,(uchar**) &order->next);
 
6165
  return 0;
 
6166
}
 
6167
 
 
6168
 
 
6169
/**
 
6170
  save order by and tables in own lists.
 
6171
*/
 
6172
 
 
6173
bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
 
6174
{
 
6175
  ORDER *order;
 
6176
  DBUG_ENTER("add_to_list");
 
6177
  if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
 
6178
    DBUG_RETURN(1);
 
6179
  order->item_ptr= item;
 
6180
  order->item= &order->item_ptr;
 
6181
  order->asc = asc;
 
6182
  order->free_me=0;
 
6183
  order->used=0;
 
6184
  order->counter_used= 0;
 
6185
  list.link_in_list((uchar*) order,(uchar**) &order->next);
 
6186
  DBUG_RETURN(0);
 
6187
}
 
6188
 
 
6189
 
 
6190
/**
 
6191
  Add a table to list of used tables.
 
6192
 
 
6193
  @param table          Table to add
 
6194
  @param alias          alias for table (or null if no alias)
 
6195
  @param table_options  A set of the following bits:
 
6196
                         - TL_OPTION_UPDATING : Table will be updated
 
6197
                         - TL_OPTION_FORCE_INDEX : Force usage of index
 
6198
                         - TL_OPTION_ALIAS : an alias in multi table DELETE
 
6199
  @param lock_type      How table should be locked
 
6200
  @param use_index      List of indexed used in USE INDEX
 
6201
  @param ignore_index   List of indexed used in IGNORE INDEX
 
6202
 
 
6203
  @retval
 
6204
      0         Error
 
6205
  @retval
 
6206
    \#  Pointer to TABLE_LIST element added to the total table list
 
6207
*/
 
6208
 
 
6209
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
 
6210
                                             Table_ident *table,
 
6211
                                             LEX_STRING *alias,
 
6212
                                             ulong table_options,
 
6213
                                             thr_lock_type lock_type,
 
6214
                                             List<Index_hint> *index_hints_arg,
 
6215
                                             LEX_STRING *option)
 
6216
{
 
6217
  register TABLE_LIST *ptr;
 
6218
  TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
 
6219
  char *alias_str;
 
6220
  LEX *lex= thd->lex;
 
6221
  DBUG_ENTER("add_table_to_list");
 
6222
  LINT_INIT(previous_table_ref);
 
6223
 
 
6224
  if (!table)
 
6225
    DBUG_RETURN(0);                             // End of memory
 
6226
  alias_str= alias ? alias->str : table->table.str;
 
6227
  if (!test(table_options & TL_OPTION_ALIAS) && 
 
6228
      check_table_name(table->table.str, table->table.length))
 
6229
  {
 
6230
    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
 
6231
    DBUG_RETURN(0);
 
6232
  }
 
6233
 
 
6234
  if (table->is_derived_table() == FALSE && table->db.str &&
 
6235
      check_db_name(&table->db))
 
6236
  {
 
6237
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
6238
    DBUG_RETURN(0);
 
6239
  }
 
6240
 
 
6241
  if (!alias)                                   /* Alias is case sensitive */
 
6242
  {
 
6243
    if (table->sel)
 
6244
    {
 
6245
      my_message(ER_DERIVED_MUST_HAVE_ALIAS,
 
6246
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
 
6247
      DBUG_RETURN(0);
 
6248
    }
 
6249
    if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
 
6250
      DBUG_RETURN(0);
 
6251
  }
 
6252
  if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
 
6253
    DBUG_RETURN(0);                             /* purecov: inspected */
 
6254
  if (table->db.str)
 
6255
  {
 
6256
    ptr->db= table->db.str;
 
6257
    ptr->db_length= table->db.length;
 
6258
  }
 
6259
  else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
 
6260
    DBUG_RETURN(0);
 
6261
 
 
6262
  ptr->alias= alias_str;
 
6263
  if (lower_case_table_names && table->table.length)
 
6264
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
 
6265
  ptr->table_name=table->table.str;
 
6266
  ptr->table_name_length=table->table.length;
 
6267
  ptr->lock_type=   lock_type;
 
6268
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
 
6269
  /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
 
6270
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
 
6271
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
 
6272
  ptr->derived=     table->sel;
 
6273
  if (!ptr->derived && is_schema_db(ptr->db, ptr->db_length))
 
6274
  {
 
6275
    ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
 
6276
    if (!schema_table ||
 
6277
        (schema_table->hidden && 
 
6278
         ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 || 
 
6279
          /*
 
6280
            this check is used for show columns|keys from I_S hidden table
 
6281
          */
 
6282
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
6283
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
6284
    {
 
6285
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
6286
               ptr->table_name, INFORMATION_SCHEMA_NAME.str);
 
6287
      DBUG_RETURN(0);
 
6288
    }
 
6289
    ptr->schema_table_name= ptr->table_name;
 
6290
    ptr->schema_table= schema_table;
 
6291
  }
 
6292
  ptr->select_lex=  lex->current_select;
 
6293
  ptr->cacheable_table= 1;
 
6294
  ptr->index_hints= index_hints_arg;
 
6295
  ptr->option= option ? option->str : 0;
 
6296
  /* check that used name is unique */
 
6297
  if (lock_type != TL_IGNORE)
 
6298
  {
 
6299
    TABLE_LIST *first_table= (TABLE_LIST*) table_list.first;
 
6300
    if (lex->sql_command == SQLCOM_CREATE_VIEW)
 
6301
      first_table= first_table ? first_table->next_local : NULL;
 
6302
    for (TABLE_LIST *tables= first_table ;
 
6303
         tables ;
 
6304
         tables=tables->next_local)
 
6305
    {
 
6306
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
 
6307
          !strcmp(ptr->db, tables->db))
 
6308
      {
 
6309
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
 
6310
        DBUG_RETURN(0);                         /* purecov: tested */
 
6311
      }
 
6312
    }
 
6313
  }
 
6314
  /* Store the table reference preceding the current one. */
 
6315
  if (table_list.elements > 0)
 
6316
  {
 
6317
    /*
 
6318
      table_list.next points to the last inserted TABLE_LIST->next_local'
 
6319
      element
 
6320
      We don't use the offsetof() macro here to avoid warnings from gcc
 
6321
    */
 
6322
    previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
 
6323
                                       ((char*) &(ptr->next_local) -
 
6324
                                        (char*) ptr));
 
6325
    /*
 
6326
      Set next_name_resolution_table of the previous table reference to point
 
6327
      to the current table reference. In effect the list
 
6328
      TABLE_LIST::next_name_resolution_table coincides with
 
6329
      TABLE_LIST::next_local. Later this may be changed in
 
6330
      store_top_level_join_columns() for NATURAL/USING joins.
 
6331
    */
 
6332
    previous_table_ref->next_name_resolution_table= ptr;
 
6333
  }
 
6334
 
 
6335
  /*
 
6336
    Link the current table reference in a local list (list for current select).
 
6337
    Notice that as a side effect here we set the next_local field of the
 
6338
    previous table reference to 'ptr'. Here we also add one element to the
 
6339
    list 'table_list'.
 
6340
  */
 
6341
  table_list.link_in_list((uchar*) ptr, (uchar**) &ptr->next_local);
 
6342
  ptr->next_name_resolution_table= NULL;
 
6343
  /* Link table in global list (all used tables) */
 
6344
  lex->add_to_query_tables(ptr);
 
6345
  DBUG_RETURN(ptr);
 
6346
}
 
6347
 
 
6348
 
 
6349
/**
 
6350
  Initialize a new table list for a nested join.
 
6351
 
 
6352
    The function initializes a structure of the TABLE_LIST type
 
6353
    for a nested join. It sets up its nested join list as empty.
 
6354
    The created structure is added to the front of the current
 
6355
    join list in the st_select_lex object. Then the function
 
6356
    changes the current nest level for joins to refer to the newly
 
6357
    created empty list after having saved the info on the old level
 
6358
    in the initialized structure.
 
6359
 
 
6360
  @param thd         current thread
 
6361
 
 
6362
  @retval
 
6363
    0   if success
 
6364
  @retval
 
6365
    1   otherwise
 
6366
*/
 
6367
 
 
6368
bool st_select_lex::init_nested_join(THD *thd)
 
6369
{
 
6370
  TABLE_LIST *ptr;
 
6371
  NESTED_JOIN *nested_join;
 
6372
  DBUG_ENTER("init_nested_join");
 
6373
 
 
6374
  if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
 
6375
                                       sizeof(NESTED_JOIN))))
 
6376
    DBUG_RETURN(1);
 
6377
  nested_join= ptr->nested_join=
 
6378
    ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
 
6379
 
 
6380
  join_list->push_front(ptr);
 
6381
  ptr->embedding= embedding;
 
6382
  ptr->join_list= join_list;
 
6383
  ptr->alias= (char*) "(nested_join)";
 
6384
  embedding= ptr;
 
6385
  join_list= &nested_join->join_list;
 
6386
  join_list->empty();
 
6387
  DBUG_RETURN(0);
 
6388
}
 
6389
 
 
6390
 
 
6391
/**
 
6392
  End a nested join table list.
 
6393
 
 
6394
    The function returns to the previous join nest level.
 
6395
    If the current level contains only one member, the function
 
6396
    moves it one level up, eliminating the nest.
 
6397
 
 
6398
  @param thd         current thread
 
6399
 
 
6400
  @return
 
6401
    - Pointer to TABLE_LIST element added to the total table list, if success
 
6402
    - 0, otherwise
 
6403
*/
 
6404
 
 
6405
TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
 
6406
{
 
6407
  TABLE_LIST *ptr;
 
6408
  NESTED_JOIN *nested_join;
 
6409
  DBUG_ENTER("end_nested_join");
 
6410
 
 
6411
  DBUG_ASSERT(embedding);
 
6412
  ptr= embedding;
 
6413
  join_list= ptr->join_list;
 
6414
  embedding= ptr->embedding;
 
6415
  nested_join= ptr->nested_join;
 
6416
  if (nested_join->join_list.elements == 1)
 
6417
  {
 
6418
    TABLE_LIST *embedded= nested_join->join_list.head();
 
6419
    join_list->pop();
 
6420
    embedded->join_list= join_list;
 
6421
    embedded->embedding= embedding;
 
6422
    join_list->push_front(embedded);
 
6423
    ptr= embedded;
 
6424
  }
 
6425
  else if (nested_join->join_list.elements == 0)
 
6426
  {
 
6427
    join_list->pop();
 
6428
    ptr= 0;                                     // return value
 
6429
  }
 
6430
  DBUG_RETURN(ptr);
 
6431
}
 
6432
 
 
6433
 
 
6434
/**
 
6435
  Nest last join operation.
 
6436
 
 
6437
    The function nest last join operation as if it was enclosed in braces.
 
6438
 
 
6439
  @param thd         current thread
 
6440
 
 
6441
  @retval
 
6442
    0  Error
 
6443
  @retval
 
6444
    \#  Pointer to TABLE_LIST element created for the new nested join
 
6445
*/
 
6446
 
 
6447
TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
 
6448
{
 
6449
  TABLE_LIST *ptr;
 
6450
  NESTED_JOIN *nested_join;
 
6451
  List<TABLE_LIST> *embedded_list;
 
6452
  DBUG_ENTER("nest_last_join");
 
6453
 
 
6454
  if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
 
6455
                                       sizeof(NESTED_JOIN))))
 
6456
    DBUG_RETURN(0);
 
6457
  nested_join= ptr->nested_join=
 
6458
    ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
 
6459
 
 
6460
  ptr->embedding= embedding;
 
6461
  ptr->join_list= join_list;
 
6462
  ptr->alias= (char*) "(nest_last_join)";
 
6463
  embedded_list= &nested_join->join_list;
 
6464
  embedded_list->empty();
 
6465
 
 
6466
  for (uint i=0; i < 2; i++)
 
6467
  {
 
6468
    TABLE_LIST *table= join_list->pop();
 
6469
    table->join_list= embedded_list;
 
6470
    table->embedding= ptr;
 
6471
    embedded_list->push_back(table);
 
6472
    if (table->natural_join)
 
6473
    {
 
6474
      ptr->is_natural_join= TRUE;
 
6475
      /*
 
6476
        If this is a JOIN ... USING, move the list of joined fields to the
 
6477
        table reference that describes the join.
 
6478
      */
 
6479
      if (prev_join_using)
 
6480
        ptr->join_using_fields= prev_join_using;
 
6481
    }
 
6482
  }
 
6483
  join_list->push_front(ptr);
 
6484
  nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
 
6485
  DBUG_RETURN(ptr);
 
6486
}
 
6487
 
 
6488
 
 
6489
/**
 
6490
  Add a table to the current join list.
 
6491
 
 
6492
    The function puts a table in front of the current join list
 
6493
    of st_select_lex object.
 
6494
    Thus, joined tables are put into this list in the reverse order
 
6495
    (the most outer join operation follows first).
 
6496
 
 
6497
  @param table       the table to add
 
6498
 
 
6499
  @return
 
6500
    None
 
6501
*/
 
6502
 
 
6503
void st_select_lex::add_joined_table(TABLE_LIST *table)
 
6504
{
 
6505
  DBUG_ENTER("add_joined_table");
 
6506
  join_list->push_front(table);
 
6507
  table->join_list= join_list;
 
6508
  table->embedding= embedding;
 
6509
  DBUG_VOID_RETURN;
 
6510
}
 
6511
 
 
6512
 
 
6513
/**
 
6514
  Convert a right join into equivalent left join.
 
6515
 
 
6516
    The function takes the current join list t[0],t[1] ... and
 
6517
    effectively converts it into the list t[1],t[0] ...
 
6518
    Although the outer_join flag for the new nested table contains
 
6519
    JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
 
6520
    operation.
 
6521
 
 
6522
  EXAMPLES
 
6523
  @verbatim
 
6524
    SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
 
6525
      SELECT * FROM t2 LEFT JOIN t1 ON on_expr
 
6526
 
 
6527
    SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
 
6528
      SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
 
6529
 
 
6530
    SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
 
6531
      SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
 
6532
 
 
6533
    SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3  ON on_expr2 =>
 
6534
      SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
 
6535
   @endverbatim
 
6536
 
 
6537
  @param thd         current thread
 
6538
 
 
6539
  @return
 
6540
    - Pointer to the table representing the inner table, if success
 
6541
    - 0, otherwise
 
6542
*/
 
6543
 
 
6544
TABLE_LIST *st_select_lex::convert_right_join()
 
6545
{
 
6546
  TABLE_LIST *tab2= join_list->pop();
 
6547
  TABLE_LIST *tab1= join_list->pop();
 
6548
  DBUG_ENTER("convert_right_join");
 
6549
 
 
6550
  join_list->push_front(tab2);
 
6551
  join_list->push_front(tab1);
 
6552
  tab1->outer_join|= JOIN_TYPE_RIGHT;
 
6553
 
 
6554
  DBUG_RETURN(tab1);
 
6555
}
 
6556
 
 
6557
/**
 
6558
  Set lock for all tables in current select level.
 
6559
 
 
6560
  @param lock_type                      Lock to set for tables
 
6561
 
 
6562
  @note
 
6563
    If lock is a write lock, then tables->updating is set 1
 
6564
    This is to get tables_ok to know that the table is updated by the
 
6565
    query
 
6566
*/
 
6567
 
 
6568
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
 
6569
{
 
6570
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
6571
  DBUG_ENTER("set_lock_for_tables");
 
6572
  DBUG_PRINT("enter", ("lock_type: %d  for_update: %d", lock_type,
 
6573
                       for_update));
 
6574
  for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first;
 
6575
       tables;
 
6576
       tables= tables->next_local)
 
6577
  {
 
6578
    tables->lock_type= lock_type;
 
6579
    tables->updating=  for_update;
 
6580
  }
 
6581
  DBUG_VOID_RETURN;
 
6582
}
 
6583
 
 
6584
 
 
6585
/**
 
6586
  Create a fake SELECT_LEX for a unit.
 
6587
 
 
6588
    The method create a fake SELECT_LEX object for a unit.
 
6589
    This object is created for any union construct containing a union
 
6590
    operation and also for any single select union construct of the form
 
6591
    @verbatim
 
6592
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ... 
 
6593
    @endvarbatim
 
6594
    or of the form
 
6595
    @varbatim
 
6596
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
6597
    @endvarbatim
 
6598
  
 
6599
  @param thd_arg                   thread handle
 
6600
 
 
6601
  @note
 
6602
    The object is used to retrieve rows from the temporary table
 
6603
    where the result on the union is obtained.
 
6604
 
 
6605
  @retval
 
6606
    1     on failure to create the object
 
6607
  @retval
 
6608
    0     on success
 
6609
*/
 
6610
 
 
6611
bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
 
6612
{
 
6613
  SELECT_LEX *first_sl= first_select();
 
6614
  DBUG_ENTER("add_fake_select_lex");
 
6615
  DBUG_ASSERT(!fake_select_lex);
 
6616
 
 
6617
  if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
 
6618
      DBUG_RETURN(1);
 
6619
  fake_select_lex->include_standalone(this, 
 
6620
                                      (SELECT_LEX_NODE**)&fake_select_lex);
 
6621
  fake_select_lex->select_number= INT_MAX;
 
6622
  fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
 
6623
  fake_select_lex->make_empty_select();
 
6624
  fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
 
6625
  fake_select_lex->select_limit= 0;
 
6626
 
 
6627
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
 
6628
  /* allow item list resolving in fake select for ORDER BY */
 
6629
  fake_select_lex->context.resolve_in_select_list= TRUE;
 
6630
  fake_select_lex->context.select_lex= fake_select_lex;
 
6631
 
 
6632
  if (!is_union())
 
6633
  {
 
6634
    /* 
 
6635
      This works only for 
 
6636
      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
 
6637
      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
 
6638
      just before the parser starts processing order_list
 
6639
    */ 
 
6640
    global_parameters= fake_select_lex;
 
6641
    fake_select_lex->no_table_names_allowed= 1;
 
6642
    thd_arg->lex->current_select= fake_select_lex;
 
6643
  }
 
6644
  thd_arg->lex->pop_context();
 
6645
  DBUG_RETURN(0);
 
6646
}
 
6647
 
 
6648
 
 
6649
/**
 
6650
  Push a new name resolution context for a JOIN ... ON clause to the
 
6651
  context stack of a query block.
 
6652
 
 
6653
    Create a new name resolution context for a JOIN ... ON clause,
 
6654
    set the first and last leaves of the list of table references
 
6655
    to be used for name resolution, and push the newly created
 
6656
    context to the stack of contexts of the query.
 
6657
 
 
6658
  @param thd       pointer to current thread
 
6659
  @param left_op   left  operand of the JOIN
 
6660
  @param right_op  rigth operand of the JOIN
 
6661
 
 
6662
  @retval
 
6663
    FALSE  if all is OK
 
6664
  @retval
 
6665
    TRUE   if a memory allocation error occured
 
6666
*/
 
6667
 
 
6668
bool
 
6669
push_new_name_resolution_context(THD *thd,
 
6670
                                 TABLE_LIST *left_op, TABLE_LIST *right_op)
 
6671
{
 
6672
  Name_resolution_context *on_context;
 
6673
  if (!(on_context= new (thd->mem_root) Name_resolution_context))
 
6674
    return TRUE;
 
6675
  on_context->init();
 
6676
  on_context->first_name_resolution_table=
 
6677
    left_op->first_leaf_for_name_resolution();
 
6678
  on_context->last_name_resolution_table=
 
6679
    right_op->last_leaf_for_name_resolution();
 
6680
  return thd->lex->push_context(on_context);
 
6681
}
 
6682
 
 
6683
 
 
6684
/**
 
6685
  Add an ON condition to the second operand of a JOIN ... ON.
 
6686
 
 
6687
    Add an ON condition to the right operand of a JOIN ... ON clause.
 
6688
 
 
6689
  @param b     the second operand of a JOIN ... ON
 
6690
  @param expr  the condition to be added to the ON clause
 
6691
 
 
6692
  @retval
 
6693
    FALSE  if there was some error
 
6694
  @retval
 
6695
    TRUE   if all is OK
 
6696
*/
 
6697
 
 
6698
void add_join_on(TABLE_LIST *b, Item *expr)
 
6699
{
 
6700
  if (expr)
 
6701
  {
 
6702
    if (!b->on_expr)
 
6703
      b->on_expr= expr;
 
6704
    else
 
6705
    {
 
6706
      /*
 
6707
        If called from the parser, this happens if you have both a
 
6708
        right and left join. If called later, it happens if we add more
 
6709
        than one condition to the ON clause.
 
6710
      */
 
6711
      b->on_expr= new Item_cond_and(b->on_expr,expr);
 
6712
    }
 
6713
    b->on_expr->top_level_item();
 
6714
  }
 
6715
}
 
6716
 
 
6717
 
 
6718
/**
 
6719
  Mark that there is a NATURAL JOIN or JOIN ... USING between two
 
6720
  tables.
 
6721
 
 
6722
    This function marks that table b should be joined with a either via
 
6723
    a NATURAL JOIN or via JOIN ... USING. Both join types are special
 
6724
    cases of each other, so we treat them together. The function
 
6725
    setup_conds() creates a list of equal condition between all fields
 
6726
    of the same name for NATURAL JOIN or the fields in 'using_fields'
 
6727
    for JOIN ... USING. The list of equality conditions is stored
 
6728
    either in b->on_expr, or in JOIN::conds, depending on whether there
 
6729
    was an outer join.
 
6730
 
 
6731
  EXAMPLE
 
6732
  @verbatim
 
6733
    SELECT * FROM t1 NATURAL LEFT JOIN t2
 
6734
     <=>
 
6735
    SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
 
6736
 
 
6737
    SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
 
6738
     <=>
 
6739
    SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
 
6740
 
 
6741
    SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
 
6742
     <=>
 
6743
    SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
 
6744
   @endverbatim
 
6745
 
 
6746
  @param a                Left join argument
 
6747
  @param b                Right join argument
 
6748
  @param using_fields    Field names from USING clause
 
6749
*/
 
6750
 
 
6751
void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
 
6752
                      SELECT_LEX *lex)
 
6753
{
 
6754
  b->natural_join= a;
 
6755
  lex->prev_join_using= using_fields;
 
6756
}
 
6757
 
 
6758
 
 
6759
/**
 
6760
  Reload/resets privileges and the different caches.
 
6761
 
 
6762
  @param thd Thread handler (can be NULL!)
 
6763
  @param options What should be reset/reloaded (tables, privileges, slave...)
 
6764
  @param tables Tables to flush (if any)
 
6765
  @param write_to_binlog True if we can write to the binlog.
 
6766
               
 
6767
  @note Depending on 'options', it may be very bad to write the
 
6768
    query to the binlog (e.g. FLUSH SLAVE); this is a
 
6769
    pointer where reload_acl_and_cache() will put 0 if
 
6770
    it thinks we really should not write to the binlog.
 
6771
    Otherwise it will put 1.
 
6772
 
 
6773
  @return Error status code
 
6774
    @retval 0 Ok
 
6775
    @retval !=0  Error; thd->killed is set or thd->is_error() is true
 
6776
*/
 
6777
 
 
6778
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
 
6779
                          bool *write_to_binlog)
 
6780
{
 
6781
  bool result=0;
 
6782
  select_errors=0;                              /* Write if more errors */
 
6783
  bool tmp_write_to_binlog= 1;
 
6784
 
 
6785
  DBUG_ASSERT(!thd || !thd->in_sub_stmt);
 
6786
 
 
6787
#ifndef NO_EMBEDDED_ACCESS_CHECKS
 
6788
  if (options & REFRESH_GRANT)
 
6789
  {
 
6790
    THD *tmp_thd= 0;
 
6791
    /*
 
6792
      If reload_acl_and_cache() is called from SIGHUP handler we have to
 
6793
      allocate temporary THD for execution of acl_reload()/grant_reload().
 
6794
    */
 
6795
    if (!thd && (thd= (tmp_thd= new THD)))
 
6796
    {
 
6797
      thd->thread_stack= (char*) &tmp_thd;
 
6798
      thd->store_globals();
 
6799
      lex_start(thd);
 
6800
    }
 
6801
 
 
6802
    if (thd)
 
6803
    {
 
6804
      bool reload_acl_failed= acl_reload(thd);
 
6805
      bool reload_grants_failed= grant_reload(thd);
 
6806
      bool reload_servers_failed= servers_reload(thd);
 
6807
 
 
6808
      if (reload_acl_failed || reload_grants_failed || reload_servers_failed)
 
6809
      {
 
6810
        result= 1;
 
6811
        /*
 
6812
          When an error is returned, my_message may have not been called and
 
6813
          the client will hang waiting for a response.
 
6814
        */
 
6815
        my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed");
 
6816
      }
 
6817
    }
 
6818
 
 
6819
    if (tmp_thd)
 
6820
    {
 
6821
      delete tmp_thd;
 
6822
      /* Remember that we don't have a THD */
 
6823
      my_pthread_setspecific_ptr(THR_THD,  0);
 
6824
      thd= 0;
 
6825
    }
 
6826
    reset_mqh((LEX_USER *)NULL, TRUE);
 
6827
  }
 
6828
#endif
 
6829
  if (options & REFRESH_LOG)
 
6830
  {
 
6831
    /*
 
6832
      Flush the normal query log, the update log, the binary log,
 
6833
      the slow query log, the relay log (if it exists) and the log
 
6834
      tables.
 
6835
    */
 
6836
 
 
6837
    /*
 
6838
      Writing this command to the binlog may result in infinite loops
 
6839
      when doing mysqlbinlog|mysql, and anyway it does not really make
 
6840
      sense to log it automatically (would cause more trouble to users
 
6841
      than it would help them)
 
6842
    */
 
6843
    tmp_write_to_binlog= 0;
 
6844
    if( mysql_bin_log.is_open() )
 
6845
    {
 
6846
      mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
 
6847
    }
 
6848
#ifdef HAVE_REPLICATION
 
6849
    pthread_mutex_lock(&LOCK_active_mi);
 
6850
    rotate_relay_log(active_mi);
 
6851
    pthread_mutex_unlock(&LOCK_active_mi);
 
6852
#endif
 
6853
 
 
6854
    /* flush slow and general logs */
 
6855
    logger.flush_logs(thd);
 
6856
 
 
6857
    if (ha_flush_logs(NULL))
 
6858
      result=1;
 
6859
    if (flush_error_log())
 
6860
      result=1;
 
6861
  }
 
6862
#ifdef HAVE_QUERY_CACHE
 
6863
  if (options & REFRESH_QUERY_CACHE_FREE)
 
6864
  {
 
6865
    query_cache.pack();                         // FLUSH QUERY CACHE
 
6866
    options &= ~REFRESH_QUERY_CACHE;    // Don't flush cache, just free memory
 
6867
  }
 
6868
  if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
 
6869
  {
 
6870
    query_cache.flush();                        // RESET QUERY CACHE
 
6871
  }
 
6872
#endif /*HAVE_QUERY_CACHE*/
 
6873
  /*
 
6874
    Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
 
6875
    (see sql_yacc.yy)
 
6876
  */
 
6877
  if (options & (REFRESH_TABLES | REFRESH_READ_LOCK)) 
 
6878
  {
 
6879
    if ((options & REFRESH_READ_LOCK) && thd)
 
6880
    {
 
6881
      /*
 
6882
        We must not try to aspire a global read lock if we have a write
 
6883
        locked table. This would lead to a deadlock when trying to
 
6884
        reopen (and re-lock) the table after the flush.
 
6885
      */
 
6886
      if (thd->locked_tables)
 
6887
      {
 
6888
        THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
 
6889
        THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
 
6890
 
 
6891
        for (; lock_p < end_p; lock_p++)
 
6892
        {
 
6893
          if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
 
6894
          {
 
6895
            my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
 
6896
            return 1;
 
6897
          }
 
6898
        }
 
6899
      }
 
6900
      /*
 
6901
        Writing to the binlog could cause deadlocks, as we don't log
 
6902
        UNLOCK TABLES
 
6903
      */
 
6904
      tmp_write_to_binlog= 0;
 
6905
      if (lock_global_read_lock(thd))
 
6906
        return 1;                               // Killed
 
6907
      if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
 
6908
                              FALSE : TRUE, TRUE))
 
6909
          result= 1;
 
6910
      
 
6911
      if (make_global_read_lock_block_commit(thd)) // Killed
 
6912
      {
 
6913
        /* Don't leave things in a half-locked state */
 
6914
        unlock_global_read_lock(thd);
 
6915
        return 1;
 
6916
      }
 
6917
    }
 
6918
    else
 
6919
    {
 
6920
      if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
 
6921
                              FALSE : TRUE, FALSE))
 
6922
        result= 1;
 
6923
    }
 
6924
    my_dbopt_cleanup();
 
6925
  }
 
6926
  if (options & REFRESH_HOSTS)
 
6927
    hostname_cache_refresh();
 
6928
  if (thd && (options & REFRESH_STATUS))
 
6929
    refresh_status(thd);
 
6930
  if (options & REFRESH_THREADS)
 
6931
    flush_thread_cache();
 
6932
#ifdef HAVE_REPLICATION
 
6933
  if (options & REFRESH_MASTER)
 
6934
  {
 
6935
    DBUG_ASSERT(thd);
 
6936
    tmp_write_to_binlog= 0;
 
6937
    if (reset_master(thd))
 
6938
    {
 
6939
      result=1;
 
6940
    }
 
6941
  }
 
6942
#endif
 
6943
#ifdef OPENSSL
 
6944
   if (options & REFRESH_DES_KEY_FILE)
 
6945
   {
 
6946
     if (des_key_file && load_des_key_file(des_key_file))
 
6947
         result= 1;
 
6948
   }
 
6949
#endif
 
6950
#ifdef HAVE_REPLICATION
 
6951
 if (options & REFRESH_SLAVE)
 
6952
 {
 
6953
   tmp_write_to_binlog= 0;
 
6954
   pthread_mutex_lock(&LOCK_active_mi);
 
6955
   if (reset_slave(thd, active_mi))
 
6956
     result=1;
 
6957
   pthread_mutex_unlock(&LOCK_active_mi);
 
6958
 }
 
6959
#endif
 
6960
 if (options & REFRESH_USER_RESOURCES)
 
6961
   reset_mqh((LEX_USER *) NULL, 0);             /* purecov: inspected */
 
6962
 *write_to_binlog= tmp_write_to_binlog;
 
6963
 /*
 
6964
   If the query was killed then this function must fail.
 
6965
 */
 
6966
 return result || (thd ? thd->killed : 0);
 
6967
}
 
6968
 
 
6969
 
 
6970
/**
 
6971
  kill on thread.
 
6972
 
 
6973
  @param thd                    Thread class
 
6974
  @param id                     Thread id
 
6975
  @param only_kill_query        Should it kill the query or the connection
 
6976
 
 
6977
  @note
 
6978
    This is written such that we have a short lock on LOCK_thread_count
 
6979
*/
 
6980
 
 
6981
uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
 
6982
{
 
6983
  THD *tmp;
 
6984
  uint error=ER_NO_SUCH_THREAD;
 
6985
  DBUG_ENTER("kill_one_thread");
 
6986
  DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
 
6987
  VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
 
6988
  I_List_iterator<THD> it(threads);
 
6989
  while ((tmp=it++))
 
6990
  {
 
6991
    if (tmp->command == COM_DAEMON)
 
6992
      continue;
 
6993
    if (tmp->thread_id == id)
 
6994
    {
 
6995
      pthread_mutex_lock(&tmp->LOCK_thd_data);  // Lock from delete
 
6996
      break;
 
6997
    }
 
6998
  }
 
6999
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
7000
  if (tmp)
 
7001
  {
 
7002
 
 
7003
    /*
 
7004
      If we're SUPER, we can KILL anything, including system-threads.
 
7005
      No further checks.
 
7006
 
 
7007
      KILLer: thd->security_ctx->user could in theory be NULL while
 
7008
      we're still in "unauthenticated" state. This is a theoretical
 
7009
      case (the code suggests this could happen, so we play it safe).
 
7010
 
 
7011
      KILLee: tmp->security_ctx->user will be NULL for system threads.
 
7012
      We need to check so Jane Random User doesn't crash the server
 
7013
      when trying to kill a) system threads or b) unauthenticated users'
 
7014
      threads (Bug#43748).
 
7015
 
 
7016
      If user of both killer and killee are non-NULL, proceed with
 
7017
      slayage if both are string-equal.
 
7018
    */
 
7019
 
 
7020
    if ((thd->security_ctx->master_access & SUPER_ACL) ||
 
7021
        thd->security_ctx->user_matches(tmp->security_ctx))
 
7022
    {
 
7023
      tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
 
7024
      error=0;
 
7025
    }
 
7026
    else
 
7027
      error=ER_KILL_DENIED_ERROR;
 
7028
    pthread_mutex_unlock(&tmp->LOCK_thd_data);
 
7029
  }
 
7030
  DBUG_PRINT("exit", ("%d", error));
 
7031
  DBUG_RETURN(error);
 
7032
}
 
7033
 
 
7034
 
 
7035
/*
 
7036
  kills a thread and sends response
 
7037
 
 
7038
  SYNOPSIS
 
7039
    sql_kill()
 
7040
    thd                 Thread class
 
7041
    id                  Thread id
 
7042
    only_kill_query     Should it kill the query or the connection
 
7043
*/
 
7044
 
 
7045
void sql_kill(THD *thd, ulong id, bool only_kill_query)
 
7046
{
 
7047
  uint error;
 
7048
  if (!(error= kill_one_thread(thd, id, only_kill_query)))
 
7049
    my_ok(thd);
 
7050
  else
 
7051
    my_error(error, MYF(0), id);
 
7052
}
 
7053
 
 
7054
 
 
7055
/** If pointer is not a null pointer, append filename to it. */
 
7056
 
 
7057
bool append_file_to_dir(THD *thd, const char **filename_ptr,
 
7058
                        const char *table_name)
 
7059
{
 
7060
  char buff[FN_REFLEN],*ptr, *end;
 
7061
  if (!*filename_ptr)
 
7062
    return 0;                                   // nothing to do
 
7063
 
 
7064
  /* Check that the filename is not too long and it's a hard path */
 
7065
  if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
 
7066
      !test_if_hard_path(*filename_ptr))
 
7067
  {
 
7068
    my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
 
7069
    return 1;
 
7070
  }
 
7071
  /* Fix is using unix filename format on dos */
 
7072
  strmov(buff,*filename_ptr);
 
7073
  end=convert_dirname(buff, *filename_ptr, NullS);
 
7074
  if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
 
7075
    return 1;                                   // End of memory
 
7076
  *filename_ptr=ptr;
 
7077
  strxmov(ptr,buff,table_name,NullS);
 
7078
  return 0;
 
7079
}
 
7080
 
 
7081
 
 
7082
/**
 
7083
  Check if the select is a simple select (not an union).
 
7084
 
 
7085
  @retval
 
7086
    0   ok
 
7087
  @retval
 
7088
    1   error   ; In this case the error messege is sent to the client
 
7089
*/
 
7090
 
 
7091
bool check_simple_select()
 
7092
{
 
7093
  THD *thd= current_thd;
 
7094
  LEX *lex= thd->lex;
 
7095
  if (lex->current_select != &lex->select_lex)
 
7096
  {
 
7097
    char command[80];
 
7098
    Lex_input_stream *lip= & thd->m_parser_state->m_lip;
 
7099
    strmake(command, lip->yylval->symbol.str,
 
7100
            min(lip->yylval->symbol.length, sizeof(command)-1));
 
7101
    my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
 
7102
    return 1;
 
7103
  }
 
7104
  return 0;
 
7105
}
 
7106
 
 
7107
 
 
7108
Comp_creator *comp_eq_creator(bool invert)
 
7109
{
 
7110
  return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
 
7111
}
 
7112
 
 
7113
 
 
7114
Comp_creator *comp_ge_creator(bool invert)
 
7115
{
 
7116
  return invert?(Comp_creator *)&lt_creator:(Comp_creator *)&ge_creator;
 
7117
}
 
7118
 
 
7119
 
 
7120
Comp_creator *comp_gt_creator(bool invert)
 
7121
{
 
7122
  return invert?(Comp_creator *)&le_creator:(Comp_creator *)&gt_creator;
 
7123
}
 
7124
 
 
7125
 
 
7126
Comp_creator *comp_le_creator(bool invert)
 
7127
{
 
7128
  return invert?(Comp_creator *)&gt_creator:(Comp_creator *)&le_creator;
 
7129
}
 
7130
 
 
7131
 
 
7132
Comp_creator *comp_lt_creator(bool invert)
 
7133
{
 
7134
  return invert?(Comp_creator *)&ge_creator:(Comp_creator *)&lt_creator;
 
7135
}
 
7136
 
 
7137
 
 
7138
Comp_creator *comp_ne_creator(bool invert)
 
7139
{
 
7140
  return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
 
7141
}
 
7142
 
 
7143
 
 
7144
/**
 
7145
  Construct ALL/ANY/SOME subquery Item.
 
7146
 
 
7147
  @param left_expr   pointer to left expression
 
7148
  @param cmp         compare function creator
 
7149
  @param all         true if we create ALL subquery
 
7150
  @param select_lex  pointer on parsed subquery structure
 
7151
 
 
7152
  @return
 
7153
    constructed Item (or 0 if out of memory)
 
7154
*/
 
7155
Item * all_any_subquery_creator(Item *left_expr,
 
7156
                                chooser_compare_func_creator cmp,
 
7157
                                bool all,
 
7158
                                SELECT_LEX *select_lex)
 
7159
{
 
7160
  if ((cmp == &comp_eq_creator) && !all)       //  = ANY <=> IN
 
7161
    return new Item_in_subselect(left_expr, select_lex);
 
7162
 
 
7163
  if ((cmp == &comp_ne_creator) && all)        // <> ALL <=> NOT IN
 
7164
    return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
 
7165
 
 
7166
  Item_allany_subselect *it=
 
7167
    new Item_allany_subselect(left_expr, cmp, select_lex, all);
 
7168
  if (all)
 
7169
    return it->upper_item= new Item_func_not_all(it);   /* ALL */
 
7170
 
 
7171
  return it->upper_item= new Item_func_nop_all(it);      /* ANY/SOME */
 
7172
}
 
7173
 
 
7174
 
 
7175
/**
 
7176
  Multi update query pre-check.
 
7177
 
 
7178
  @param thd            Thread handler
 
7179
  @param tables Global/local table list (have to be the same)
 
7180
 
 
7181
  @retval
 
7182
    FALSE OK
 
7183
  @retval
 
7184
    TRUE  Error
 
7185
*/
 
7186
 
 
7187
bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
 
7188
{
 
7189
  const char *msg= 0;
 
7190
  TABLE_LIST *table;
 
7191
  LEX *lex= thd->lex;
 
7192
  SELECT_LEX *select_lex= &lex->select_lex;
 
7193
  DBUG_ENTER("multi_update_precheck");
 
7194
 
 
7195
  if (select_lex->item_list.elements != lex->value_list.elements)
 
7196
  {
 
7197
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
 
7198
    DBUG_RETURN(TRUE);
 
7199
  }
 
7200
  /*
 
7201
    Ensure that we have UPDATE or SELECT privilege for each table
 
7202
    The exact privilege is checked in mysql_multi_update()
 
7203
  */
 
7204
  for (table= tables; table; table= table->next_local)
 
7205
  {
 
7206
    if (table->derived)
 
7207
      table->grant.privilege= SELECT_ACL;
 
7208
    else if ((check_access(thd, UPDATE_ACL, table->db,
 
7209
                           &table->grant.privilege, 0, 1,
 
7210
                           test(table->schema_table)) ||
 
7211
              check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
 
7212
             (check_access(thd, SELECT_ACL, table->db,
 
7213
                           &table->grant.privilege, 0, 0,
 
7214
                           test(table->schema_table)) ||
 
7215
              check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
 
7216
      DBUG_RETURN(TRUE);
 
7217
 
 
7218
    table->table_in_first_from_clause= 1;
 
7219
  }
 
7220
  /*
 
7221
    Is there tables of subqueries?
 
7222
  */
 
7223
  if (&lex->select_lex != lex->all_selects_list)
 
7224
  {
 
7225
    DBUG_PRINT("info",("Checking sub query list"));
 
7226
    for (table= tables; table; table= table->next_global)
 
7227
    {
 
7228
      if (!table->table_in_first_from_clause)
 
7229
      {
 
7230
        if (check_access(thd, SELECT_ACL, table->db,
 
7231
                         &table->grant.privilege, 0, 0,
 
7232
                         test(table->schema_table)) ||
 
7233
            check_grant(thd, SELECT_ACL, table, 0, 1, 0))
 
7234
          DBUG_RETURN(TRUE);
 
7235
      }
 
7236
    }
 
7237
  }
 
7238
 
 
7239
  if (select_lex->order_list.elements)
 
7240
    msg= "ORDER BY";
 
7241
  else if (select_lex->select_limit)
 
7242
    msg= "LIMIT";
 
7243
  if (msg)
 
7244
  {
 
7245
    my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
 
7246
    DBUG_RETURN(TRUE);
 
7247
  }
 
7248
  DBUG_RETURN(FALSE);
 
7249
}
 
7250
 
 
7251
/**
 
7252
  Multi delete query pre-check.
 
7253
 
 
7254
  @param thd                    Thread handler
 
7255
  @param tables         Global/local table list
 
7256
 
 
7257
  @retval
 
7258
    FALSE OK
 
7259
  @retval
 
7260
    TRUE  error
 
7261
*/
 
7262
 
 
7263
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
 
7264
{
 
7265
  SELECT_LEX *select_lex= &thd->lex->select_lex;
 
7266
  TABLE_LIST *aux_tables=
 
7267
    (TABLE_LIST *)thd->lex->auxiliary_table_list.first;
 
7268
  TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
 
7269
  DBUG_ENTER("multi_delete_precheck");
 
7270
 
 
7271
  /* sql_yacc guarantees that tables and aux_tables are not zero */
 
7272
  DBUG_ASSERT(aux_tables != 0);
 
7273
  if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
 
7274
    DBUG_RETURN(TRUE);
 
7275
 
 
7276
  /*
 
7277
    Since aux_tables list is not part of LEX::query_tables list we
 
7278
    have to juggle with LEX::query_tables_own_last value to be able
 
7279
    call check_table_access() safely.
 
7280
  */
 
7281
  thd->lex->query_tables_own_last= 0;
 
7282
  if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE))
 
7283
  {
 
7284
    thd->lex->query_tables_own_last= save_query_tables_own_last;
 
7285
    DBUG_RETURN(TRUE);
 
7286
  }
 
7287
  thd->lex->query_tables_own_last= save_query_tables_own_last;
 
7288
 
 
7289
  if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
 
7290
  {
 
7291
    my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
 
7292
               ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
 
7293
    DBUG_RETURN(TRUE);
 
7294
  }
 
7295
  DBUG_RETURN(FALSE);
 
7296
}
 
7297
 
 
7298
 
 
7299
/**
 
7300
  Link tables in auxilary table list of multi-delete with corresponding
 
7301
  elements in main table list, and set proper locks for them.
 
7302
 
 
7303
  @param lex   pointer to LEX representing multi-delete
 
7304
 
 
7305
  @retval
 
7306
    FALSE   success
 
7307
  @retval
 
7308
    TRUE    error
 
7309
*/
 
7310
 
 
7311
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
 
7312
{
 
7313
  TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
 
7314
  TABLE_LIST *target_tbl;
 
7315
  DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
 
7316
 
 
7317
  lex->table_count= 0;
 
7318
 
 
7319
  for (target_tbl= (TABLE_LIST *)lex->auxiliary_table_list.first;
 
7320
       target_tbl; target_tbl= target_tbl->next_local)
 
7321
  {
 
7322
    lex->table_count++;
 
7323
    /* All tables in aux_tables must be found in FROM PART */
 
7324
    TABLE_LIST *walk;
 
7325
    for (walk= tables; walk; walk= walk->next_local)
 
7326
    {
 
7327
      if (!my_strcasecmp(table_alias_charset,
 
7328
                         target_tbl->alias, walk->alias) &&
 
7329
          !strcmp(walk->db, target_tbl->db))
 
7330
        break;
 
7331
    }
 
7332
    if (!walk)
 
7333
    {
 
7334
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
7335
               target_tbl->table_name, "MULTI DELETE");
 
7336
      DBUG_RETURN(TRUE);
 
7337
    }
 
7338
    if (!walk->derived)
 
7339
    {
 
7340
      target_tbl->table_name= walk->table_name;
 
7341
      target_tbl->table_name_length= walk->table_name_length;
 
7342
    }
 
7343
    walk->updating= target_tbl->updating;
 
7344
    walk->lock_type= target_tbl->lock_type;
 
7345
    target_tbl->correspondent_table= walk;      // Remember corresponding table
 
7346
  }
 
7347
  DBUG_RETURN(FALSE);
 
7348
}
 
7349
 
 
7350
 
 
7351
/**
 
7352
  simple UPDATE query pre-check.
 
7353
 
 
7354
  @param thd            Thread handler
 
7355
  @param tables Global table list
 
7356
 
 
7357
  @retval
 
7358
    FALSE OK
 
7359
  @retval
 
7360
    TRUE  Error
 
7361
*/
 
7362
 
 
7363
bool update_precheck(THD *thd, TABLE_LIST *tables)
 
7364
{
 
7365
  DBUG_ENTER("update_precheck");
 
7366
  if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
 
7367
  {
 
7368
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
 
7369
    DBUG_RETURN(TRUE);
 
7370
  }
 
7371
  DBUG_RETURN(check_one_table_access(thd, UPDATE_ACL, tables));
 
7372
}
 
7373
 
 
7374
 
 
7375
/**
 
7376
  simple DELETE query pre-check.
 
7377
 
 
7378
  @param thd            Thread handler
 
7379
  @param tables Global table list
 
7380
 
 
7381
  @retval
 
7382
    FALSE  OK
 
7383
  @retval
 
7384
    TRUE   error
 
7385
*/
 
7386
 
 
7387
bool delete_precheck(THD *thd, TABLE_LIST *tables)
 
7388
{
 
7389
  DBUG_ENTER("delete_precheck");
 
7390
  if (check_one_table_access(thd, DELETE_ACL, tables))
 
7391
    DBUG_RETURN(TRUE);
 
7392
  /* Set privilege for the WHERE clause */
 
7393
  tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
 
7394
  DBUG_RETURN(FALSE);
 
7395
}
 
7396
 
 
7397
 
 
7398
/**
 
7399
  simple INSERT query pre-check.
 
7400
 
 
7401
  @param thd            Thread handler
 
7402
  @param tables Global table list
 
7403
 
 
7404
  @retval
 
7405
    FALSE  OK
 
7406
  @retval
 
7407
    TRUE   error
 
7408
*/
 
7409
 
 
7410
bool insert_precheck(THD *thd, TABLE_LIST *tables)
 
7411
{
 
7412
  LEX *lex= thd->lex;
 
7413
  DBUG_ENTER("insert_precheck");
 
7414
 
 
7415
  /*
 
7416
    Check that we have modify privileges for the first table and
 
7417
    select privileges for the rest
 
7418
  */
 
7419
  ulong privilege= (INSERT_ACL |
 
7420
                    (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
 
7421
                    (lex->value_list.elements ? UPDATE_ACL : 0));
 
7422
 
 
7423
  if (check_one_table_access(thd, privilege, tables))
 
7424
    DBUG_RETURN(TRUE);
 
7425
 
 
7426
  if (lex->update_list.elements != lex->value_list.elements)
 
7427
  {
 
7428
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
 
7429
    DBUG_RETURN(TRUE);
 
7430
  }
 
7431
  DBUG_RETURN(FALSE);
 
7432
}
 
7433
 
 
7434
 
 
7435
/**
 
7436
    @brief  Check privileges for SHOW CREATE TABLE statement.
 
7437
 
 
7438
    @param  thd    Thread context
 
7439
    @param  table  Target table
 
7440
 
 
7441
    @retval TRUE  Failure
 
7442
    @retval FALSE Success
 
7443
*/
 
7444
 
 
7445
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table)
 
7446
{
 
7447
  return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db,
 
7448
                      &table->grant.privilege, 0, 0,
 
7449
                      test(table->schema_table)) ||
 
7450
         check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0);
 
7451
}
 
7452
 
 
7453
 
 
7454
/**
 
7455
  CREATE TABLE query pre-check.
 
7456
 
 
7457
  @param thd                    Thread handler
 
7458
  @param tables         Global table list
 
7459
  @param create_table           Table which will be created
 
7460
 
 
7461
  @retval
 
7462
    FALSE   OK
 
7463
  @retval
 
7464
    TRUE   Error
 
7465
*/
 
7466
 
 
7467
bool create_table_precheck(THD *thd, TABLE_LIST *tables,
 
7468
                           TABLE_LIST *create_table)
 
7469
{
 
7470
  LEX *lex= thd->lex;
 
7471
  SELECT_LEX *select_lex= &lex->select_lex;
 
7472
  ulong want_priv;
 
7473
  bool error= TRUE;                                 // Error message is given
 
7474
  DBUG_ENTER("create_table_precheck");
 
7475
 
 
7476
  /*
 
7477
    Require CREATE [TEMPORARY] privilege on new table; for
 
7478
    CREATE TABLE ... SELECT, also require INSERT.
 
7479
  */
 
7480
 
 
7481
  want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
 
7482
              CREATE_TMP_ACL : CREATE_ACL) |
 
7483
             (select_lex->item_list.elements ? INSERT_ACL : 0);
 
7484
 
 
7485
  if (check_access(thd, want_priv, create_table->db,
 
7486
                   &create_table->grant.privilege, 0, 0,
 
7487
                   test(create_table->schema_table)) ||
 
7488
      check_merge_table_access(thd, create_table->db,
 
7489
                               (TABLE_LIST *)
 
7490
                               lex->create_info.merge_list.first))
 
7491
    goto err;
 
7492
  if (want_priv != CREATE_TMP_ACL &&
 
7493
      check_grant(thd, want_priv, create_table, 0, 1, 0))
 
7494
    goto err;
 
7495
 
 
7496
  if (select_lex->item_list.elements)
 
7497
  {
 
7498
    /* Check permissions for used tables in CREATE TABLE ... SELECT */
 
7499
 
 
7500
#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
 
7501
    /* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
 
7502
    /*
 
7503
      Only do the check for PS, because we on execute we have to check that
 
7504
      against the opened tables to ensure we don't use a table that is part
 
7505
      of the view (which can only be done after the table has been opened).
 
7506
    */
 
7507
    if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
 
7508
    {
 
7509
      /*
 
7510
        For temporary tables we don't have to check if the created table exists
 
7511
      */
 
7512
      if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
 
7513
          find_table_in_global_list(tables, create_table->db,
 
7514
                                    create_table->table_name))
 
7515
      {
 
7516
        error= FALSE;
 
7517
        goto err;
 
7518
      }
 
7519
    }
 
7520
#endif
 
7521
    if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
 
7522
      goto err;
 
7523
  }
 
7524
  else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
 
7525
  {
 
7526
    if (check_show_create_table_access(thd, tables))
 
7527
      goto err;
 
7528
  }
 
7529
  error= FALSE;
 
7530
 
 
7531
err:
 
7532
  DBUG_RETURN(error);
 
7533
}
 
7534
 
 
7535
 
 
7536
/**
 
7537
  negate given expression.
 
7538
 
 
7539
  @param thd  thread handler
 
7540
  @param expr expression for negation
 
7541
 
 
7542
  @return
 
7543
    negated expression
 
7544
*/
 
7545
 
 
7546
Item *negate_expression(THD *thd, Item *expr)
 
7547
{
 
7548
  Item *negated;
 
7549
  if (expr->type() == Item::FUNC_ITEM &&
 
7550
      ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
 
7551
  {
 
7552
    /* it is NOT(NOT( ... )) */
 
7553
    Item *arg= ((Item_func *) expr)->arguments()[0];
 
7554
    enum_parsing_place place= thd->lex->current_select->parsing_place;
 
7555
    if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
 
7556
      return arg;
 
7557
    /*
 
7558
      if it is not boolean function then we have to emulate value of
 
7559
      not(not(a)), it will be a != 0
 
7560
    */
 
7561
    return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1));
 
7562
  }
 
7563
 
 
7564
  if ((negated= expr->neg_transformer(thd)) != 0)
 
7565
    return negated;
 
7566
  return new Item_func_not(expr);
 
7567
}
 
7568
 
 
7569
/**
 
7570
  Set the specified definer to the default value, which is the
 
7571
  current user in the thread.
 
7572
 
 
7573
  @param[in]  thd       thread handler
 
7574
  @param[out] definer   definer
 
7575
*/
 
7576
 
 
7577
void get_default_definer(THD *thd, LEX_USER *definer)
 
7578
{
 
7579
  const Security_context *sctx= thd->security_ctx;
 
7580
 
 
7581
  definer->user.str= (char *) sctx->priv_user;
 
7582
  definer->user.length= strlen(definer->user.str);
 
7583
 
 
7584
  definer->host.str= (char *) sctx->priv_host;
 
7585
  definer->host.length= strlen(definer->host.str);
 
7586
 
 
7587
  definer->password.str= NULL;
 
7588
  definer->password.length= 0;
 
7589
}
 
7590
 
 
7591
 
 
7592
/**
 
7593
  Create default definer for the specified THD.
 
7594
 
 
7595
  @param[in] thd         thread handler
 
7596
 
 
7597
  @return
 
7598
    - On success, return a valid pointer to the created and initialized
 
7599
    LEX_USER, which contains definer information.
 
7600
    - On error, return 0.
 
7601
*/
 
7602
 
 
7603
LEX_USER *create_default_definer(THD *thd)
 
7604
{
 
7605
  LEX_USER *definer;
 
7606
 
 
7607
  if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
 
7608
    return 0;
 
7609
 
 
7610
  get_default_definer(thd, definer);
 
7611
 
 
7612
  return definer;
 
7613
}
 
7614
 
 
7615
 
 
7616
/**
 
7617
  Create definer with the given user and host names.
 
7618
 
 
7619
  @param[in] thd          thread handler
 
7620
  @param[in] user_name    user name
 
7621
  @param[in] host_name    host name
 
7622
 
 
7623
  @return
 
7624
    - On success, return a valid pointer to the created and initialized
 
7625
    LEX_USER, which contains definer information.
 
7626
    - On error, return 0.
 
7627
*/
 
7628
 
 
7629
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
 
7630
{
 
7631
  LEX_USER *definer;
 
7632
 
 
7633
  /* Create and initialize. */
 
7634
 
 
7635
  if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
 
7636
    return 0;
 
7637
 
 
7638
  definer->user= *user_name;
 
7639
  definer->host= *host_name;
 
7640
  definer->password.str= NULL;
 
7641
  definer->password.length= 0;
 
7642
 
 
7643
  return definer;
 
7644
}
 
7645
 
 
7646
 
 
7647
/**
 
7648
  Retuns information about user or current user.
 
7649
 
 
7650
  @param[in] thd          thread handler
 
7651
  @param[in] user         user
 
7652
 
 
7653
  @return
 
7654
    - On success, return a valid pointer to initialized
 
7655
    LEX_USER, which contains user information.
 
7656
    - On error, return 0.
 
7657
*/
 
7658
 
 
7659
LEX_USER *get_current_user(THD *thd, LEX_USER *user)
 
7660
{
 
7661
  if (!user->user.str)  // current_user
 
7662
    return create_default_definer(thd);
 
7663
 
 
7664
  return user;
 
7665
}
 
7666
 
 
7667
 
 
7668
/**
 
7669
  Check that byte length of a string does not exceed some limit.
 
7670
 
 
7671
  @param str         string to be checked
 
7672
  @param err_msg     error message to be displayed if the string is too long
 
7673
  @param max_length  max length
 
7674
 
 
7675
  @retval
 
7676
    FALSE   the passed string is not longer than max_length
 
7677
  @retval
 
7678
    TRUE    the passed string is longer than max_length
 
7679
 
 
7680
  NOTE
 
7681
    The function is not used in existing code but can be useful later?
 
7682
*/
 
7683
 
 
7684
bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
 
7685
                              uint max_byte_length)
 
7686
{
 
7687
  if (str->length <= max_byte_length)
 
7688
    return FALSE;
 
7689
 
 
7690
  my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_byte_length);
 
7691
 
 
7692
  return TRUE;
 
7693
}
 
7694
 
 
7695
 
 
7696
/*
 
7697
  Check that char length of a string does not exceed some limit.
 
7698
 
 
7699
  SYNOPSIS
 
7700
  check_string_char_length()
 
7701
      str              string to be checked
 
7702
      err_msg          error message to be displayed if the string is too long
 
7703
      max_char_length  max length in symbols
 
7704
      cs               string charset
 
7705
 
 
7706
  RETURN
 
7707
    FALSE   the passed string is not longer than max_char_length
 
7708
    TRUE    the passed string is longer than max_char_length
 
7709
*/
 
7710
 
 
7711
 
 
7712
bool check_string_char_length(LEX_STRING *str, const char *err_msg,
 
7713
                              uint max_char_length, CHARSET_INFO *cs,
 
7714
                              bool no_error)
 
7715
{
 
7716
  int well_formed_error;
 
7717
  uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
 
7718
                                      max_char_length, &well_formed_error);
 
7719
 
 
7720
  if (!well_formed_error &&  str->length == res)
 
7721
    return FALSE;
 
7722
 
 
7723
  if (!no_error)
 
7724
    my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_char_length);
 
7725
  return TRUE;
 
7726
}
 
7727
 
 
7728
 
 
7729
/*
 
7730
  Check if path does not contain mysql data home directory
 
7731
  SYNOPSIS
 
7732
    test_if_data_home_dir()
 
7733
    dir                     directory
 
7734
    conv_home_dir           converted data home directory
 
7735
    home_dir_len            converted data home directory length
 
7736
 
 
7737
  RETURN VALUES
 
7738
    0   ok
 
7739
    1   error  
 
7740
*/
 
7741
C_MODE_START
 
7742
 
 
7743
int test_if_data_home_dir(const char *dir)
 
7744
{
 
7745
  char path[FN_REFLEN];
 
7746
  int dir_len;
 
7747
  DBUG_ENTER("test_if_data_home_dir");
 
7748
 
 
7749
  if (!dir)
 
7750
    DBUG_RETURN(0);
 
7751
 
 
7752
  (void) fn_format(path, dir, "", "",
 
7753
                   (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
 
7754
  dir_len= strlen(path);
 
7755
  if (mysql_unpacked_real_data_home_len<= dir_len)
 
7756
  {
 
7757
    if (dir_len > mysql_unpacked_real_data_home_len &&
 
7758
        path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
 
7759
      DBUG_RETURN(0);
 
7760
 
 
7761
    if (lower_case_file_system)
 
7762
    {
 
7763
      if (!my_strnncoll(default_charset_info, (const uchar*) path,
 
7764
                        mysql_unpacked_real_data_home_len,
 
7765
                        (const uchar*) mysql_unpacked_real_data_home,
 
7766
                        mysql_unpacked_real_data_home_len))
 
7767
        DBUG_RETURN(1);
 
7768
    }
 
7769
    else if (!memcmp(path, mysql_unpacked_real_data_home,
 
7770
                     mysql_unpacked_real_data_home_len))
 
7771
      DBUG_RETURN(1);
 
7772
  }
 
7773
  DBUG_RETURN(0);
 
7774
}
 
7775
 
 
7776
C_MODE_END
 
7777
 
 
7778
 
 
7779
/**
 
7780
  Check that host name string is valid.
 
7781
 
 
7782
  @param[in] str string to be checked
 
7783
 
 
7784
  @return             Operation status
 
7785
    @retval  FALSE    host name is ok
 
7786
    @retval  TRUE     host name string is longer than max_length or
 
7787
                      has invalid symbols
 
7788
*/
 
7789
 
 
7790
bool check_host_name(LEX_STRING *str)
 
7791
{
 
7792
  const char *name= str->str;
 
7793
  const char *end= str->str + str->length;
 
7794
  if (check_string_byte_length(str, ER(ER_HOSTNAME), HOSTNAME_LENGTH))
 
7795
    return TRUE;
 
7796
 
 
7797
  while (name != end)
 
7798
  {
 
7799
    if (*name == '@')
 
7800
    {
 
7801
      my_printf_error(ER_UNKNOWN_ERROR, 
 
7802
                      "Malformed hostname (illegal symbol: '%c')", MYF(0),
 
7803
                      *name);
 
7804
      return TRUE;
 
7805
    }
 
7806
    name++;
 
7807
  }
 
7808
  return FALSE;
 
7809
}
 
7810
 
 
7811
 
 
7812
extern int MYSQLparse(void *thd); // from sql_yacc.cc
 
7813
 
 
7814
 
 
7815
/**
 
7816
  This is a wrapper of MYSQLparse(). All the code should call parse_sql()
 
7817
  instead of MYSQLparse().
 
7818
 
 
7819
  @param thd Thread context.
 
7820
  @param parser_state Parser state.
 
7821
  @param creation_ctx Object creation context.
 
7822
 
 
7823
  @return Error status.
 
7824
    @retval FALSE on success.
 
7825
    @retval TRUE on parsing error.
 
7826
*/
 
7827
 
 
7828
bool parse_sql(THD *thd,
 
7829
               Parser_state *parser_state,
 
7830
               Object_creation_ctx *creation_ctx)
 
7831
{
 
7832
  DBUG_ASSERT(thd->m_parser_state == NULL);
 
7833
 
 
7834
  /* Backup creation context. */
 
7835
 
 
7836
  Object_creation_ctx *backup_ctx= NULL;
 
7837
 
 
7838
  if (creation_ctx)
 
7839
    backup_ctx= creation_ctx->set_n_backup(thd);
 
7840
 
 
7841
  /* Set parser state. */
 
7842
 
 
7843
  thd->m_parser_state= parser_state;
 
7844
 
 
7845
  /* Parse the query. */
 
7846
 
 
7847
  bool mysql_parse_status= MYSQLparse(thd) != 0;
 
7848
 
 
7849
  /* Check that if MYSQLparse() failed, thd->is_error() is set. */
 
7850
 
 
7851
  DBUG_ASSERT(!mysql_parse_status ||
 
7852
              (mysql_parse_status && thd->is_error()));
 
7853
 
 
7854
  /* Reset parser state. */
 
7855
 
 
7856
  thd->m_parser_state= NULL;
 
7857
 
 
7858
  /* Restore creation context. */
 
7859
 
 
7860
  if (creation_ctx)
 
7861
    creation_ctx->restore_env(thd, backup_ctx);
 
7862
 
 
7863
  /* That's it. */
 
7864
 
 
7865
  return mysql_parse_status || thd->is_fatal_error;
 
7866
}
 
7867
 
 
7868
/**
 
7869
  @} (end of group Runtime_Environment)
 
7870
*/