~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

Merged Nathan from lp:~nlws/drizzle/fix-string-c-ptr-overrun

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Basic functions needed by many modules */
18
18
#include <drizzled/server_includes.h>
19
 
#include <drizzled/virtual_column_info.h>
20
19
#include <drizzled/field/timestamp.h>
21
20
#include <drizzled/field/null.h>
22
21
 
42
41
#include <drizzled/sql_base.h>
43
42
#include <drizzled/show.h>
44
43
#include <drizzled/item/cmpfunc.h>
45
 
 
46
 
 
47
 
/**
48
 
  return true if the table was created explicitly.
49
 
*/
50
 
inline bool is_user_table(Table * table)
51
 
{
52
 
  const char *name= table->s->table_name.str;
53
 
  return strncmp(name, TMP_FILE_PREFIX, TMP_FILE_PREFIX_LENGTH);
54
 
}
55
 
 
 
44
#include <drizzled/transaction_services.h>
 
45
#include <drizzled/check_stack_overrun.h>
 
46
#include <drizzled/lock.h>
 
47
 
 
48
extern drizzled::TransactionServices transaction_services;
56
49
 
57
50
/**
58
51
  @defgroup Data_Dictionary Data Dictionary
61
54
Table *unused_tables;                           /* Used by mysql_test */
62
55
HASH open_cache;                                /* Used by mysql_test */
63
56
static HASH table_def_cache;
64
 
static TABLE_SHARE *oldest_unused_share, end_of_unused_share;
 
57
static TableShare *oldest_unused_share, end_of_unused_share;
65
58
static pthread_mutex_t LOCK_table_share;
66
59
static bool table_def_inited= 0;
67
60
 
68
61
static int open_unireg_entry(Session *session, Table *entry, TableList *table_list,
69
62
                             const char *alias,
70
63
                             char *cache_key, uint32_t cache_key_length);
71
 
static void free_cache_entry(Table *entry);
 
64
extern "C" void free_cache_entry(void *entry);
72
65
static void close_old_data_files(Session *session, Table *table, bool morph_locks,
73
66
                                 bool send_refresh);
74
67
 
75
68
 
76
69
extern "C" unsigned char *table_cache_key(const unsigned char *record, size_t *length,
77
 
                                  bool not_used __attribute__((unused)))
 
70
                                  bool )
78
71
{
79
72
  Table *entry=(Table*) record;
80
73
  *length= entry->s->table_cache_key.length;
84
77
 
85
78
bool table_cache_init(void)
86
79
{
87
 
  return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
 
80
  return hash_init(&open_cache, &my_charset_bin,
 
81
                   (size_t) table_cache_size+16,
88
82
                   0, 0, table_cache_key,
89
 
                   (hash_free_key) free_cache_entry, 0);
 
83
                   free_cache_entry, 0);
90
84
}
91
85
 
92
86
void table_cache_free(void)
110
104
 
111
105
  SYNOPSIS
112
106
    create_table_def_key()
113
 
    session                     Thread handler
114
107
    key                 Create key here (must be of size MAX_DBKEY_LENGTH)
115
108
    table_list          Table definition
116
 
    tmp_table           Set if table is a tmp table
117
109
 
118
110
 IMPLEMENTATION
119
111
    The table cache_key is created from:
130
122
    Length of key
131
123
*/
132
124
 
133
 
uint32_t create_table_def_key(Session *session, char *key, TableList *table_list,
134
 
                          bool tmp_table)
 
125
uint32_t create_table_def_key(char *key, TableList *table_list)
135
126
{
136
 
  uint32_t key_length= (uint) (my_stpcpy(my_stpcpy(key, table_list->db)+1,
137
 
                                  table_list->table_name)-key)+1;
138
 
  if (tmp_table)
139
 
  {
140
 
    int4store(key + key_length, session->server_id);
141
 
    int4store(key + key_length + 4, session->variables.pseudo_thread_id);
142
 
    key_length+= TMP_TABLE_KEY_EXTRA;
143
 
  }
 
127
  uint32_t key_length;
 
128
  char *key_pos= key;
 
129
  key_pos= strcpy(key_pos, table_list->db) + strlen(table_list->db);
 
130
  key_pos= strcpy(key_pos+1, table_list->table_name) +
 
131
                  strlen(table_list->table_name);
 
132
  key_length= (uint32_t)(key_pos-key)+1;
 
133
 
144
134
  return key_length;
145
135
}
146
136
 
147
137
 
148
138
 
149
139
/*****************************************************************************
150
 
  Functions to handle table definition cach (TABLE_SHARE)
 
140
  Functions to handle table definition cach (TableShare)
151
141
*****************************************************************************/
152
142
 
153
143
extern "C" unsigned char *table_def_key(const unsigned char *record, size_t *length,
154
 
                                bool not_used __attribute__((unused)))
 
144
                                bool )
155
145
{
156
 
  TABLE_SHARE *entry=(TABLE_SHARE*) record;
 
146
  TableShare *entry=(TableShare*) record;
157
147
  *length= entry->table_cache_key.length;
158
148
  return (unsigned char*) entry->table_cache_key.str;
159
149
}
160
150
 
161
151
 
162
 
static void table_def_free_entry(TABLE_SHARE *share)
 
152
static void table_def_free_entry(TableShare *share)
163
153
{
164
154
  if (share->prev)
165
155
  {
169
159
    share->next->prev= share->prev;
170
160
    pthread_mutex_unlock(&LOCK_table_share);
171
161
  }
172
 
  free_table_share(share);
 
162
  share->free_table_share();
173
163
  return;
174
164
}
175
165
 
181
171
  oldest_unused_share= &end_of_unused_share;
182
172
  end_of_unused_share.prev= &oldest_unused_share;
183
173
 
184
 
  return hash_init(&table_def_cache, &my_charset_bin, table_def_size,
 
174
  return hash_init(&table_def_cache, &my_charset_bin, (size_t)table_def_size,
185
175
                   0, 0, table_def_key,
186
176
                   (hash_free_key) table_def_free_entry, 0);
187
177
}
206
196
 
207
197
 
208
198
/*
209
 
  Get TABLE_SHARE for a table.
 
199
  Get TableShare for a table.
210
200
 
211
201
  get_table_share()
212
202
  session                       Thread handle
213
203
  table_list            Table that should be opened
214
204
  key                   Table cache key
215
205
  key_length            Length of key
216
 
  db_flags              Flags to open_table_def():
217
 
                        OPEN_VIEW
218
206
  error                 out: Error code from open_table_def()
219
207
 
220
208
  IMPLEMENTATION
230
218
   #  Share for table
231
219
*/
232
220
 
233
 
TABLE_SHARE *get_table_share(Session *session, TableList *table_list, char *key,
234
 
                             uint32_t key_length, uint32_t db_flags, int *error)
 
221
TableShare *get_table_share(Session *session, TableList *table_list, char *key,
 
222
                             uint32_t key_length, uint32_t, int *error)
235
223
{
236
 
  TABLE_SHARE *share;
 
224
  TableShare *share;
237
225
 
238
226
  *error= 0;
239
227
 
240
228
  /* Read table definition from cache */
241
 
  if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key,
 
229
  if ((share= (TableShare*) hash_search(&table_def_cache,(unsigned char*) key,
242
230
                                         key_length)))
243
231
    goto found;
244
232
 
253
241
  */
254
242
  (void) pthread_mutex_lock(&share->mutex);
255
243
 
256
 
  /*
257
 
    We assign a new table id under the protection of the LOCK_open and
258
 
    the share's own mutex.  We do this insted of creating a new mutex
259
 
    and using it for the sole purpose of serializing accesses to a
260
 
    static variable, we assign the table id here.  We assign it to the
261
 
    share before inserting it into the table_def_cache to be really
262
 
    sure that it cannot be read from the cache without having a table
263
 
    id assigned.
264
 
 
265
 
    CAVEAT. This means that the table cannot be used for
266
 
    binlogging/replication purposes, unless get_table_share() has been
267
 
    called directly or indirectly.
268
 
   */
269
 
  assign_new_table_id(share);
270
 
 
271
244
  if (my_hash_insert(&table_def_cache, (unsigned char*) share))
272
245
  {
273
 
    free_table_share(share);
 
246
    share->free_table_share();
274
247
    return(0);                          // return error
275
248
  }
276
 
  if (open_table_def(session, share, db_flags))
 
249
  if (open_table_def(session, share))
277
250
  {
278
251
    *error= share->error;
279
252
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
284
257
  return(share);
285
258
 
286
259
found:
287
 
  /* 
 
260
  /*
288
261
     We found an existing table definition. Return it if we didn't get
289
262
     an error when reading the table definition from file.
290
263
  */
332
305
  For arguments and return values, see get_table_from_share()
333
306
*/
334
307
 
335
 
static TABLE_SHARE
 
308
static TableShare
336
309
*get_table_share_with_create(Session *session, TableList *table_list,
337
310
                             char *key, uint32_t key_length,
338
311
                             uint32_t db_flags, int *error)
339
312
{
340
 
  TABLE_SHARE *share;
341
 
  int tmp;
 
313
  TableShare *share;
342
314
 
343
315
  share= get_table_share(session, table_list, key, key_length, db_flags, error);
344
316
  /*
346
318
 
347
319
    If share is NULL, and there is no error, we're inside
348
320
    pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
349
 
    with the intention to silently drop non-existing tables 
 
321
    with the intention to silently drop non-existing tables
350
322
    from the pre-locking list. In this case we still need to try
351
323
    auto-discover before returning a NULL share.
352
324
 
353
325
    If share is NULL and the error is ER_NO_SUCH_TABLE, this is
354
 
    the same as above, only that the error was not silenced by 
 
326
    the same as above, only that the error was not silenced by
355
327
    pre-locking. Once again, we need to try to auto-discover
356
328
    the share.
357
329
 
364
336
 
365
337
    return(share);
366
338
 
367
 
  /* Table didn't exist. Check if some engine can provide it */
368
 
  if ((tmp= ha_create_table_from_engine(session, table_list->db,
369
 
                                        table_list->table_name)) < 0)
370
 
    return(0);
371
 
 
372
 
  if (tmp)
373
 
  {
374
 
    /* Give right error message */
375
 
    session->clear_error();
376
 
    my_printf_error(ER_UNKNOWN_ERROR,
377
 
                    "Failed to open '%-.64s', error while "
378
 
                    "unpacking from engine",
379
 
                    MYF(0), table_list->table_name);
380
 
    return(0);
381
 
  }
382
 
  /* Table existed in engine. Let's open it */
383
 
  drizzle_reset_errors(session, 1);                   // Clear warnings
384
 
  session->clear_error();                           // Clear error message
385
 
  return(get_table_share(session, table_list, key, key_length,
386
 
                              db_flags, error));
 
339
  return 0;
387
340
}
388
341
 
389
342
 
390
 
/* 
 
343
/*
391
344
   Mark that we are not using table share anymore.
392
345
 
393
346
   SYNOPSIS
408
361
     that the table is deleted or the thread is killed.
409
362
*/
410
363
 
411
 
void release_table_share(TABLE_SHARE *share,
412
 
                         enum release_type type __attribute__((unused)))
 
364
void release_table_share(TableShare *share,
 
365
                         enum release_type )
413
366
{
414
367
  bool to_be_deleted= 0;
415
368
 
455
408
 
456
409
  RETURN
457
410
    0  Not cached
458
 
    #  TABLE_SHARE for table
 
411
    #  TableShare for table
459
412
*/
460
413
 
461
 
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
 
414
TableShare *get_cached_table_share(const char *db, const char *table_name)
462
415
{
463
416
  char key[NAME_LEN*2+2];
464
417
  TableList table_list;
467
420
 
468
421
  table_list.db= (char*) db;
469
422
  table_list.table_name= (char*) table_name;
470
 
  key_length= create_table_def_key((Session*) 0, key, &table_list, 0);
471
 
  return (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
472
 
}  
 
423
  key_length= create_table_def_key(key, &table_list);
 
424
  return (TableShare*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
 
425
}
473
426
 
474
427
 
475
428
/*
492
445
 
493
446
void close_handle_and_leave_table_as_lock(Table *table)
494
447
{
495
 
  TABLE_SHARE *share, *old_share= table->s;
 
448
  TableShare *share, *old_share= table->s;
496
449
  char *key_buff;
497
450
  MEM_ROOT *mem_root= &table->mem_root;
498
451
 
530
483
 
531
484
  SYNOPSIS
532
485
    list_open_tables()
533
 
    session                     Thread Session
534
486
    wild                SQL like expression
535
487
 
536
488
  NOTES
543
495
    #           Pointer to list of names of open tables.
544
496
*/
545
497
 
546
 
OPEN_TableList *list_open_tables(Session *session __attribute__((unused)),
547
 
                                  const char *db, const char *wild)
 
498
OPEN_TableList *list_open_tables(const char *db, const char *wild)
548
499
{
549
500
  int result = 0;
550
501
  OPEN_TableList **start_list, *open_list;
559
510
  {
560
511
    OPEN_TableList *table;
561
512
    Table *entry=(Table*) hash_element(&open_cache,idx);
562
 
    TABLE_SHARE *share= entry->s;
 
513
    TableShare *share= entry->s;
563
514
 
564
515
    if (db && my_strcasecmp(system_charset_info, db, share->db.str))
565
516
      continue;
591
542
      open_list=0;                              // Out of memory
592
543
      break;
593
544
    }
594
 
    my_stpcpy((*start_list)->table=
595
 
           my_stpcpy(((*start_list)->db= (char*) ((*start_list)+1)),
596
 
                  share->db.str)+1,
597
 
           share->table_name.str);
 
545
    strcpy((*start_list)->table=
 
546
           strcpy(((*start_list)->db= (char*) ((*start_list)+1)),
 
547
           share->db.str)+share->db.length+1,
 
548
           share->table_name.str);
598
549
    (*start_list)->in_use= entry->in_use ? 1 : 0;
599
550
    (*start_list)->locked= entry->locked_by_name ? 1 : 0;
600
551
    start_list= &(*start_list)->next;
613
564
{                                               // Free all structures
614
565
  free_io_cache(table);
615
566
  if (table->file)                              // Not true if name lock
616
 
    closefrm(table, 1);                 // close file
 
567
    table->closefrm(true);                      // close file
617
568
  return;
618
569
}
619
570
 
622
573
 
623
574
  SYNOPSIS
624
575
    free_cache_entry()
625
 
    table               Table to remove
 
576
    entry               Table to remove
626
577
 
627
578
  NOTE
628
579
    We need to have a lock on LOCK_open when calling this
629
580
*/
630
581
 
631
 
static void free_cache_entry(Table *table)
 
582
void free_cache_entry(void *entry)
632
583
{
 
584
  Table *table= static_cast<Table *>(entry);
633
585
  intern_close_table(table);
634
586
  if (!table->in_use)
635
587
  {
642
594
        unused_tables=0;
643
595
    }
644
596
  }
645
 
  free((unsigned char*) table);
 
597
  free(table);
646
598
  return;
647
599
}
648
600
 
653
605
  if (table->sort.io_cache)
654
606
  {
655
607
    close_cached_file(table->sort.io_cache);
656
 
    free((unsigned char*) table->sort.io_cache);
657
 
    table->sort.io_cache=0;
 
608
    delete table->sort.io_cache;
 
609
    table->sort.io_cache= 0;
658
610
  }
659
611
  return;
660
612
}
772
724
    session->set_proc_info("Flushing tables");
773
725
 
774
726
    close_old_data_files(session,session->open_tables,1,1);
775
 
    mysql_ha_flush(session);
776
727
 
777
728
    bool found=1;
778
729
    /* Wait until all threads has closed all the tables we had locked */
861
812
 
862
813
  for (idx= 0; idx < table_def_cache.records; idx++)
863
814
  {
864
 
    TABLE_SHARE *share= (TABLE_SHARE *) hash_element(&table_def_cache, idx);
 
815
    TableShare *share= (TableShare *) hash_element(&table_def_cache, idx);
865
816
 
866
817
    /* Ignore if table is not open or does not have a connect_string */
867
818
    if (!share->connect_string.length || !share->ref_count)
882
833
    tmp.table_name= share->table_name.str;
883
834
    tmp.next_local= tables;
884
835
 
885
 
    tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp, 
 
836
    tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp,
886
837
                                       sizeof(TableList));
887
838
  }
888
839
 
919
870
{
920
871
  for (Table *table= session->temporary_tables ; table ; table= table->next)
921
872
  {
922
 
    if ((table->query_id == session->query_id) && ! table->open_by_handler)
 
873
    if (table->query_id == session->query_id)
923
874
    {
924
875
      table->query_id= 0;
925
876
      table->file->ha_reset();
1088
1039
      handled either before writing a query log event (inside
1089
1040
      binlog_query()) or when preparing a pending event.
1090
1041
     */
1091
 
    session->binlog_flush_pending_rows_event(true);
1092
1042
    mysql_unlock_tables(session, session->lock);
1093
1043
    session->lock=0;
1094
1044
  }
1148
1098
  return(found_old_table);
1149
1099
}
1150
1100
 
1151
 
 
1152
 
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
1153
 
static inline uint32_t  tmpkeyval(Session *session __attribute__((unused)),
1154
 
                              Table *table)
1155
 
{
1156
 
  return uint4korr(table->s->table_cache_key.str + table->s->table_cache_key.length - 4);
1157
 
}
1158
 
 
1159
 
 
1160
 
/*
1161
 
  Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1162
 
  creates one DROP TEMPORARY Table binlog event for each pseudo-thread 
1163
 
*/
1164
 
 
1165
 
void close_temporary_tables(Session *session)
1166
 
{
1167
 
  Table *table;
1168
 
  Table *next= NULL;
1169
 
  Table *prev_table;
1170
 
  /* Assume session->options has OPTION_QUOTE_SHOW_CREATE */
1171
 
  bool was_quote_show= true;
1172
 
 
1173
 
  if (!session->temporary_tables)
1174
 
    return;
1175
 
 
1176
 
  if (!drizzle_bin_log.is_open() || true )
1177
 
  {
1178
 
    Table *tmp_next;
1179
 
    for (table= session->temporary_tables; table; table= tmp_next)
1180
 
    {
1181
 
      tmp_next= table->next;
1182
 
      close_temporary(table, 1, 1);
1183
 
    }
1184
 
    session->temporary_tables= 0;
1185
 
    return;
1186
 
  }
1187
 
 
1188
 
  /* Better add "if exists", in case a RESET MASTER has been done */
1189
 
  const char stub[]= "DROP /*!40005 TEMPORARY */ Table IF EXISTS ";
1190
 
  uint32_t stub_len= sizeof(stub) - 1;
1191
 
  char buf[256];
1192
 
  String s_query= String(buf, sizeof(buf), system_charset_info);
1193
 
  bool found_user_tables= false;
1194
 
 
1195
 
  memcpy(buf, stub, stub_len);
1196
 
 
1197
 
  /*
1198
 
    Insertion sort of temp tables by pseudo_thread_id to build ordered list
1199
 
    of sublists of equal pseudo_thread_id
1200
 
  */
1201
 
 
1202
 
  for (prev_table= session->temporary_tables, table= prev_table->next;
1203
 
       table;
1204
 
       prev_table= table, table= table->next)
1205
 
  {
1206
 
    Table *prev_sorted /* same as for prev_table */, *sorted;
1207
 
    if (is_user_table(table))
1208
 
    {
1209
 
      if (!found_user_tables)
1210
 
        found_user_tables= true;
1211
 
      for (prev_sorted= NULL, sorted= session->temporary_tables; sorted != table;
1212
 
           prev_sorted= sorted, sorted= sorted->next)
1213
 
      {
1214
 
        if (!is_user_table(sorted) ||
1215
 
            tmpkeyval(session, sorted) > tmpkeyval(session, table))
1216
 
        {
1217
 
          /* move into the sorted part of the list from the unsorted */
1218
 
          prev_table->next= table->next;
1219
 
          table->next= sorted;
1220
 
          if (prev_sorted)
1221
 
          {
1222
 
            prev_sorted->next= table;
1223
 
          }
1224
 
          else
1225
 
          {
1226
 
            session->temporary_tables= table;
1227
 
          }
1228
 
          table= prev_table;
1229
 
          break;
1230
 
        }
1231
 
      }
1232
 
    }
1233
 
  }
1234
 
 
1235
 
  /* We always quote db,table names though it is slight overkill */
1236
 
  if (found_user_tables &&
1237
 
      !(was_quote_show= test(session->options & OPTION_QUOTE_SHOW_CREATE)))
1238
 
  {
1239
 
    session->options |= OPTION_QUOTE_SHOW_CREATE;
1240
 
  }
1241
 
 
1242
 
  /* scan sorted tmps to generate sequence of DROP */
1243
 
  for (table= session->temporary_tables; table; table= next)
1244
 
  {
1245
 
    if (is_user_table(table))
1246
 
    {
1247
 
      my_thread_id save_pseudo_thread_id= session->variables.pseudo_thread_id;
1248
 
      /* Set pseudo_thread_id to be that of the processed table */
1249
 
      session->variables.pseudo_thread_id= tmpkeyval(session, table);
1250
 
      /*
1251
 
        Loop forward through all tables within the sublist of
1252
 
        common pseudo_thread_id to create single DROP query.
1253
 
      */
1254
 
      for (s_query.length(stub_len);
1255
 
           table && is_user_table(table) &&
1256
 
             tmpkeyval(session, table) == session->variables.pseudo_thread_id;
1257
 
           table= next)
1258
 
      {
1259
 
        /*
1260
 
          We are going to add 4 ` around the db/table names and possible more
1261
 
          due to special characters in the names
1262
 
        */
1263
 
        append_identifier(session, &s_query, table->s->db.str, strlen(table->s->db.str));
1264
 
        s_query.append('.');
1265
 
        append_identifier(session, &s_query, table->s->table_name.str,
1266
 
                          strlen(table->s->table_name.str));
1267
 
        s_query.append(',');
1268
 
        next= table->next;
1269
 
        close_temporary(table, 1, 1);
1270
 
      }
1271
 
      session->clear_error();
1272
 
      const CHARSET_INFO * const cs_save= session->variables.character_set_client;
1273
 
      session->variables.character_set_client= system_charset_info;
1274
 
      Query_log_event qinfo(session, s_query.ptr(),
1275
 
                            s_query.length() - 1 /* to remove trailing ',' */,
1276
 
                            0, false);
1277
 
      session->variables.character_set_client= cs_save;
1278
 
      /*
1279
 
        Imagine the thread had created a temp table, then was doing a
1280
 
        SELECT, and the SELECT was killed. Then it's not clever to
1281
 
        mark the statement above as "killed", because it's not really
1282
 
        a statement updating data, and there are 99.99% chances it
1283
 
        will succeed on slave.  If a real update (one updating a
1284
 
        persistent table) was killed on the master, then this real
1285
 
        update will be logged with error_code=killed, rightfully
1286
 
        causing the slave to stop.
1287
 
      */
1288
 
      qinfo.error_code= 0;
1289
 
      drizzle_bin_log.write(&qinfo);
1290
 
      session->variables.pseudo_thread_id= save_pseudo_thread_id;
1291
 
    }
1292
 
    else
1293
 
    {
1294
 
      next= table->next;
1295
 
      close_temporary(table, 1, 1);
1296
 
    }
1297
 
  }
1298
 
  if (!was_quote_show)
1299
 
    session->options&= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
1300
 
  session->temporary_tables=0;
1301
 
}
1302
 
 
1303
1101
/*
1304
1102
  Find table in list.
1305
1103
 
1439
1237
*/
1440
1238
 
1441
1239
void update_non_unique_table_error(TableList *update,
1442
 
                                   const char *operation __attribute__((unused)),
1443
 
                                   TableList *duplicate __attribute__((unused)))
 
1240
                                   const char *,
 
1241
                                   TableList *)
1444
1242
{
1445
1243
  my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
1446
1244
}
1462
1260
  uint  key_length;
1463
1261
  Table *table;
1464
1262
 
1465
 
  key_length= create_table_def_key(session, key, table_list, 1);
 
1263
  key_length= create_table_def_key(key, table_list);
1466
1264
  for (table=session->temporary_tables ; table ; table= table->next)
1467
1265
  {
1468
1266
    if (table->s->table_cache_key.length == key_length &&
1548
1346
    if (session->temporary_tables)
1549
1347
      table->next->prev= 0;
1550
1348
  }
1551
 
  if (session->slave_thread)
1552
 
  {
1553
 
    /* natural invariant of temporary_tables */
1554
 
    assert(slave_open_temp_tables || !session->temporary_tables);
1555
 
    slave_open_temp_tables--;
1556
 
  }
1557
1349
  close_temporary(table, free_share, delete_table);
1558
1350
  return;
1559
1351
}
1569
1361
 
1570
1362
void close_temporary(Table *table, bool free_share, bool delete_table)
1571
1363
{
1572
 
  handlerton *table_type= table->s->db_type();
 
1364
  StorageEngine *table_type= table->s->db_type();
1573
1365
 
1574
1366
  free_io_cache(table);
1575
 
  closefrm(table, 0);
 
1367
  table->closefrm(false);
1576
1368
 
1577
1369
  if (delete_table)
1578
1370
    rm_temporary_table(table_type, table->s->path.str);
1579
1371
 
1580
1372
  if (free_share)
1581
1373
  {
1582
 
    free_table_share(table->s);
 
1374
    table->s->free_table_share();
1583
1375
    free((char*) table);
1584
1376
  }
1585
1377
  return;
1594
1386
  session->slave_proxy_id, separated by '\0'.
1595
1387
*/
1596
1388
 
1597
 
bool rename_temporary_table(Session* session, Table *table, const char *db,
1598
 
                            const char *table_name)
 
1389
bool rename_temporary_table(Table *table, const char *db, const char *table_name)
1599
1390
{
1600
1391
  char *key;
1601
1392
  uint32_t key_length;
1602
 
  TABLE_SHARE *share= table->s;
 
1393
  TableShare *share= table->s;
1603
1394
  TableList table_list;
1604
1395
 
1605
1396
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
1606
 
    return(1);                          /* purecov: inspected */
 
1397
    return true;                                /* purecov: inspected */
1607
1398
 
1608
1399
  table_list.db= (char*) db;
1609
1400
  table_list.table_name= (char*) table_name;
1610
 
  key_length= create_table_def_key(session, key, &table_list, 1);
 
1401
  key_length= create_table_def_key(key, &table_list);
1611
1402
  share->set_table_cache_key(key, key_length);
1612
 
  return(0);
 
1403
 
 
1404
  return false;
1613
1405
}
1614
1406
 
1615
1407
 
1715
1507
    close_temporary_table(session, table, 1, 1);
1716
1508
  else
1717
1509
  {
1718
 
    handlerton *table_type= table->s->db_type();
 
1510
    StorageEngine *table_type= table->s->db_type();
1719
1511
    pthread_mutex_lock(&LOCK_open);
1720
1512
    /*
1721
1513
      unlink_open_table() also tells threads waiting for refresh or close
1735
1527
     wait_for_condition()
1736
1528
     session    Thread handler
1737
1529
     mutex      mutex that is currently hold that is associated with condition
1738
 
                Will be unlocked on return     
 
1530
                Will be unlocked on return
1739
1531
     cond       Condition to wait for
1740
1532
*/
1741
1533
 
1760
1552
    condition variables that are guranteed to not disapper (freed) even if this
1761
1553
    mutex is unlocked
1762
1554
  */
1763
 
    
 
1555
 
1764
1556
  pthread_mutex_unlock(mutex);
1765
1557
  pthread_mutex_lock(&session->mysys_var->mutex);
1766
1558
  session->mysys_var->current_mutex= 0;
1788
1580
 
1789
1581
  if (!tables->table)
1790
1582
    my_error(ER_TABLE_NOT_LOCKED, MYF(0), tables->alias);
1791
 
  else if (tables->table->reginfo.lock_type < TL_WRITE_LOW_PRIORITY)
 
1583
  else if (tables->table->reginfo.lock_type <= TL_WRITE_DEFAULT)
1792
1584
    my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->alias);
1793
1585
  else
1794
1586
  {
1830
1622
bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in)
1831
1623
{
1832
1624
  Table *table= table_list->table;
1833
 
  TABLE_SHARE *share;
 
1625
  TableShare *share;
1834
1626
  char *table_name= table_list->table_name;
1835
1627
  Table orig_table;
1836
1628
 
1910
1702
                                      uint32_t key_length)
1911
1703
{
1912
1704
  Table *table;
1913
 
  TABLE_SHARE *share;
 
1705
  TableShare *share;
1914
1706
  char *key_buff;
1915
1707
 
1916
1708
  safe_mutex_assert_owner(&LOCK_open);
1925
1717
                       &share, sizeof(*share),
1926
1718
                       &key_buff, key_length,
1927
1719
                       NULL))
1928
 
    return(NULL);
 
1720
    return NULL;
1929
1721
 
1930
1722
  table->s= share;
1931
1723
  share->set_table_cache_key(key_buff, key, key_length);
1936
1728
  if (my_hash_insert(&open_cache, (unsigned char*)table))
1937
1729
  {
1938
1730
    free((unsigned char*) table);
1939
 
    return(NULL);
 
1731
    return NULL;
1940
1732
  }
1941
1733
 
1942
1734
  return(table);
1969
1761
                                   const char *table_name, Table **table)
1970
1762
{
1971
1763
  char key[MAX_DBKEY_LENGTH];
 
1764
  char *key_pos= key;
1972
1765
  uint32_t key_length;
1973
1766
 
1974
 
  key_length= (uint)(my_stpcpy(my_stpcpy(key, db) + 1, table_name) - key) + 1;
 
1767
  key_pos= strcpy(key_pos, db) + strlen(db);
 
1768
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
1769
  key_length= (uint32_t) (key_pos-key)+1;
 
1770
 
1975
1771
  pthread_mutex_lock(&LOCK_open);
1976
1772
 
1977
1773
  if (hash_search(&open_cache, (unsigned char *)key, key_length))
1992
1788
  return(false);
1993
1789
}
1994
1790
 
1995
 
 
1996
 
/**
1997
 
    Check that table exists in table definition cache, on disk
1998
 
    or in some storage engine.
1999
 
 
2000
 
    @param       session     Thread context
2001
 
    @param       table   Table list element
2002
 
    @param[out]  exists  Out parameter which is set to true if table
2003
 
                         exists and to false otherwise.
2004
 
 
2005
 
    @note This function assumes that caller owns LOCK_open mutex.
2006
 
          It also assumes that the fact that there are no name-locks
2007
 
          on the table was checked beforehand.
2008
 
 
2009
 
    @note If there is no .FRM file for the table but it exists in one
2010
 
          of engines (e.g. it was created on another node of NDB cluster)
2011
 
          this function will fetch and create proper .FRM file for it.
2012
 
 
2013
 
    @retval  true   Some error occured
2014
 
    @retval  false  No error. 'exists' out parameter set accordingly.
2015
 
*/
2016
 
 
2017
 
bool check_if_table_exists(Session *session, TableList *table, bool *exists)
2018
 
{
2019
 
  char path[FN_REFLEN];
2020
 
  int rc;
2021
 
 
2022
 
  safe_mutex_assert_owner(&LOCK_open);
2023
 
 
2024
 
  *exists= true;
2025
 
 
2026
 
  if (get_cached_table_share(table->db, table->table_name))
2027
 
    return(false);
2028
 
 
2029
 
  build_table_filename(path, sizeof(path) - 1, table->db, table->table_name,
2030
 
                       reg_ext, 0);
2031
 
 
2032
 
  if (!access(path, F_OK))
2033
 
    return(false);
2034
 
 
2035
 
  /* .FRM file doesn't exist. Check if some engine can provide it. */
2036
 
 
2037
 
  rc= ha_create_table_from_engine(session, table->db, table->table_name);
2038
 
 
2039
 
  if (rc < 0)
2040
 
  {
2041
 
    /* Table does not exists in engines as well. */
2042
 
    *exists= false;
2043
 
    return(false);
2044
 
  }
2045
 
  else if (!rc)
2046
 
  {
2047
 
    /* Table exists in some engine and .FRM for it was created. */
2048
 
    return(false);
2049
 
  }
2050
 
  else /* (rc > 0) */
2051
 
  {
2052
 
    my_printf_error(ER_UNKNOWN_ERROR, "Failed to open '%-.64s', error while "
2053
 
                    "unpacking from engine", MYF(0), table->table_name);
2054
 
    return(true);
2055
 
  }
2056
 
}
2057
 
 
2058
 
 
2059
1791
/*
2060
1792
  Open a table.
2061
1793
 
2111
1843
  if (session->killed)
2112
1844
    return(0);
2113
1845
 
2114
 
  key_length= (create_table_def_key(session, key, table_list, 1) -
2115
 
               TMP_TABLE_KEY_EXTRA);
 
1846
  key_length= create_table_def_key(key, table_list);
2116
1847
 
2117
1848
  /*
2118
1849
    Unless requested otherwise, try to resolve this table in the list
2124
1855
  {
2125
1856
    for (table= session->temporary_tables; table ; table=table->next)
2126
1857
    {
2127
 
      if (table->s->table_cache_key.length == key_length +
2128
 
          TMP_TABLE_KEY_EXTRA &&
2129
 
          !memcmp(table->s->table_cache_key.str, key,
2130
 
                  key_length + TMP_TABLE_KEY_EXTRA))
 
1858
      if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length))
2131
1859
      {
2132
1860
        /*
2133
1861
          We're trying to use the same temporary table twice in a query.
2135
1863
          is always represented by only one Table object in Session, and
2136
1864
          it can not be cloned. Emit an error for an unsupported behaviour.
2137
1865
        */
2138
 
        if (table->query_id)
2139
 
        {
2140
 
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
2141
 
          return(0);
2142
 
        }
2143
 
        table->query_id= session->query_id;
2144
 
        session->thread_specific_used= true;
 
1866
        if (table->query_id)
 
1867
        {
 
1868
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 
1869
          return(0);
 
1870
        }
 
1871
        table->query_id= session->query_id;
2145
1872
        goto reset;
2146
1873
      }
2147
1874
    }
2161
1888
    TODO: move this block into a separate function.
2162
1889
  */
2163
1890
  if (session->locked_tables)
2164
 
  {                                             // Using table locks
 
1891
  { // Using table locks
2165
1892
    Table *best_table= 0;
2166
1893
    int best_distance= INT_MIN;
2167
1894
    bool check_if_used= false;
2168
1895
    for (table=session->open_tables; table ; table=table->next)
2169
1896
    {
2170
1897
      if (table->s->table_cache_key.length == key_length &&
2171
 
          !memcmp(table->s->table_cache_key.str, key, key_length))
 
1898
          !memcmp(table->s->table_cache_key.str, key, key_length))
2172
1899
      {
2173
1900
        if (check_if_used && table->query_id &&
2174
1901
            table->query_id != session->query_id)
2278
2005
  }
2279
2006
 
2280
2007
  /*
2281
 
    In order for the back off and re-start process to work properly,
2282
 
    handler tables having old versions (due to FLUSH TABLES or pending
2283
 
    name-lock) MUST be closed. This is specially important if a name-lock
2284
 
    is pending for any table of the handler_tables list, otherwise a
2285
 
    deadlock may occur.
2286
 
  */
2287
 
  if (session->handler_tables)
2288
 
    mysql_ha_flush(session);
2289
 
 
2290
 
  /*
2291
2008
    Actually try to find the table in the open_cache.
2292
2009
    The cache may contain several "Table" instances for the same
2293
2010
    physical table. The instances that are currently "in use" by
2316
2033
      need to back off and re-start opening tables.
2317
2034
      If we do not back off now, we may dead lock in case of lock
2318
2035
      order mismatch with some other thread:
2319
 
      c1: name lock t1; -- sort of exclusive lock 
 
2036
      c1: name lock t1; -- sort of exclusive lock
2320
2037
      c2: open t2;      -- sort of shared lock
2321
2038
      c1: name lock t2; -- blocks
2322
2039
      c2: open t1; -- blocks
2333
2050
      /* Avoid self-deadlocks by detecting self-dependencies. */
2334
2051
      if (table->open_placeholder && table->in_use == session)
2335
2052
      {
2336
 
        pthread_mutex_unlock(&LOCK_open);
 
2053
        pthread_mutex_unlock(&LOCK_open);
2337
2054
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
2338
2055
        return(0);
2339
2056
      }
2374
2091
      }
2375
2092
      else
2376
2093
      {
2377
 
        pthread_mutex_unlock(&LOCK_open);
 
2094
        pthread_mutex_unlock(&LOCK_open);
2378
2095
      }
2379
2096
      /*
2380
2097
        There is a refresh in progress for this table.
2381
2098
        Signal the caller that it has to try again.
2382
2099
      */
2383
2100
      if (refresh)
2384
 
        *refresh=1;
 
2101
        *refresh=1;
2385
2102
      return(0);
2386
2103
    }
2387
2104
  }
2389
2106
  {
2390
2107
    /* Unlink the table from "unused_tables" list. */
2391
2108
    if (table == unused_tables)
2392
 
    {                                           // First unused
2393
 
      unused_tables=unused_tables->next;        // Remove from link
 
2109
    {  // First unused
 
2110
      unused_tables=unused_tables->next; // Remove from link
2394
2111
      if (table == unused_tables)
2395
 
        unused_tables=0;
 
2112
        unused_tables=0;
2396
2113
    }
2397
 
    table->prev->next=table->next;              /* Remove from unused list */
 
2114
    table->prev->next=table->next; /* Remove from unused list */
2398
2115
    table->next->prev=table->prev;
2399
2116
    table->in_use= session;
2400
2117
  }
2408
2125
 
2409
2126
    if (table_list->create)
2410
2127
    {
2411
 
      bool exists;
2412
 
 
2413
 
      if (check_if_table_exists(session, table_list, &exists))
2414
 
      {
2415
 
        pthread_mutex_unlock(&LOCK_open);
2416
 
        return(NULL);
2417
 
      }
2418
 
 
2419
 
      if (!exists)
 
2128
      if(ha_table_exists_in_engine(session, table_list->db,
 
2129
                                   table_list->table_name)
 
2130
         != HA_ERR_TABLE_EXIST)
2420
2131
      {
2421
2132
        /*
2422
2133
          Table to be created, so we need to create placeholder in table-cache.
2424
2135
        if (!(table= table_cache_insert_placeholder(session, key, key_length)))
2425
2136
        {
2426
2137
          pthread_mutex_unlock(&LOCK_open);
2427
 
          return(NULL);
 
2138
          return NULL;
2428
2139
        }
2429
2140
        /*
2430
2141
          Link placeholder to the open tables list so it will be automatically
2441
2152
    }
2442
2153
 
2443
2154
    /* make a new table */
2444
 
    if (!(table=(Table*) my_malloc(sizeof(*table),MYF(MY_WME))))
 
2155
    table= (Table *) malloc(sizeof(*table));
 
2156
    if (table == NULL)
2445
2157
    {
2446
2158
      pthread_mutex_unlock(&LOCK_open);
2447
 
      return(NULL);
 
2159
      return NULL;
2448
2160
    }
2449
2161
 
2450
2162
    error= open_unireg_entry(session, table, table_list, alias, key, key_length);
2451
 
    /* Combine the follow two */
2452
 
    if (error > 0)
2453
 
    {
2454
 
      free((unsigned char*)table);
2455
 
      pthread_mutex_unlock(&LOCK_open);
2456
 
      return(NULL);
2457
 
    }
2458
 
    if (error < 0)
2459
 
    {
2460
 
      free((unsigned char*)table);
2461
 
      pthread_mutex_unlock(&LOCK_open);
2462
 
      return(0); // VIEW
 
2163
    if (error != 0)
 
2164
    {
 
2165
      free(table);
 
2166
      pthread_mutex_unlock(&LOCK_open);
 
2167
      return NULL;
2463
2168
    }
2464
2169
    my_hash_insert(&open_cache,(unsigned char*) table);
2465
2170
  }
2467
2172
  pthread_mutex_unlock(&LOCK_open);
2468
2173
  if (refresh)
2469
2174
  {
2470
 
    table->next=session->open_tables;           /* Link into simple list */
 
2175
    table->next=session->open_tables; /* Link into simple list */
2471
2176
    session->open_tables=table;
2472
2177
  }
2473
 
  table->reginfo.lock_type=TL_READ;             /* Assume read */
 
2178
  table->reginfo.lock_type=TL_READ; /* Assume read */
2474
2179
 
2475
2180
 reset:
2476
2181
  assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
2481
2186
  /* Fix alias if table name changes */
2482
2187
  if (strcmp(table->alias, alias))
2483
2188
  {
2484
 
    uint32_t length=(uint) strlen(alias)+1;
2485
 
    table->alias= (char*) my_realloc((char*) table->alias, length,
2486
 
                                     MYF(MY_WME));
 
2189
    uint32_t length=(uint32_t) strlen(alias)+1;
 
2190
    table->alias= (char*) realloc((char*) table->alias, length);
2487
2191
    memcpy((void*) table->alias, alias, length);
2488
2192
  }
2489
2193
  /* These variables are also set in reopen_table() */
2509
2213
 
2510
2214
Table *find_locked_table(Session *session, const char *db,const char *table_name)
2511
2215
{
2512
 
  char  key[MAX_DBKEY_LENGTH];
2513
 
  uint32_t key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
2216
  char key[MAX_DBKEY_LENGTH];
 
2217
  char *key_pos= key;
 
2218
  uint32_t key_length;
 
2219
 
 
2220
  key_pos= strcpy(key_pos, db) + strlen(db);
 
2221
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
2222
  key_length= (uint32_t)(key_pos-key)+1;
2514
2223
 
2515
2224
  for (Table *table=session->open_tables; table ; table=table->next)
2516
2225
  {
2517
2226
    if (table->s->table_cache_key.length == key_length &&
2518
 
        !memcmp(table->s->table_cache_key.str, key, key_length))
 
2227
        !memcmp(table->s->table_cache_key.str, key, key_length))
2519
2228
      return table;
2520
2229
  }
2521
2230
  return(0);
2552
2261
 
2553
2262
#ifdef EXTRA_DEBUG
2554
2263
  if (table->db_stat)
2555
 
    sql_print_error(_("Table %s had a open data handler in reopen_table"),
 
2264
    errmsg_printf(ERRMSG_LVL_ERROR, _("Table %s had a open data handler in reopen_table"),
2556
2265
                    table->alias);
2557
2266
#endif
2558
2267
  memset(&table_list, 0, sizeof(TableList));
2577
2286
  tmp.maybe_null=       table->maybe_null;
2578
2287
  tmp.status=           table->status;
2579
2288
 
2580
 
  tmp.s->table_map_id=  table->s->table_map_id;
2581
 
 
2582
2289
  /* Get state */
2583
2290
  tmp.in_use=           session;
2584
2291
  tmp.reginfo.lock_type=table->reginfo.lock_type;
2588
2295
  tmp.prev=             table->prev;
2589
2296
 
2590
2297
  if (table->file)
2591
 
    closefrm(table, 1);         // close file, free everything
 
2298
    table->closefrm(true);              // close file, free everything
2592
2299
 
2593
2300
  *table= tmp;
2594
2301
  table->default_column_bitmaps();
2632
2339
          the function probably has to be adjusted before it can be used
2633
2340
          anywhere outside ALTER Table.
2634
2341
 
2635
 
    @note Must not use TABLE_SHARE::table_name/db of the table being closed,
 
2342
    @note Must not use TableShare::table_name/db of the table being closed,
2636
2343
          the strings are used in a loop even after the share may be freed.
2637
2344
*/
2638
2345
 
2717
2424
    uint32_t opens=0;
2718
2425
    for (table= session->open_tables; table ; table=table->next)
2719
2426
      opens++;
2720
 
    tables= (Table**) my_alloca(sizeof(Table*)*opens);
 
2427
    tables= (Table**) malloc(sizeof(Table*)*opens);
2721
2428
  }
2722
2429
  else
2723
2430
    tables= &session->open_tables;
2758
2465
      already locked.
2759
2466
    */
2760
2467
    session->some_tables_deleted=0;
2761
 
    if ((lock= mysql_lock_tables(session, tables, (uint) (tables_ptr - tables),
 
2468
    if ((lock= mysql_lock_tables(session, tables, (uint32_t) (tables_ptr - tables),
2762
2469
                                 flags, &not_used)))
2763
2470
    {
2764
2471
      session->locked_tables=mysql_lock_merge(session->locked_tables,lock);
2776
2483
  }
2777
2484
  if (get_locks && tables)
2778
2485
  {
2779
 
    my_afree((unsigned char*) tables);
 
2486
    free((unsigned char*) tables);
2780
2487
  }
2781
2488
  broadcast_refresh();
2782
2489
  return(error);
2919
2626
  {
2920
2627
    session->some_tables_deleted=0;
2921
2628
    close_old_data_files(session,session->open_tables,0,dropping_tables != 0);
2922
 
    mysql_ha_flush(session);
2923
2629
    if (!table_is_used(session->open_tables,1))
2924
2630
      break;
2925
2631
    (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
3038
2744
  }
3039
2745
}
3040
2746
 
3041
 
 
3042
 
/*
3043
 
  Function to assign a new table map id to a table share.
3044
 
 
3045
 
  PARAMETERS
3046
 
 
3047
 
    share - Pointer to table share structure
3048
 
 
3049
 
  DESCRIPTION
3050
 
 
3051
 
    We are intentionally not checking that share->mutex is locked
3052
 
    since this function should only be called when opening a table
3053
 
    share and before it is entered into the table_def_cache (meaning
3054
 
    that it cannot be fetched by another thread, even accidentally).
3055
 
 
3056
 
  PRE-CONDITION(S)
3057
 
 
3058
 
    share is non-NULL
3059
 
    The LOCK_open mutex is locked
3060
 
 
3061
 
  POST-CONDITION(S)
3062
 
 
3063
 
    share->table_map_id is given a value that with a high certainty is
3064
 
    not used by any other table (the only case where a table id can be
3065
 
    reused is on wrap-around, which means more than 4 billion table
3066
 
    share opens have been executed while one table was open all the
3067
 
    time).
3068
 
 
3069
 
    share->table_map_id is not UINT32_MAX.
3070
 
 */
3071
 
void assign_new_table_id(TABLE_SHARE *share)
3072
 
{
3073
 
  static uint32_t last_table_id= UINT32_MAX;
3074
 
 
3075
 
  /* Preconditions */
3076
 
  assert(share != NULL);
3077
 
  safe_mutex_assert_owner(&LOCK_open);
3078
 
 
3079
 
  ulong tid= ++last_table_id;                   /* get next id */
3080
 
  /*
3081
 
    There is one reserved number that cannot be used.  Remember to
3082
 
    change this when 6-byte global table id's are introduced.
3083
 
  */
3084
 
  if (unlikely(tid == UINT32_MAX))
3085
 
    tid= ++last_table_id;
3086
 
  share->table_map_id= tid;
3087
 
 
3088
 
  /* Post conditions */
3089
 
  assert(share->table_map_id != UINT32_MAX);
3090
 
 
3091
 
  return;
3092
 
}
3093
 
 
3094
2747
/*
3095
2748
  Load a table definition from file and open unireg table
3096
2749
 
3117
2770
                             char *cache_key, uint32_t cache_key_length)
3118
2771
{
3119
2772
  int error;
3120
 
  TABLE_SHARE *share;
 
2773
  TableShare *share;
3121
2774
  uint32_t discover_retry_count= 0;
3122
2775
 
3123
2776
  safe_mutex_assert_owner(&LOCK_open);
3124
2777
retry:
3125
2778
  if (!(share= get_table_share_with_create(session, table_list, cache_key,
3126
 
                                           cache_key_length, 
 
2779
                                           cache_key_length,
3127
2780
                                           table_list->i_s_requested_object,
3128
2781
                                           &error)))
3129
2782
    return(1);
3130
2783
 
3131
2784
  while ((error= open_table_from_share(session, share, alias,
3132
 
                                       (uint) (HA_OPEN_KEYFILE |
 
2785
                                       (uint32_t) (HA_OPEN_KEYFILE |
3133
2786
                                               HA_OPEN_RNDFILE |
3134
2787
                                               HA_GET_INDEX |
3135
2788
                                               HA_TRY_READ_ONLY),
3147
2800
        Here we should wait until all threads has released the table.
3148
2801
        For now we do one retry. This may cause a deadlock if there
3149
2802
        is other threads waiting for other tables used by this thread.
3150
 
        
 
2803
 
3151
2804
        Proper fix would be to if the second retry failed:
3152
2805
        - Mark that table def changed
3153
2806
        - Return from open table
3155
2808
        - Start waiting that the share is released
3156
2809
        - Retry by opening all tables again
3157
2810
      */
3158
 
      if (ha_create_table_from_engine(session, table_list->db,
3159
 
                                      table_list->table_name))
3160
 
        goto err;
 
2811
 
3161
2812
      /*
3162
2813
        TO BE FIXED
3163
2814
        To avoid deadlock, only wait for release if no one else is
3184
2835
        goto err;
3185
2836
       if (wait_for_locked_table_names(session, table_list))
3186
2837
       {
3187
 
        unlock_table_name(session, table_list);
 
2838
        unlock_table_name(table_list);
3188
2839
        goto err;
3189
2840
       }
3190
2841
     }
3192
2843
     session->clear_error();                            // Clear error message
3193
2844
     error= 0;
3194
2845
     if (open_table_from_share(session, share, alias,
3195
 
                               (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
 
2846
                               (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3196
2847
                                       HA_GET_INDEX |
3197
2848
                                       HA_TRY_READ_ONLY),
3198
2849
                               EXTRA_RECORD,
3203
2854
       /* Give right error message */
3204
2855
       session->clear_error();
3205
2856
       my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str, my_errno);
3206
 
       sql_print_error(_("Couldn't repair table: %s.%s"), share->db.str,
 
2857
       errmsg_printf(ERRMSG_LVL_ERROR, _("Couldn't repair table: %s.%s"), share->db.str,
3207
2858
                       share->table_name.str);
3208
2859
       if (entry->file)
3209
 
        closefrm(entry, 0);
 
2860
        entry->closefrm(false);
3210
2861
       error=1;
3211
2862
     }
3212
2863
     else
3213
2864
       session->clear_error();                  // Clear error message
3214
2865
     pthread_mutex_lock(&LOCK_open);
3215
 
     unlock_table_name(session, table_list);
3216
 
 
 
2866
     unlock_table_name(table_list);
 
2867
 
3217
2868
     if (error)
3218
2869
       goto err;
3219
2870
     break;
3226
2877
  if (unlikely(entry->file->implicit_emptied))
3227
2878
  {
3228
2879
    entry->file->implicit_emptied= 0;
3229
 
    if (drizzle_bin_log.is_open())
3230
2880
    {
3231
2881
      char *query, *end;
3232
2882
      uint32_t query_buf_size= 20 + share->db.length + share->table_name.length +1;
3233
 
      if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
 
2883
      if ((query= (char*) malloc(query_buf_size)))
3234
2884
      {
3235
 
        /* this DELETE FROM is needed even with row-based binlogging */
3236
 
        end = strxmov(my_stpcpy(query, "DELETE FROM `"),
3237
 
                      share->db.str,"`.`",share->table_name.str,"`", NULL);
3238
 
        session->binlog_query(Session::STMT_QUERY_TYPE,
3239
 
                          query, (ulong)(end-query), false, false);
 
2885
        /* 
 
2886
          "this DELETE FROM is needed even with row-based binlogging"
 
2887
 
 
2888
          We inherited this from MySQL. TODO: fix it to issue a propper truncate
 
2889
          of the table (though that may not be completely right sematics).
 
2890
        */
 
2891
        end= query;
 
2892
        end+= sprintf(query, "DELETE FROM `%s`.`%s`", share->db.str,
 
2893
                      share->table_name.str);
 
2894
        transaction_services.rawStatement(session, query, (size_t)(end - query)); 
3240
2895
        free(query);
3241
2896
      }
3242
2897
      else
3243
2898
      {
3244
 
        /*
3245
 
          As replication is maybe going to be corrupted, we need to warn the
3246
 
          DBA on top of warning the client (which will automatically be done
3247
 
          because of MYF(MY_WME) in my_malloc() above).
3248
 
        */
3249
 
        sql_print_error(_("When opening HEAP table, could not allocate memory "
3250
 
                          "to write 'DELETE FROM `%s`.`%s`' to the binary log"),
3251
 
                        table_list->db, table_list->table_name);
3252
 
        closefrm(entry, 0);
 
2899
        errmsg_printf(ERRMSG_LVL_ERROR, _("When opening HEAP table, could not allocate memory "
 
2900
                                          "to write 'DELETE FROM `%s`.`%s`' to replication"),
 
2901
                      table_list->db, table_list->table_name);
 
2902
        my_error(ER_OUTOFMEMORY, MYF(0), query_buf_size);
 
2903
        entry->closefrm(false);
3253
2904
        goto err;
3254
2905
      }
3255
2906
    }
3487
3138
  /* Restore list. */
3488
3139
  table_l->next_global= save_next_global;
3489
3140
 
3490
 
  return(table_l->table);
 
3141
  return table_l->table;
3491
3142
}
3492
3143
 
3493
3144
 
3509
3160
  RETURN VALUES
3510
3161
    table               Opened table
3511
3162
    0                   Error
3512
 
  
 
3163
 
3513
3164
    If ok, the following are also set:
3514
3165
      table_list->lock_type     lock_type
3515
3166
      table_list->table         table
3580
3231
  uint32_t counter;
3581
3232
  bool need_reopen;
3582
3233
 
3583
 
  for ( ; ; ) 
 
3234
  for ( ; ; )
3584
3235
  {
3585
3236
    if (open_tables(session, &tables, &counter, 0))
3586
3237
      return(-1);
3615
3266
    false - ok
3616
3267
    true  - error
3617
3268
 
3618
 
  NOTE 
 
3269
  NOTE
3619
3270
    This is to be used on prepare stage when you don't read any
3620
3271
    data from the tables.
3621
3272
*/
3685
3336
        *(ptr++)= table->table;
3686
3337
    }
3687
3338
 
3688
 
    if (!(session->lock= mysql_lock_tables(session, start, (uint) (ptr - start),
 
3339
    if (!(session->lock= mysql_lock_tables(session, start, (uint32_t) (ptr - start),
3689
3340
                                       lock_flag, need_reopen)))
3690
3341
    {
3691
3342
      return(-1);
3769
3420
                            open_table_mode open_mode)
3770
3421
{
3771
3422
  Table *tmp_table;
3772
 
  TABLE_SHARE *share;
 
3423
  TableShare *share;
3773
3424
  char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
3774
 
  uint32_t key_length;
 
3425
  uint32_t key_length, path_length;
3775
3426
  TableList table_list;
3776
3427
 
3777
3428
  table_list.db=         (char*) db;
3778
3429
  table_list.table_name= (char*) table_name;
3779
3430
  /* Create the cache_key for temporary tables */
3780
 
  key_length= create_table_def_key(session, cache_key, &table_list, 1);
3781
 
 
3782
 
  if (!(tmp_table= (Table*) my_malloc(sizeof(*tmp_table) + sizeof(*share) +
3783
 
                                      strlen(path)+1 + key_length,
3784
 
                                      MYF(MY_WME))))
3785
 
    return(0);                          /* purecov: inspected */
3786
 
 
3787
 
  share= (TABLE_SHARE*) (tmp_table+1);
 
3431
  key_length= create_table_def_key(cache_key, &table_list);
 
3432
  path_length= strlen(path);
 
3433
 
 
3434
  if (!(tmp_table= (Table*) malloc(sizeof(*tmp_table) + sizeof(*share) +
 
3435
                                   path_length + 1 + key_length)))
 
3436
    return NULL;
 
3437
 
 
3438
  share= (TableShare*) (tmp_table+1);
3788
3439
  tmp_path= (char*) (share+1);
3789
 
  saved_cache_key= my_stpcpy(tmp_path, path)+1;
 
3440
  saved_cache_key= strcpy(tmp_path, path)+path_length+1;
3790
3441
  memcpy(saved_cache_key, cache_key, key_length);
3791
3442
 
3792
 
  init_tmp_table_share(session, share, saved_cache_key, key_length,
3793
 
                       strchr(saved_cache_key, '\0')+1, tmp_path);
 
3443
  share->init(saved_cache_key, key_length, strchr(saved_cache_key, '\0')+1, tmp_path);
3794
3444
 
3795
 
  if (open_table_def(session, share, 0) ||
 
3445
  if (open_table_def(session, share) ||
3796
3446
      open_table_from_share(session, share, table_name,
3797
3447
                            (open_mode == OTM_ALTER) ? 0 :
3798
 
                            (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
 
3448
                            (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3799
3449
                                    HA_GET_INDEX),
3800
3450
                            (open_mode == OTM_ALTER) ?
3801
3451
                              (EXTRA_RECORD | OPEN_FRM_FILE_ONLY)
3804
3454
                            tmp_table, open_mode))
3805
3455
  {
3806
3456
    /* No need to lock share->mutex as this is not needed for tmp tables */
3807
 
    free_table_share(share);
 
3457
    share->free_table_share();
3808
3458
    free((char*) tmp_table);
3809
3459
    return(0);
3810
3460
  }
3830
3480
      tmp_table->next->prev= tmp_table;
3831
3481
    session->temporary_tables= tmp_table;
3832
3482
    session->temporary_tables->prev= 0;
3833
 
    if (session->slave_thread)
3834
 
      slave_open_temp_tables++;
3835
3483
  }
3836
3484
  tmp_table->pos_in_table_list= 0;
3837
3485
  return(tmp_table);
3838
3486
}
3839
3487
 
3840
3488
 
3841
 
bool rm_temporary_table(handlerton *base, char *path)
 
3489
bool rm_temporary_table(StorageEngine *base, char *path)
3842
3490
{
3843
3491
  bool error=0;
3844
3492
  handler *file;
3845
 
  char *ext;
3846
 
 
3847
 
  delete_table_proto_file(path);
3848
 
 
3849
 
  my_stpcpy(ext= strchr(path, '\0'), reg_ext);
3850
 
  if (my_delete(path,MYF(0)))
 
3493
 
 
3494
  if(delete_table_proto_file(path))
3851
3495
    error=1; /* purecov: inspected */
3852
 
  *ext= 0;                              // remove extension
3853
 
  file= get_new_handler((TABLE_SHARE*) 0, current_session->mem_root, base);
 
3496
 
 
3497
  file= get_new_handler((TableShare*) 0, current_session->mem_root, base);
3854
3498
  if (file && file->ha_delete_table(path))
3855
3499
  {
3856
3500
    error=1;
3857
 
    sql_print_warning(_("Could not remove temporary table: '%s', error: %d"),
 
3501
    errmsg_printf(ERRMSG_LVL_WARN, _("Could not remove temporary table: '%s', error: %d"),
3858
3502
                      path, my_errno);
3859
3503
  }
3860
3504
  delete file;
3873
3517
 
3874
3518
/* Special Field pointers as return values of find_field_in_XXX functions. */
3875
3519
Field *not_found_field= (Field*) 0x1;
3876
 
Field *view_ref_found= (Field*) 0x2; 
 
3520
Field *view_ref_found= (Field*) 0x2;
3877
3521
 
3878
3522
#define WRONG_GRANT (Field*) -1
3879
3523
 
3887
3531
      We always want to register the used keys, as the column bitmap may have
3888
3532
      been set for all fields (for example for view).
3889
3533
    */
3890
 
      
3891
 
    table->covering_keys.intersect(field->part_of_key);
3892
 
    table->merge_keys.merge(field->part_of_key);
 
3534
 
 
3535
    table->covering_keys&= field->part_of_key;
 
3536
    table->merge_keys|= field->part_of_key;
3893
3537
 
3894
3538
    if (session->mark_used_columns == MARK_COLUMNS_READ)
3895
3539
    {
3948
3592
*/
3949
3593
 
3950
3594
static Field *
3951
 
find_field_in_natural_join(Session *session, TableList *table_ref, const char *name,
3952
 
                           uint32_t length __attribute__((unused)),
3953
 
                           Item **ref __attribute__((unused)), bool register_tree_change __attribute__((unused)),
3954
 
                           TableList **actual_table)
 
3595
find_field_in_natural_join(Session *session, TableList *table_ref,
 
3596
                           const char *name, uint32_t , Item **,
 
3597
                           bool, TableList **actual_table)
3955
3598
{
3956
3599
  List_iterator_fast<Natural_join_column>
3957
3600
    field_it(*(table_ref->join_columns));
3961
3604
  assert(table_ref->is_natural_join && table_ref->join_columns);
3962
3605
  assert(*actual_table == NULL);
3963
3606
 
3964
 
  for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col; 
 
3607
  for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col;
3965
3608
       curr_nj_col= field_it++)
3966
3609
  {
3967
3610
    if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name))
3969
3612
      if (nj_col)
3970
3613
      {
3971
3614
        my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where);
3972
 
        return(NULL);
 
3615
        return NULL;
3973
3616
      }
3974
3617
      nj_col= curr_nj_col;
3975
3618
    }
3976
3619
  }
3977
3620
  if (!nj_col)
3978
 
    return(NULL);
 
3621
    return NULL;
3979
3622
  {
3980
3623
    /* This is a base table. */
3981
3624
    assert(nj_col->table_ref->table == nj_col->table_field->table);
3984
3627
  }
3985
3628
 
3986
3629
  *actual_table= nj_col->table_ref;
3987
 
  
 
3630
 
3988
3631
  return(found_field);
3989
3632
}
3990
3633
 
4026
3669
    if (field_ptr)
4027
3670
    {
4028
3671
      /*
4029
 
        field_ptr points to field in TABLE_SHARE. Convert it to the matching
 
3672
        field_ptr points to field in TableShare. Convert it to the matching
4030
3673
        field in table
4031
3674
      */
4032
3675
      field_ptr= (table->field + (field_ptr - table->s->field));
4043
3686
 
4044
3687
  if (field_ptr && *field_ptr)
4045
3688
  {
4046
 
    if ((*field_ptr)->vcol_info)
4047
 
    {
4048
 
      if (session->mark_used_columns != MARK_COLUMNS_NONE)
4049
 
      {
4050
 
        Item *vcol_item= (*field_ptr)->vcol_info->expr_item;
4051
 
        assert(vcol_item);
4052
 
        vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
4053
 
        /* 
4054
 
          Set the virtual field for write here if 
4055
 
          1) this procedure is called for a read-only operation (SELECT), and
4056
 
          2) the virtual column is not phycically stored in the table
4057
 
        */
4058
 
        if ((session->mark_used_columns != MARK_COLUMNS_WRITE) && 
4059
 
            (not (*field_ptr)->is_stored))
4060
 
          bitmap_set_bit((*field_ptr)->table->write_set, (*field_ptr)->field_index);
4061
 
      }
4062
 
    }
4063
3689
    *cached_field_index_ptr= field_ptr - table->field;
4064
3690
    field= *field_ptr;
4065
3691
  }
4153
3779
          something !
4154
3780
  */
4155
3781
  if (/* Exclude nested joins. */
4156
 
      (!table_list->nested_join ||
 
3782
      (!table_list->nested_join) &&
4157
3783
       /* Include merge views and information schema tables. */
4158
 
       table_list->field_translation) &&
4159
3784
      /*
4160
3785
        Test if the field qualifiers match the table reference we plan
4161
3786
        to search.
4168
3793
 
4169
3794
  *actual_table= NULL;
4170
3795
 
4171
 
  if (table_list->field_translation)
4172
 
  {
4173
 
  }
4174
 
  else if (!table_list->nested_join)
 
3796
  if (!table_list->nested_join)
4175
3797
  {
4176
3798
    /* 'table_list' is a stored table. */
4177
3799
    assert(table_list->table);
4241
3863
        {
4242
3864
          Table *table= field_to_set->table;
4243
3865
          if (session->mark_used_columns == MARK_COLUMNS_READ)
4244
 
            bitmap_set_bit(table->read_set, field_to_set->field_index);
 
3866
            table->setReadSet(field_to_set->field_index);
4245
3867
          else
4246
 
            bitmap_set_bit(table->write_set, field_to_set->field_index);
 
3868
            table->setWriteSet(field_to_set->field_index);
4247
3869
        }
4248
3870
      }
4249
3871
  }
4276
3898
    if (field_ptr)
4277
3899
    {
4278
3900
      /*
4279
 
        field_ptr points to field in TABLE_SHARE. Convert it to the matching
 
3901
        field_ptr points to field in TableShare. Convert it to the matching
4280
3902
        field in table
4281
3903
      */
4282
3904
      field_ptr= (table->field + (field_ptr - table->s->field));
4341
3963
  const char *db= item->db_name;
4342
3964
  const char *table_name= item->table_name;
4343
3965
  const char *name= item->field_name;
4344
 
  uint32_t length=(uint) strlen(name);
 
3966
  uint32_t length=(uint32_t) strlen(name);
4345
3967
  char name_buff[NAME_LEN+1];
4346
3968
  TableList *cur_table= first_table;
4347
3969
  TableList *actual_table;
4391
4013
        fields.
4392
4014
      */
4393
4015
      {
4394
 
        SELECT_LEX *current_sel= session->lex->current_select;
4395
 
        SELECT_LEX *last_select= table_ref->select_lex;
 
4016
        Select_Lex *current_sel= session->lex->current_select;
 
4017
        Select_Lex *last_select= table_ref->select_lex;
4396
4018
        /*
4397
4019
          If the field was an outer referencee, mark all selects using this
4398
4020
          sub query as dependent on the outer query
4412
4034
      We can't do this in Item_field as this would change the
4413
4035
      'name' of the item which may be used in the select list
4414
4036
    */
4415
 
    strmake(name_buff, db, sizeof(name_buff)-1);
 
4037
    strncpy(name_buff, db, sizeof(name_buff)-1);
4416
4038
    my_casedn_str(files_charset_info, name_buff);
4417
4039
    db= name_buff;
4418
4040
  }
4461
4083
        Store the original table of the field, which may be different from
4462
4084
        cur_table in the case of NATURAL/USING join.
4463
4085
      */
4464
 
      item->cached_table= (!actual_table->cacheable_table || found) ?
4465
 
                          0 : actual_table;
 
4086
      item->cached_table= found ?  0 : actual_table;
4466
4087
 
4467
4088
      assert(session->where);
4468
4089
      /*
4541
4162
                                return not_found_item, report other errors,
4542
4163
                                return 0
4543
4164
      IGNORE_ERRORS             Do not report errors, return 0 if error
4544
 
    resolution                  Set to the resolution type if the item is found 
4545
 
                                (it says whether the item is resolved 
 
4165
    resolution                  Set to the resolution type if the item is found
 
4166
                                (it says whether the item is resolved
4546
4167
                                 against an alias name,
4547
4168
                                 or as a field name without alias,
4548
4169
                                 or as a field hidden by alias,
4549
4170
                                 or ignoring alias)
4550
 
                                
 
4171
 
4551
4172
  RETURN VALUES
4552
4173
    0                   Item is not found or item is not unique,
4553
4174
                        error message is reported
4581
4202
 
4582
4203
  *resolution= NOT_RESOLVED;
4583
4204
 
4584
 
  is_ref_by_name= (find->type() == Item::FIELD_ITEM  || 
 
4205
  is_ref_by_name= (find->type() == Item::FIELD_ITEM  ||
4585
4206
                   find->type() == Item::REF_ITEM);
4586
4207
  if (is_ref_by_name)
4587
4208
  {
4598
4219
 
4599
4220
      /*
4600
4221
        In case of group_concat() with ORDER BY condition in the QUERY
4601
 
        item_field can be field of temporary table without item name 
 
4222
        item_field can be field of temporary table without item name
4602
4223
        (if this field created from expression argument of group_concat()),
4603
4224
        => we have to check presence of name before compare
4604
 
      */ 
 
4225
      */
4605
4226
      if (!item_field->name)
4606
4227
        continue;
4607
4228
 
4626
4247
        if (item_field->field_name && item_field->table_name &&
4627
4248
            !my_strcasecmp(system_charset_info, item_field->field_name,
4628
4249
                           field_name) &&
4629
 
            !my_strcasecmp(table_alias_charset, item_field->table_name, 
 
4250
            !my_strcasecmp(table_alias_charset, item_field->table_name,
4630
4251
                           table_name) &&
4631
4252
            (!db_name || (item_field->db_name &&
4632
4253
                          !strcmp(item_field->db_name, db_name))))
4701
4322
      }
4702
4323
    }
4703
4324
    else if (!table_name)
4704
 
    { 
 
4325
    {
4705
4326
      if (is_ref_by_name && find->name && item->name &&
4706
4327
          !my_strcasecmp(system_charset_info,item->name,find->name))
4707
4328
      {
4877
4498
    if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
4878
4499
      goto err;
4879
4500
    field_name_1= nj_col_1->name();
4880
 
    is_using_column_1= using_fields && 
 
4501
    is_using_column_1= using_fields &&
4881
4502
      test_if_string_in_list(field_name_1, using_fields);
4882
4503
 
4883
4504
    /*
4904
4525
        (then cur_nj_col_2->is_common == true).
4905
4526
        Note that it is too early to check the columns outside of the
4906
4527
        USING list for ambiguity because they are not actually "referenced"
4907
 
        here. These columns must be checked only on unqualified reference 
 
4528
        here. These columns must be checked only on unqualified reference
4908
4529
        by name (e.g. in SELECT list).
4909
4530
      */
4910
4531
      if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2))
4991
4612
      {
4992
4613
        Table *table_1= nj_col_1->table_ref->table;
4993
4614
        /* Mark field_1 used for table cache. */
4994
 
        bitmap_set_bit(table_1->read_set, field_1->field_index);
4995
 
        table_1->covering_keys.intersect(field_1->part_of_key);
4996
 
        table_1->merge_keys.merge(field_1->part_of_key);
 
4615
        table_1->setReadSet(field_1->field_index);
 
4616
        table_1->covering_keys&= field_1->part_of_key;
 
4617
        table_1->merge_keys|= field_1->part_of_key;
4997
4618
      }
4998
4619
      if (field_2)
4999
4620
      {
5000
4621
        Table *table_2= nj_col_2->table_ref->table;
5001
4622
        /* Mark field_2 used for table cache. */
5002
 
        bitmap_set_bit(table_2->read_set, field_2->field_index);
5003
 
        table_2->covering_keys.intersect(field_2->part_of_key);
5004
 
        table_2->merge_keys.merge(field_2->part_of_key);
 
4623
        table_2->setReadSet(field_2->field_index);
 
4624
        table_2->covering_keys&= field_2->part_of_key;
 
4625
        table_2->merge_keys|= field_2->part_of_key;
5005
4626
      }
5006
4627
 
5007
4628
      if (using_fields != NULL)
5062
4683
*/
5063
4684
 
5064
4685
static bool
5065
 
store_natural_using_join_columns(Session *session __attribute__((unused)),
 
4686
store_natural_using_join_columns(Session *,
5066
4687
                                 TableList *natural_using_join,
5067
4688
                                 TableList *table_ref_1,
5068
4689
                                 TableList *table_ref_2,
5167
4788
    and materializes the row types of NATURAL/USING joins in a
5168
4789
    bottom-up manner until it reaches the TableList elements that
5169
4790
    represent the top-most NATURAL/USING joins. The procedure should be
5170
 
    applied to each element of SELECT_LEX::top_join_list (i.e. to each
 
4791
    applied to each element of Select_Lex::top_join_list (i.e. to each
5171
4792
    top-level element of the FROM clause).
5172
4793
 
5173
4794
  IMPLEMENTATION
5388
5009
****************************************************************************/
5389
5010
 
5390
5011
int setup_wild(Session *session,
5391
 
               TableList *tables __attribute__((unused)),
 
5012
               TableList *,
5392
5013
               List<Item> &fields,
5393
5014
               List<Item> *sum_func_list,
5394
5015
               uint32_t wild_num)
5566
5187
{
5567
5188
  uint32_t tablenr= 0;
5568
5189
 
5569
 
  assert ((select_insert && !tables->next_name_resolution_table) || !tables || 
 
5190
  assert ((select_insert && !tables->next_name_resolution_table) || !tables ||
5570
5191
               (context->table_list && context->first_name_resolution_table));
5571
5192
  /*
5572
5193
    this is used for INSERT ... SELECT.
5592
5213
      first_select_table= 0;
5593
5214
      tablenr= 0;
5594
5215
    }
5595
 
    setup_table_map(table, table_list, tablenr);
 
5216
    table->setup_table_map(table_list, tablenr);
5596
5217
    if (table_list->process_index_hints(table))
5597
5218
      return(1);
5598
5219
  }
5633
5254
    false ok;  In this case *map will include the chosen index
5634
5255
    true  error
5635
5256
*/
5636
 
bool setup_tables_and_check_access(Session *session, 
 
5257
bool setup_tables_and_check_access(Session *session,
5637
5258
                                   Name_resolution_context *context,
5638
5259
                                   List<TableList> *from_clause,
5639
5260
                                   TableList *tables,
5679
5300
  String *name;
5680
5301
  uint32_t pos;
5681
5302
 
5682
 
  map->clear_all();
 
5303
  map->reset();
5683
5304
  while ((name=it++))
5684
5305
  {
5685
5306
    if (table->s->keynames.type_names == 0 ||
5689
5310
    {
5690
5311
      my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
5691
5312
               table->pos_in_table_list->alias);
5692
 
      map->set_all();
 
5313
      map->set();
5693
5314
      return 1;
5694
5315
    }
5695
 
    map->set_bit(pos-1);
 
5316
    map->set(pos-1);
5696
5317
  }
5697
5318
  return 0;
5698
5319
}
5719
5340
bool
5720
5341
insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
5721
5342
              const char *table_name, List_iterator<Item> *it,
5722
 
              bool any_privileges __attribute__((unused)))
 
5343
              bool )
5723
5344
{
5724
5345
  Field_iterator_table_ref field_iterator;
5725
5346
  bool found;
5732
5353
      We can't do this in Item_field as this would change the
5733
5354
      'name' of the item which may be used in the select list
5734
5355
    */
5735
 
    strmake(name_buff, db_name, sizeof(name_buff)-1);
 
5356
    strncpy(name_buff, db_name, sizeof(name_buff)-1);
5736
5357
    my_casedn_str(files_charset_info, name_buff);
5737
5358
    db_name= name_buff;
5738
5359
  }
5756
5377
 
5757
5378
    assert(tables->is_leaf_for_name_resolution());
5758
5379
 
5759
 
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) || 
 
5380
    if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
5760
5381
        (db_name && strcmp(tables->db,db_name)))
5761
5382
      continue;
5762
5383
 
5793
5414
      if ((field= field_iterator.field()))
5794
5415
      {
5795
5416
        /* Mark fields as used to allow storage engine to optimze access */
5796
 
        bitmap_set_bit(field->table->read_set, field->field_index);
5797
 
        /*
5798
 
          Mark virtual fields for write and others that the virtual fields
5799
 
          depend on for read.
5800
 
        */
5801
 
        if (field->vcol_info)
5802
 
        {
5803
 
          Item *vcol_item= field->vcol_info->expr_item;
5804
 
          assert(vcol_item);
5805
 
          vcol_item->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
5806
 
          bitmap_set_bit(field->table->write_set, field->field_index);
5807
 
        }
 
5417
        field->table->setReadSet(field->field_index);
5808
5418
        if (table)
5809
5419
        {
5810
 
          table->covering_keys.intersect(field->part_of_key);
5811
 
          table->merge_keys.merge(field->part_of_key);
 
5420
          table->covering_keys&= field->part_of_key;
 
5421
          table->merge_keys|= field->part_of_key;
5812
5422
        }
5813
5423
        if (tables->is_natural_join)
5814
5424
        {
5825
5435
          if (field_table)
5826
5436
          {
5827
5437
            session->used_tables|= field_table->map;
5828
 
            field_table->covering_keys.intersect(field->part_of_key);
5829
 
            field_table->merge_keys.merge(field->part_of_key);
 
5438
            field_table->covering_keys&= field->part_of_key;
 
5439
            field_table->merge_keys|= field->part_of_key;
5830
5440
            field_table->used_fields++;
5831
5441
          }
5832
5442
        }
5879
5489
    false if all is OK
5880
5490
*/
5881
5491
 
5882
 
int setup_conds(Session *session, TableList *tables __attribute__((unused)),
 
5492
int setup_conds(Session *session, TableList *,
5883
5493
                TableList *leaves,
5884
5494
                COND **conds)
5885
5495
{
5886
 
  SELECT_LEX *select_lex= session->lex->current_select;
 
5496
  Select_Lex *select_lex= session->lex->current_select;
5887
5497
  TableList *table= NULL;       // For HP compilers
5888
5498
  void *save_session_marker= session->session_marker;
5889
5499
  /*
5890
 
    it_is_update set to true when tables of primary SELECT_LEX (SELECT_LEX
 
5500
    it_is_update set to true when tables of primary Select_Lex (Select_Lex
5891
5501
    which belong to LEX, i.e. most up SELECT) will be updated by
5892
5502
    INSERT/UPDATE/LOAD
5893
5503
    NOTE: using this condition helps to prevent call of prepare_check_option()
6019
5629
    table= rfield->table;
6020
5630
    if (rfield == table->next_number_field)
6021
5631
      table->auto_increment_field_not_null= true;
6022
 
    if (rfield->vcol_info && 
6023
 
        value->type() != Item::DEFAULT_VALUE_ITEM && 
6024
 
        value->type() != Item::NULL_ITEM &&
6025
 
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6026
 
    {
6027
 
      session->abort_on_warning= false;
6028
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6029
 
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6030
 
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6031
 
                          rfield->field_name, table->s->table_name.str);
6032
 
      session->abort_on_warning= abort_on_warning_saved;
6033
 
    }
6034
5632
    if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
6035
5633
    {
6036
5634
      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
6047
5645
    while ((table= t++))
6048
5646
    {
6049
5647
      /*
6050
 
        Do simple optimization to prevent unnecessary re-generating 
 
5648
        Do simple optimization to prevent unnecessary re-generating
6051
5649
        values for virtual fields
6052
5650
      */
6053
5651
      if (table != prev_table)
6054
 
      {
6055
5652
        prev_table= table;
6056
 
        if (table->vfield)
6057
 
        {
6058
 
          if (update_virtual_fields_marked_for_write(table, false))
6059
 
            goto err;
6060
 
        }
6061
 
      }
6062
5653
    }
6063
5654
  }
6064
5655
  session->abort_on_warning= abort_on_warning_saved;
6093
5684
 
6094
5685
bool
6095
5686
fill_record(Session *session, Field **ptr, List<Item> &values,
6096
 
            bool ignore_errors __attribute__((unused)))
 
5687
            bool )
6097
5688
{
6098
5689
  List_iterator_fast<Item> v(values);
6099
5690
  Item *value;
6101
5692
  Field *field;
6102
5693
  List<Table> tbl_list;
6103
5694
  bool abort_on_warning_saved= session->abort_on_warning;
6104
 
  
 
5695
 
6105
5696
  tbl_list.empty();
6106
5697
  /*
6107
5698
    Reset the table->auto_increment_field_not_null as it is valid for
6122
5713
    table= field->table;
6123
5714
    if (field == table->next_number_field)
6124
5715
      table->auto_increment_field_not_null= true;
6125
 
    if (field->vcol_info && 
6126
 
        value->type() != Item::DEFAULT_VALUE_ITEM && 
6127
 
        value->type() != Item::NULL_ITEM &&
6128
 
        table->s->table_category != TABLE_CATEGORY_TEMPORARY)
6129
 
    {
6130
 
      session->abort_on_warning= false;
6131
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6132
 
                          ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN,
6133
 
                          ER(ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN),
6134
 
                          field->field_name, table->s->table_name.str);
6135
 
      session->abort_on_warning= abort_on_warning_saved;
6136
 
    }
6137
5716
    if (value->save_in_field(field, 0) < 0)
6138
5717
      goto err;
6139
5718
    tbl_list.push_back(table);
6147
5726
    while ((table= t++))
6148
5727
    {
6149
5728
      /*
6150
 
        Do simple optimization to prevent unnecessary re-generating 
 
5729
        Do simple optimization to prevent unnecessary re-generating
6151
5730
        values for virtual fields
6152
5731
      */
6153
5732
      if (table != prev_table)
6154
5733
      {
6155
5734
        prev_table= table;
6156
 
        if (table->vfield)
6157
 
        {
6158
 
          if (update_virtual_fields_marked_for_write(table, false))
6159
 
          {
6160
 
            goto err;
6161
 
          }
6162
 
        }
6163
5735
      }
6164
5736
    }
6165
5737
  }
6176
5748
 
6177
5749
bool drizzle_rm_tmp_tables(void)
6178
5750
{
6179
 
  uint32_t i, idx;
6180
 
  char  filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
 
5751
  uint32_t  idx;
 
5752
  char  filePath[FN_REFLEN], filePathCopy[FN_REFLEN];
6181
5753
  MY_DIR *dirp;
6182
5754
  FILEINFO *file;
6183
 
  TABLE_SHARE share;
 
5755
  TableShare share;
6184
5756
  Session *session;
6185
5757
 
6186
 
  if (!(session= new Session))
6187
 
    return(1);
 
5758
  assert(drizzle_tmpdir);
 
5759
 
 
5760
  if (!(session= new Session(get_protocol())))
 
5761
    return true;
6188
5762
  session->thread_stack= (char*) &session;
6189
5763
  session->store_globals();
6190
5764
 
6191
 
  for (i=0; i<=drizzle_tmpdir_list.max; i++)
 
5765
  /* Remove all temp tables in the tmpdir */
 
5766
  /* See if the directory exists */
 
5767
  if ((dirp = my_dir(drizzle_tmpdir ,MYF(MY_WME | MY_DONT_SORT))))
6192
5768
  {
6193
 
    tmpdir=drizzle_tmpdir_list.list[i];
6194
 
    /* See if the directory exists */
6195
 
    if (!(dirp = my_dir(tmpdir,MYF(MY_WME | MY_DONT_SORT))))
6196
 
      continue;
6197
 
 
6198
5769
    /* Remove all SQLxxx tables from directory */
6199
 
 
6200
 
    for (idx=0 ; idx < (uint) dirp->number_off_files ; idx++)
 
5770
    for (idx=0 ; idx < (uint32_t) dirp->number_off_files ; idx++)
6201
5771
    {
6202
5772
      file=dirp->dir_entry+idx;
6203
5773
 
6211
5781
        char *ext= fn_ext(file->name);
6212
5782
        uint32_t ext_len= strlen(ext);
6213
5783
        uint32_t filePath_len= snprintf(filePath, sizeof(filePath),
6214
 
                                    "%s%c%s", tmpdir, FN_LIBCHAR,
6215
 
                                    file->name);
6216
 
        if (!memcmp(reg_ext, ext, ext_len))
 
5784
                                        "%s%c%s", drizzle_tmpdir, FN_LIBCHAR,
 
5785
                                        file->name);
 
5786
        if (!memcmp(".dfe", ext, ext_len))
6217
5787
        {
6218
5788
          handler *handler_file= 0;
6219
5789
          /* We should cut file extention before deleting of table */
6220
5790
          memcpy(filePathCopy, filePath, filePath_len - ext_len);
6221
5791
          filePathCopy[filePath_len - ext_len]= 0;
6222
 
          init_tmp_table_share(session, &share, "", 0, "", filePathCopy);
6223
 
          if (!open_table_def(session, &share, 0) &&
 
5792
          share.init(NULL, filePathCopy);
 
5793
          if (!open_table_def(session, &share) &&
6224
5794
              ((handler_file= get_new_handler(&share, session->mem_root,
6225
5795
                                              share.db_type()))))
6226
5796
          {
6227
5797
            handler_file->ha_delete_table(filePathCopy);
6228
5798
            delete handler_file;
6229
5799
          }
6230
 
          free_table_share(&share);
 
5800
          share.free_table_share();
6231
5801
        }
6232
5802
        /*
6233
5803
          File can be already deleted by tmp_table.file->delete_table().
6234
5804
          So we hide error messages which happnes during deleting of these
6235
5805
          files(MYF(0)).
6236
5806
        */
6237
 
        my_delete(filePath, MYF(0)); 
 
5807
        my_delete(filePath, MYF(0));
6238
5808
      }
6239
5809
    }
6240
5810
    my_dirend(dirp);
6241
5811
  }
 
5812
 
6242
5813
  delete session;
6243
 
  pthread_setspecific(THR_Session,  0);
6244
 
  return(0);
 
5814
 
 
5815
  return false;
6245
5816
}
6246
5817
 
6247
5818
 
6316
5887
                             uint32_t flags)
6317
5888
{
6318
5889
  char key[MAX_DBKEY_LENGTH];
 
5890
  char *key_pos= key;
6319
5891
  uint32_t key_length;
6320
5892
  Table *table;
6321
 
  TABLE_SHARE *share;
 
5893
  TableShare *share;
6322
5894
  bool result= 0, signalled= 0;
6323
5895
 
6324
 
  key_length=(uint) (my_stpcpy(my_stpcpy(key,db)+1,table_name)-key)+1;
 
5896
  key_pos= strcpy(key_pos, db) + strlen(db);
 
5897
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
 
5898
  key_length= (uint32_t) (key_pos-key)+1;
 
5899
 
6325
5900
  for (;;)
6326
5901
  {
6327
5902
    HASH_SEARCH_STATE state;
6377
5952
      hash_delete(&open_cache,(unsigned char*) unused_tables);
6378
5953
 
6379
5954
    /* Remove table from table definition cache if it's not in use */
6380
 
    if ((share= (TABLE_SHARE*) hash_search(&table_def_cache,(unsigned char*) key,
 
5955
    if ((share= (TableShare*) hash_search(&table_def_cache,(unsigned char*) key,
6381
5956
                                           key_length)))
6382
5957
    {
6383
5958
      share->version= 0;                          // Mark for delete
6436
6011
 
6437
6012
void kill_drizzle(void)
6438
6013
{
6439
 
 
6440
 
#if defined(SIGNALS_DONT_BREAK_READ)
6441
 
  abort_loop=1;                                 // Break connection loops
6442
 
  close_server_sock();                          // Force accept to wake up
6443
 
#endif
6444
 
 
6445
 
#if defined(HAVE_PTHREAD_KILL)
6446
6014
  pthread_kill(signal_thread, SIGTERM);
6447
 
#elif !defined(SIGNALS_DONT_BREAK_READ)
6448
 
  kill(current_pid, SIGTERM);
6449
 
#endif
6450
 
  shutdown_in_progress=1;                       // Safety if kill didn't work
6451
 
#ifdef SIGNALS_DONT_BREAK_READ
6452
 
  if (!kill_in_progress)
6453
 
  {
6454
 
    pthread_t tmp;
6455
 
    abort_loop=1;
6456
 
    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
6457
 
                           (void*) 0))
6458
 
      sql_print_error(_("Can't create thread to kill server"));
6459
 
  }
6460
 
#endif
6461
 
  return;;
 
6015
  shutdown_in_progress= 1;                      // Safety if kill didn't work
6462
6016
}