~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
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
17
/* Some general useful functions */
18
19
#include "mysql_priv.h"
20
#include <m_ctype.h>
21
#include "my_md5.h"
22
23
/* INFORMATION_SCHEMA name */
24
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
25
26
/* MYSQL_SCHEMA name */
27
LEX_STRING MYSQL_SCHEMA_NAME= {C_STRING_WITH_LEN("mysql")};
28
29
/* Functions defined in this file */
30
31
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
32
                      myf errortype, int errarg);
33
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
34
                           uchar *head, File file);
35
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
36
			      uint types, char **names);
37
static uint find_field(Field **fields, uchar *record, uint start, uint length);
38
39
/**************************************************************************
40
  Object_creation_ctx implementation.
41
**************************************************************************/
42
43
Object_creation_ctx *Object_creation_ctx::set_n_backup(THD *thd)
44
{
45
  Object_creation_ctx *backup_ctx;
46
47
  backup_ctx= create_backup_ctx(thd);
48
  change_env(thd);
49
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
50
  return(backup_ctx);
1 by brian
clean slate
51
}
52
53
void Object_creation_ctx::restore_env(THD *thd, Object_creation_ctx *backup_ctx)
54
{
55
  if (!backup_ctx)
56
    return;
57
58
  backup_ctx->change_env(thd);
59
60
  delete backup_ctx;
61
}
62
63
/**************************************************************************
64
  Default_object_creation_ctx implementation.
65
**************************************************************************/
66
67
Default_object_creation_ctx::Default_object_creation_ctx(THD *thd)
68
  : m_client_cs(thd->variables.character_set_client),
69
    m_connection_cl(thd->variables.collation_connection)
70
{ }
71
72
Default_object_creation_ctx::Default_object_creation_ctx(
73
  CHARSET_INFO *client_cs, CHARSET_INFO *connection_cl)
74
  : m_client_cs(client_cs),
75
    m_connection_cl(connection_cl)
76
{ }
77
78
Object_creation_ctx *
79
Default_object_creation_ctx::create_backup_ctx(THD *thd) const
80
{
81
  return new Default_object_creation_ctx(thd);
82
}
83
84
void Default_object_creation_ctx::change_env(THD *thd) const
85
{
86
  thd->variables.character_set_client= m_client_cs;
87
  thd->variables.collation_connection= m_connection_cl;
88
89
  thd->update_charset();
90
}
91
92
/*************************************************************************/
93
94
/* Get column name from column hash */
95
96
static uchar *get_field_name(Field **buff, size_t *length,
97
                             my_bool not_used __attribute__((unused)))
98
{
99
  *length= (uint) strlen((*buff)->field_name);
100
  return (uchar*) (*buff)->field_name;
101
}
102
103
104
/*
105
  Returns pointer to '.frm' extension of the file name.
106
107
  SYNOPSIS
108
    fn_rext()
109
    name       file name
110
111
  DESCRIPTION
112
    Checks file name part starting with the rightmost '.' character,
113
    and returns it if it is equal to '.frm'. 
114
115
  TODO
116
    It is a good idea to get rid of this function modifying the code
117
    to garantee that the functions presently calling fn_rext() always
118
    get arguments in the same format: either with '.frm' or without '.frm'.
119
120
  RETURN VALUES
121
    Pointer to the '.frm' extension. If there is no extension,
122
    or extension is not '.frm', pointer at the end of file name.
123
*/
124
125
char *fn_rext(char *name)
126
{
127
  char *res= strrchr(name, '.');
128
  if (res && !strcmp(res, reg_ext))
129
    return res;
130
  return name + strlen(name);
131
}
132
133
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
134
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
135
  assert(db != NULL);
136
  assert(name != NULL);
1 by brian
clean slate
137
138
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
139
      (my_strcasecmp(system_charset_info,
140
                    INFORMATION_SCHEMA_NAME.str,
141
                    db->str) == 0))
142
  {
143
    return TABLE_CATEGORY_INFORMATION;
144
  }
145
146
  return TABLE_CATEGORY_USER;
147
}
148
149
150
/*
151
  Allocate a setup TABLE_SHARE structure
152
153
  SYNOPSIS
154
    alloc_table_share()
155
    TABLE_LIST		Take database and table name from there
156
    key			Table cache key (db \0 table_name \0...)
157
    key_length		Length of key
158
159
  RETURN
160
    0  Error (out of memory)
161
    #  Share
162
*/
163
164
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
165
                               uint key_length)
166
{
167
  MEM_ROOT mem_root;
168
  TABLE_SHARE *share;
169
  char *key_buff, *path_buff;
170
  char path[FN_REFLEN];
171
  uint path_length;
172
173
  path_length= build_table_filename(path, sizeof(path) - 1,
174
                                    table_list->db,
175
                                    table_list->table_name, "", 0);
176
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
177
  if (multi_alloc_root(&mem_root,
178
                       &share, sizeof(*share),
179
                       &key_buff, key_length,
180
                       &path_buff, path_length + 1,
181
                       NULL))
182
  {
183
    bzero((char*) share, sizeof(*share));
184
185
    share->set_table_cache_key(key_buff, key, key_length);
186
187
    share->path.str= path_buff;
188
    share->path.length= path_length;
189
    strmov(share->path.str, path);
190
    share->normalized_path.str=    share->path.str;
191
    share->normalized_path.length= path_length;
192
193
    share->version=       refresh_version;
194
195
    share->tablespace=    NULL;
196
197
    /*
198
      This constant is used to mark that no table map version has been
199
      assigned.  No arithmetic is done on the value: it will be
200
      overwritten with a value taken from MYSQL_BIN_LOG.
201
    */
202
    share->table_map_version= ~(uint64_t)0;
203
204
    /*
205
      Since alloc_table_share() can be called without any locking (for
206
      example, ha_create_table... functions), we do not assign a table
207
      map id here.  Instead we assign a value that is not used
208
      elsewhere, and then assign a table map id inside open_table()
209
      under the protection of the LOCK_open mutex.
210
    */
211
    share->table_map_id= ~0UL;
212
    share->cached_row_logging_check= -1;
213
214
    memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
215
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
216
    pthread_cond_init(&share->cond, NULL);
217
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
218
  return(share);
1 by brian
clean slate
219
}
220
221
222
/*
223
  Initialize share for temporary tables
224
225
  SYNOPSIS
226
    init_tmp_table_share()
227
    thd         thread handle
228
    share	Share to fill
229
    key		Table_cache_key, as generated from create_table_def_key.
230
		must start with db name.    
231
    key_length	Length of key
232
    table_name	Table name
233
    path	Path to file (possible in lower case) without .frm
234
235
  NOTES
236
    This is different from alloc_table_share() because temporary tables
237
    don't have to be shared between threads or put into the table def
238
    cache, so we can do some things notable simpler and faster
239
240
    If table is not put in thd->temporary_tables (happens only when
241
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
242
    use key_length= 0 as neither table_cache_key or key_length will be used).
243
*/
244
245
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
246
                          uint key_length, const char *table_name,
247
                          const char *path)
248
{
249
250
  bzero((char*) share, sizeof(*share));
251
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
252
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
253
  share->tmp_table=              INTERNAL_TMP_TABLE;
254
  share->db.str=                 (char*) key;
255
  share->db.length=		 strlen(key);
256
  share->table_cache_key.str=    (char*) key;
257
  share->table_cache_key.length= key_length;
258
  share->table_name.str=         (char*) table_name;
259
  share->table_name.length=      strlen(table_name);
260
  share->path.str=               (char*) path;
261
  share->normalized_path.str=    (char*) path;
262
  share->path.length= share->normalized_path.length= strlen(path);
263
  share->frm_version= 		 FRM_VER_TRUE_VARCHAR;
264
  share->tablespace=             NULL;
265
  /*
266
    Temporary tables are not replicated, but we set up these fields
267
    anyway to be able to catch errors.
268
   */
269
  share->table_map_version= ~(uint64_t)0;
270
  share->cached_row_logging_check= -1;
271
272
  /*
273
    table_map_id is also used for MERGE tables to suppress repeated
274
    compatibility checks.
275
  */
276
  share->table_map_id= (ulong) thd->query_id;
277
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
278
  return;
1 by brian
clean slate
279
}
280
281
282
/*
283
  Free table share and memory used by it
284
285
  SYNOPSIS
286
    free_table_share()
287
    share		Table share
288
289
  NOTES
290
    share->mutex must be locked when we come here if it's not a temp table
291
*/
292
293
void free_table_share(TABLE_SHARE *share)
294
{
295
  MEM_ROOT mem_root;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
296
  assert(share->ref_count == 0);
1 by brian
clean slate
297
298
  /*
299
    If someone is waiting for this to be deleted, inform it about this.
300
    Don't do a delete until we know that no one is refering to this anymore.
301
  */
302
  if (share->tmp_table == NO_TMP_TABLE)
303
  {
304
    /* share->mutex is locked in release_table_share() */
305
    while (share->waiting_on_cond)
306
    {
307
      pthread_cond_broadcast(&share->cond);
308
      pthread_cond_wait(&share->cond, &share->mutex);
309
    }
310
    /* No thread refers to this anymore */
311
    pthread_mutex_unlock(&share->mutex);
312
    pthread_mutex_destroy(&share->mutex);
313
    pthread_cond_destroy(&share->cond);
314
  }
315
  hash_free(&share->name_hash);
316
  
317
  plugin_unlock(NULL, share->db_plugin);
318
  share->db_plugin= NULL;
319
320
  /* We must copy mem_root from share because share is allocated through it */
321
  memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root));
322
  free_root(&mem_root, MYF(0));                 // Free's share
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
323
  return;
1 by brian
clean slate
324
}
325
326
/*
327
  Read table definition from a binary / text based .frm file
328
  
329
  SYNOPSIS
330
  open_table_def()
331
  thd		Thread handler
332
  share		Fill this with table definition
333
  db_flags	Bit mask of the following flags: OPEN_VIEW
334
335
  NOTES
336
    This function is called when the table definition is not cached in
337
    table_def_cache
338
    The data is returned in 'share', which is alloced by
339
    alloc_table_share().. The code assumes that share is initialized.
340
341
  RETURN VALUES
342
   0	ok
343
   1	Error (see open_table_error)
344
   2    Error (see open_table_error)
345
   3    Wrong data in .frm file
346
   4    Error (see open_table_error)
347
   5    Error (see open_table_error: charset unavailable)
348
   6    Unknown .frm version
349
*/
350
351
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
352
{
353
  int error, table_type;
354
  bool error_given;
355
  File file;
356
  uchar head[64], *disk_buff;
357
  char	path[FN_REFLEN];
358
  MEM_ROOT **root_ptr, *old_root;
359
360
  error= 1;
361
  error_given= 0;
362
  disk_buff= NULL;
363
364
  strxmov(path, share->normalized_path.str, reg_ext, NullS);
365
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
366
  {
367
    /*
368
      We don't try to open 5.0 unencoded name, if
369
      - non-encoded name contains '@' signs, 
370
        because '@' can be misinterpreted.
371
        It is not clear if '@' is escape character in 5.1,
372
        or a normal character in 5.0.
373
        
374
      - non-encoded db or table name contain "#mysql50#" prefix.
375
        This kind of tables must have been opened only by the
376
        my_open() above.
377
    */
378
    if (strchr(share->table_name.str, '@') ||
379
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
380
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
381
        !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
382
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
383
      goto err_not_open;
384
385
    /* Try unencoded 5.0 name */
386
    uint length;
387
    strxnmov(path, sizeof(path)-1,
388
             mysql_data_home, "/", share->db.str, "/",
389
             share->table_name.str, reg_ext, NullS);
390
    length= unpack_filename(path, path) - reg_ext_length;
391
    /*
392
      The following is a safety test and should never fail
393
      as the old file name should never be longer than the new one.
394
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
395
    assert(length <= share->normalized_path.length);
1 by brian
clean slate
396
    /*
397
      If the old and the new names have the same length,
398
      then table name does not have tricky characters,
399
      so no need to check the old file name.
400
    */
401
    if (length == share->normalized_path.length ||
402
        ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
403
      goto err_not_open;
404
405
    /* Unencoded 5.0 table name found */
406
    path[length]= '\0'; // Remove .frm extension
407
    strmov(share->normalized_path.str, path);
408
    share->normalized_path.length= length;
409
  }
410
411
  error= 4;
412
  if (my_read(file, head, 64, MYF(MY_NABP)))
413
    goto err;
414
415
  if (head[0] == (uchar) 254 && head[1] == 1)
416
  {
417
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
418
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
419
    {
420
      /* Open view only */
421
      if (db_flags & OPEN_VIEW_ONLY)
422
      {
423
        error_given= 1;
424
        goto err;
425
      }
426
      table_type= 1;
427
    }
428
    else
429
    {
430
      error= 6;                                 // Unkown .frm version
431
      goto err;
432
    }
433
  }
434
  else
435
    goto err;
436
437
  /* No handling of text based files yet */
438
  if (table_type == 1)
439
  {
4 by Brian Aker
Remove my_pthread_getspecific_ptr()
440
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
1 by brian
clean slate
441
    old_root= *root_ptr;
442
    *root_ptr= &share->mem_root;
443
    error= open_binary_frm(thd, share, head, file);
444
    *root_ptr= old_root;
445
    error_given= 1;
446
  }
81 by Brian Aker
Small cleanups
447
  else
448
    assert(1);
1 by brian
clean slate
449
450
  share->table_category= get_table_category(& share->db, & share->table_name);
451
452
  if (!error)
453
    thd->status_var.opened_shares++;
454
455
err:
456
  my_close(file, MYF(MY_WME));
457
458
err_not_open:
459
  if (error && !error_given)
460
  {
461
    share->error= error;
462
    open_table_error(share, error, (share->open_errno= my_errno), 0);
463
  }
464
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
465
  return(error);
1 by brian
clean slate
466
}
467
468
469
/*
470
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
471
*/
472
473
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
474
                           File file)
475
{
476
  int error, errarg= 0;
477
  uint new_frm_ver, field_pack_length, new_field_pack_flag;
478
  uint interval_count, interval_parts, read_length, int_length;
479
  uint db_create_options, keys, key_parts, n_length;
480
  uint key_info_length, com_length, null_bit_pos;
481
  uint extra_rec_buf_length;
482
  uint i,j;
483
  bool use_hash;
484
  uchar forminfo[288];
485
  char *keynames, *names, *comment_pos;
486
  uchar *record;
487
  uchar *disk_buff, *strpos, *null_flags, *null_pos;
488
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
489
  handler *handler_file= 0;
490
  KEY	*keyinfo;
491
  KEY_PART_INFO *key_part;
492
  SQL_CRYPT *crypted=0;
493
  Field  **field_ptr, *reg_field;
494
  const char **interval_array;
495
  enum legacy_db_type legacy_db_type;
496
  my_bitmap_map *bitmaps;
497
  uchar *buff= 0;
498
  uchar *field_extra_info= 0;
499
500
  new_field_pack_flag= head[27];
501
  new_frm_ver= (head[2] - FRM_VER);
502
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
503
  disk_buff= 0;
504
505
  error= 3;
506
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
507
    goto err;                                   /* purecov: inspected */
508
  VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
509
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
510
    goto err;
511
512
  share->frm_version= head[2];
513
  /*
514
    Check if .frm file created by MySQL 5.0. In this case we want to
515
    display CHAR fields as CHAR and not as VARCHAR.
516
    We do it this way as we want to keep the old frm version to enable
517
    MySQL 4.1 to read these files.
518
  */
519
  if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
520
    share->frm_version= FRM_VER_TRUE_VARCHAR;
521
81 by Brian Aker
Small cleanups
522
  legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
523
  assert(share->db_plugin == NULL);
1 by brian
clean slate
524
  /*
525
    if the storage engine is dynamic, no point in resolving it by its
526
    dynamically allocated legacy_db_type. We will resolve it later by name.
527
  */
528
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
529
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
530
    share->db_plugin= ha_lock_engine(NULL, 
531
                                     ha_checktype(thd, legacy_db_type, 0, 0));
532
  share->db_create_options= db_create_options= uint2korr(head+30);
533
  share->db_options_in_use= share->db_create_options;
534
  share->mysql_version= uint4korr(head+51);
535
  share->null_field_first= 0;
536
  if (!head[32])				// New frm file in 3.23
537
  {
538
    share->avg_row_length= uint4korr(head+34);
539
    share->transactional= (ha_choice) (head[39] & 3);
540
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
541
    share->row_type= (row_type) head[40];
542
    share->table_charset= get_charset((uint) head[38],MYF(0));
543
    share->null_field_first= 1;
544
  }
545
  if (!share->table_charset)
546
  {
547
    /* unknown charset in head[38] or pre-3.23 frm */
548
    if (use_mb(default_charset_info))
549
    {
550
      /* Warn that we may be changing the size of character columns */
551
      sql_print_warning("'%s' had no or invalid character set, "
552
                        "and default character set is multi-byte, "
553
                        "so character column sizes may have changed",
554
                        share->path.str);
555
    }
556
    share->table_charset= default_charset_info;
557
  }
558
  share->db_record_offset= 1;
559
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
560
    share->blob_ptr_size= portable_sizeof_char_ptr;
561
  /* Set temporarily a good value for db_low_byte_first */
562
  share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM);
563
  error=4;
564
  share->max_rows= uint4korr(head+18);
565
  share->min_rows= uint4korr(head+22);
566
567
  /* Read keyinformation */
568
  key_info_length= (uint) uint2korr(head+28);
569
  VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
570
  if (read_string(file,(uchar**) &disk_buff,key_info_length))
571
    goto err;                                   /* purecov: inspected */
572
  if (disk_buff[0] & 0x80)
573
  {
574
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
575
    share->key_parts= key_parts= uint2korr(disk_buff+2);
576
  }
577
  else
578
  {
579
    share->keys=      keys=      disk_buff[0];
580
    share->key_parts= key_parts= disk_buff[1];
581
  }
582
  share->keys_for_keyread.init(0);
583
  share->keys_in_use.init(keys);
584
585
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
586
  if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
587
				    n_length + uint2korr(disk_buff+4))))
588
    goto err;                                   /* purecov: inspected */
589
  bzero((char*) keyinfo,n_length);
590
  share->key_info= keyinfo;
591
  key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
592
  strpos=disk_buff+6;
593
594
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
595
					 sizeof(ulong*)*key_parts)))
596
    goto err;
597
598
  for (i=0 ; i < keys ; i++, keyinfo++)
599
  {
600
    keyinfo->table= 0;                           // Updated in open_frm
601
    if (new_frm_ver >= 3)
602
    {
603
      keyinfo->flags=	   (uint) uint2korr(strpos) ^ HA_NOSAME;
604
      keyinfo->key_length= (uint) uint2korr(strpos+2);
605
      keyinfo->key_parts=  (uint) strpos[4];
606
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
607
      keyinfo->block_size= uint2korr(strpos+6);
608
      strpos+=8;
609
    }
610
611
    keyinfo->key_part=	 key_part;
612
    keyinfo->rec_per_key= rec_per_key;
613
    for (j=keyinfo->key_parts ; j-- ; key_part++)
614
    {
615
      *rec_per_key++=0;
616
      key_part->fieldnr=	(uint16) (uint2korr(strpos) & FIELD_NR_MASK);
617
      key_part->offset= (uint) uint2korr(strpos+2)-1;
618
      key_part->key_type=	(uint) uint2korr(strpos+5);
619
      // key_part->field=	(Field*) 0;	// Will be fixed later
620
      if (new_frm_ver >= 1)
621
      {
622
	key_part->key_part_flag= *(strpos+4);
623
	key_part->length=	(uint) uint2korr(strpos+7);
624
	strpos+=9;
625
      }
626
      else
627
      {
628
	key_part->length=	*(strpos+4);
629
	key_part->key_part_flag=0;
630
	if (key_part->length > 128)
631
	{
632
	  key_part->length&=127;		/* purecov: inspected */
633
	  key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
634
	}
635
	strpos+=7;
636
      }
637
      key_part->store_length=key_part->length;
638
    }
639
  }
640
  keynames=(char*) key_part;
641
  strpos+= (strmov(keynames, (char *) strpos) - keynames)+1;
642
643
  //reading index comments
644
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
645
  {
646
    if (keyinfo->flags & HA_USES_COMMENT)
647
    {
648
      keyinfo->comment.length= uint2korr(strpos);
649
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
650
                                         keyinfo->comment.length);
651
      strpos+= 2 + keyinfo->comment.length;
652
    } 
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
653
    assert(test(keyinfo->flags & HA_USES_COMMENT) == 
1 by brian
clean slate
654
               (keyinfo->comment.length > 0));
655
  }
656
657
  share->reclength = uint2korr((head+16));
658
  if (*(head+26) == 1)
659
    share->system= 1;				/* one-record-database */
660
661
  record_offset= (ulong) (uint2korr(head+6)+
662
                          ((uint2korr(head+14) == 0xffff ?
663
                            uint4korr(head+47) : uint2korr(head+14))));
664
 
665
  if ((n_length= uint4korr(head+55)))
666
  {
667
    /* Read extra data segment */
668
    uchar *next_chunk, *buff_end;
669
    if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
670
      goto err;
31 by Brian Aker
Removed my versions of pread/pwrite from the Kernel
671
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
1 by brian
clean slate
672
    {
673
      goto err;
674
    }
675
    share->connect_string.length= uint2korr(buff);
676
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
677
                                                  (char*) next_chunk + 2,
678
                                                  share->connect_string.
679
                                                  length)))
680
    {
681
      goto err;
682
    }
683
    next_chunk+= share->connect_string.length + 2;
684
    buff_end= buff + n_length;
685
    if (next_chunk + 2 < buff_end)
686
    {
687
      uint str_db_type_length= uint2korr(next_chunk);
688
      LEX_STRING name;
689
      name.str= (char*) next_chunk + 2;
690
      name.length= str_db_type_length;
691
692
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
693
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
694
      {
695
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
696
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
697
            legacy_db_type != ha_legacy_type(
698
                plugin_data(tmp_plugin, handlerton *)))
699
        {
700
          /* bad file, legacy_db_type did not match the name */
701
          my_free(buff, MYF(0));
702
          goto err;
703
        }
704
        /*
705
          tmp_plugin is locked with a local lock.
706
          we unlock the old value of share->db_plugin before
707
          replacing it with a globally locked version of tmp_plugin
708
        */
709
        plugin_unlock(NULL, share->db_plugin);
710
        share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
711
      }
712
      else if (!tmp_plugin)
713
      {
714
        /* purecov: begin inspected */
715
        error= 8;
716
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
717
        my_free(buff, MYF(0));
718
        goto err;
719
        /* purecov: end */
720
      }
721
      next_chunk+= str_db_type_length + 2;
722
    }
723
    if (share->mysql_version >= 50110)
724
    {
725
      /* New auto_partitioned indicator introduced in 5.1.11 */
726
      next_chunk++;
727
    }
728
    if (forminfo[46] == (uchar)255)
729
    {
730
      //reading long table comment
731
      if (next_chunk + 2 > buff_end)
732
      {
733
          my_free(buff, MYF(0));
734
          goto err;
735
      }
736
      share->comment.length = uint2korr(next_chunk);
737
      if (! (share->comment.str= strmake_root(&share->mem_root,
738
                               (char*)next_chunk + 2, share->comment.length)))
739
      {
740
          my_free(buff, MYF(0));
741
          goto err;
742
      }
743
      next_chunk+= 2 + share->comment.length;
744
    }
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
745
    assert(next_chunk <= buff_end);
1 by brian
clean slate
746
    if (share->mysql_version >= MYSQL_VERSION_TABLESPACE_IN_FRM_CGE)
747
    {
748
      /*
749
       New frm format in mysql_version 5.2.5 (originally in
750
       mysql-5.1.22-ndb-6.2.5)
751
       New column properties added:
752
       COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
753
       TABLESPACE name is now stored in frm
754
      */
755
      if (next_chunk >= buff_end)
756
      {
757
        if (share->mysql_version >= MYSQL_VERSION_TABLESPACE_IN_FRM)
758
        {
759
          goto err;
760
        }
761
      }
762
      else
763
      {
764
        const uint format_section_header_size= 8;
765
        uint format_section_len= uint2korr(next_chunk+0);
766
        uint flags=              uint4korr(next_chunk+2);
767
768
        share->default_storage_media= (enum ha_storage_media) (flags & 0x7);
769
770
        const char *tablespace= (const char*)next_chunk + format_section_header_size;
771
        uint tablespace_len= strlen(tablespace);
772
        if (tablespace_len != 0) 
773
        {
774
          share->tablespace= (char *) alloc_root(&share->mem_root,
775
                                                 tablespace_len+1);
776
          strxmov(share->tablespace, tablespace, NullS);
777
        }
778
        else
779
          share->tablespace= NULL;
780
781
        field_extra_info= next_chunk + format_section_header_size + tablespace_len + 1;
782
        next_chunk+= format_section_len;
783
      }
784
    }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
785
    assert (next_chunk <= buff_end);
1 by brian
clean slate
786
    if (next_chunk > buff_end)
787
    {
788
      goto err;
789
    }
790
  }
791
  share->key_block_size= uint2korr(head+62);
792
793
  error=4;
794
  extra_rec_buf_length= uint2korr(head+59);
795
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
796
  share->rec_buff_length= rec_buff_length;
797
  if (!(record= (uchar *) alloc_root(&share->mem_root,
798
                                     rec_buff_length)))
799
    goto err;                                   /* purecov: inspected */
800
  share->default_values= record;
31 by Brian Aker
Removed my versions of pread/pwrite from the Kernel
801
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
1 by brian
clean slate
802
    goto err;                                   /* purecov: inspected */
803
804
  VOID(my_seek(file,pos+288,MY_SEEK_SET,MYF(0)));
805
806
  share->fields= uint2korr(forminfo+258);
807
  pos= uint2korr(forminfo+260);			/* Length of all screens */
808
  n_length= uint2korr(forminfo+268);
809
  interval_count= uint2korr(forminfo+270);
810
  interval_parts= uint2korr(forminfo+272);
811
  int_length= uint2korr(forminfo+274);
812
  share->null_fields= uint2korr(forminfo+282);
813
  com_length= uint2korr(forminfo+284);
814
  if (forminfo[46] != (uchar)255)
815
  {
816
    share->comment.length=  (int) (forminfo[46]);
817
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
818
                                     share->comment.length);
819
  }
820
821
822
  if (!(field_ptr = (Field **)
823
	alloc_root(&share->mem_root,
824
		   (uint) ((share->fields+1)*sizeof(Field*)+
825
			   interval_count*sizeof(TYPELIB)+
826
			   (share->fields+interval_parts+
827
			    keys+3)*sizeof(char *)+
828
			   (n_length+int_length+com_length)))))
829
    goto err;                                   /* purecov: inspected */
830
831
  share->field= field_ptr;
832
  read_length=(uint) (share->fields * field_pack_length +
833
		      pos+ (uint) (n_length+int_length+com_length));
834
  if (read_string(file,(uchar**) &disk_buff,read_length))
835
    goto err;                                   /* purecov: inspected */
836
  strpos= disk_buff+pos;
837
838
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
839
  interval_array= (const char **) (share->intervals+interval_count);
840
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
841
  if (!interval_count)
842
    share->intervals= 0;			// For better debugging
843
  memcpy((char*) names, strpos+(share->fields*field_pack_length),
844
	 (uint) (n_length+int_length));
845
  comment_pos= names+(n_length+int_length);
846
  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
847
848
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
849
  if (share->fieldnames.count != share->fields)
850
    goto err;
851
  fix_type_pointers(&interval_array, share->intervals, interval_count,
852
		    &names);
853
854
  {
855
    /* Set ENUM and SET lengths */
856
    TYPELIB *interval;
857
    for (interval= share->intervals;
858
         interval < share->intervals + interval_count;
859
         interval++)
860
    {
861
      uint count= (uint) (interval->count + 1) * sizeof(uint);
862
      if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
863
                                                        count)))
864
        goto err;
865
      for (count= 0; count < interval->count; count++)
866
      {
867
        char *val= (char*) interval->type_names[count];
868
        interval->type_lengths[count]= strlen(val);
869
      }
870
      interval->type_lengths[count]= 0;
871
    }
872
  }
873
874
  if (keynames)
875
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
876
877
 /* Allocate handler */
878
  if (!(handler_file= get_new_handler(share, thd->mem_root,
879
                                      share->db_type())))
880
    goto err;
881
882
  record= share->default_values-1;              /* Fieldstart = 1 */
883
  if (share->null_field_first)
884
  {
885
    null_flags= null_pos= (uchar*) record+1;
886
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
887
    /*
888
      null_bytes below is only correct under the condition that
889
      there are no bit fields.  Correct values is set below after the
890
      table struct is initialized
891
    */
892
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
893
  }
894
#ifndef WE_WANT_TO_SUPPORT_VERY_OLD_FRM_FILES
895
  else
896
  {
897
    share->null_bytes= (share->null_fields+7)/8;
898
    null_flags= null_pos= (uchar*) (record + 1 +share->reclength -
899
                                    share->null_bytes);
900
    null_bit_pos= 0;
901
  }
902
#endif
903
904
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
905
  if (use_hash)
906
    use_hash= !hash_init(&share->name_hash,
907
			 system_charset_info,
908
			 share->fields,0,0,
909
			 (hash_get_key) get_field_name,0,0);
910
911
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
912
  {
913
    uint pack_flag, interval_nr, unireg_type, recpos, field_length;
914
    enum_field_types field_type;
915
    enum ha_storage_media storage_type= HA_SM_DEFAULT;
916
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
917
    CHARSET_INFO *charset=NULL;
918
    LEX_STRING comment;
919
920
    if (field_extra_info)
921
    {
922
      char tmp= field_extra_info[i];
923
      storage_type= (enum ha_storage_media)(tmp & STORAGE_TYPE_MASK);
924
      column_format= (enum column_format_type)
925
                    ((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
926
    }
927
    if (new_frm_ver >= 3)
928
    {
929
      /* new frm file in 4.1 */
930
      field_length= uint2korr(strpos+3);
931
      recpos=	    uint3korr(strpos+5);
932
      pack_flag=    uint2korr(strpos+8);
933
      unireg_type=  (uint) strpos[10];
934
      interval_nr=  (uint) strpos[12];
935
      uint comment_length=uint2korr(strpos+15);
936
      field_type=(enum_field_types) (uint) strpos[13];
937
938
      {
939
        if (!strpos[14])
940
          charset= &my_charset_bin;
941
        else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
942
        {
943
          error= 5; // Unknown or unavailable charset
944
          errarg= (int) strpos[14];
945
          goto err;
946
        }
947
      }
948
      if (!comment_length)
949
      {
950
	comment.str= (char*) "";
951
	comment.length=0;
952
      }
953
      else
954
      {
955
	comment.str=    (char*) comment_pos;
956
	comment.length= comment_length;
957
	comment_pos+=   comment_length;
958
      }
959
    }
960
    else
961
    {
962
      field_length= (uint) strpos[3];
963
      recpos=	    uint2korr(strpos+4),
964
      pack_flag=    uint2korr(strpos+6);
965
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
966
      unireg_type=  (uint) strpos[8];
967
      interval_nr=  (uint) strpos[10];
968
969
      /* old frm file */
970
      field_type= (enum_field_types) f_packtype(pack_flag);
971
      if (f_is_binary(pack_flag))
972
      {
973
        /*
974
          Try to choose the best 4.1 type:
975
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
976
            try to find a binary collation for character set.
977
          - for other types (e.g. BLOB) just use my_charset_bin. 
978
        */
979
        if (!f_is_blob(pack_flag))
980
        {
981
          // 3.23 or 4.0 string
982
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
983
                                               MY_CS_BINSORT, MYF(0))))
984
            charset= &my_charset_bin;
985
        }
986
        else
987
          charset= &my_charset_bin;
988
      }
989
      else
990
        charset= share->table_charset;
991
      bzero((char*) &comment, sizeof(comment));
992
    }
993
994
    if (interval_nr && charset->mbminlen > 1)
995
    {
996
      /* Unescape UCS2 intervals from HEX notation */
997
      TYPELIB *interval= share->intervals + interval_nr - 1;
998
      unhex_type2(interval);
999
    }
1000
    
1001
#ifndef TO_BE_DELETED_ON_PRODUCTION
1002
    if (field_type == MYSQL_TYPE_NEWDECIMAL && !share->mysql_version)
1003
    {
1004
      /*
1005
        Fix pack length of old decimal values from 5.0.3 -> 5.0.4
1006
        The difference is that in the old version we stored precision
1007
        in the .frm table while we now store the display_length
1008
      */
1009
      uint decimals= f_decimals(pack_flag);
1010
      field_length= my_decimal_precision_to_length(field_length,
1011
                                                   decimals,
1012
                                                   f_is_dec(pack_flag) == 0);
1013
      sql_print_error("Found incompatible DECIMAL field '%s' in %s; "
1014
                      "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
1015
                      share->fieldnames.type_names[i], share->table_name.str,
1016
                      share->table_name.str);
1017
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1018
                          ER_CRASHED_ON_USAGE,
1019
                          "Found incompatible DECIMAL field '%s' in %s; "
1020
                          "Please do \"ALTER TABLE '%s' FORCE\" to fix it!",
1021
                          share->fieldnames.type_names[i],
1022
                          share->table_name.str,
1023
                          share->table_name.str);
1024
      share->crashed= 1;                        // Marker for CHECK TABLE
1025
    }
1026
#endif
1027
1028
    *field_ptr= reg_field=
1029
      make_field(share, record+recpos,
1030
		 (uint32) field_length,
1031
		 null_pos, null_bit_pos,
1032
		 pack_flag,
1033
		 field_type,
1034
		 charset,
1035
		 (Field::utype) MTYP_TYPENR(unireg_type),
1036
		 (interval_nr ?
1037
		  share->intervals+interval_nr-1 :
1038
		  (TYPELIB*) 0),
1039
		 share->fieldnames.type_names[i]);
1040
    if (!reg_field)				// Not supported field type
1041
    {
1042
      error= 4;
1043
      goto err;			/* purecov: inspected */
1044
    }
1045
1046
    reg_field->flags|= ((uint)storage_type << FIELD_STORAGE_FLAGS);
1047
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
1048
    reg_field->field_index= i;
1049
    reg_field->comment=comment;
1050
    if (!(reg_field->flags & NOT_NULL_FLAG))
1051
    {
1052
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
1053
        null_pos++;
1054
    }
1055
    if (f_no_default(pack_flag))
1056
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
1057
1058
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
1059
      share->found_next_number_field= field_ptr;
1060
    if (share->timestamp_field == reg_field)
1061
      share->timestamp_field_offset= i;
1062
1063
    if (use_hash)
1064
      (void) my_hash_insert(&share->name_hash,
1065
                            (uchar*) field_ptr); // never fail
1066
  }
1067
  *field_ptr=0;					// End marker
1068
1069
  /* Fix key->name and key_part->field */
1070
  if (key_parts)
1071
  {
1072
    uint primary_key=(uint) (find_type((char*) primary_key_name,
1073
				       &share->keynames, 3) - 1);
1074
    longlong ha_option= handler_file->ha_table_flags();
1075
    keyinfo= share->key_info;
1076
    key_part= keyinfo->key_part;
1077
1078
    for (uint key=0 ; key < share->keys ; key++,keyinfo++)
1079
    {
1080
      uint usable_parts= 0;
1081
      keyinfo->name=(char*) share->keynames.type_names[key];
1082
1083
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1084
      {
1085
	/*
1086
	  If the UNIQUE key doesn't have NULL columns and is not a part key
1087
	  declare this as a primary key.
1088
	*/
1089
	primary_key=key;
1090
	for (i=0 ; i < keyinfo->key_parts ;i++)
1091
	{
1092
	  uint fieldnr= key_part[i].fieldnr;
1093
	  if (!fieldnr ||
1094
	      share->field[fieldnr-1]->null_ptr ||
1095
	      share->field[fieldnr-1]->key_length() !=
1096
	      key_part[i].length)
1097
	  {
1098
	    primary_key=MAX_KEY;		// Can't be used
1099
	    break;
1100
	  }
1101
	}
1102
      }
1103
1104
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1105
      {
1106
        Field *field;
1107
	if (new_field_pack_flag <= 1)
1108
	  key_part->fieldnr= (uint16) find_field(share->field,
1109
                                                 share->default_values,
1110
                                                 (uint) key_part->offset,
1111
                                                 (uint) key_part->length);
1112
	if (!key_part->fieldnr)
1113
        {
1114
          error= 4;                             // Wrong file
1115
          goto err;
1116
        }
1117
        field= key_part->field= share->field[key_part->fieldnr-1];
1118
        key_part->type= field->key_type();
1119
        if (field->null_ptr)
1120
        {
1121
          key_part->null_offset=(uint) ((uchar*) field->null_ptr -
1122
                                        share->default_values);
1123
          key_part->null_bit= field->null_bit;
1124
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1125
          keyinfo->flags|=HA_NULL_PART_KEY;
1126
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1127
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1128
        }
1129
        if (field->type() == MYSQL_TYPE_BLOB ||
1130
            field->real_type() == MYSQL_TYPE_VARCHAR)
1131
        {
1132
          if (field->type() == MYSQL_TYPE_BLOB)
1133
            key_part->key_part_flag|= HA_BLOB_PART;
1134
          else
1135
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1136
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1137
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1138
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1139
        }
1140
        if (i == 0 && key != primary_key)
1141
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1142
                           (keyinfo->key_parts == 1)) ?
1143
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1144
        if (i == 0)
1145
          field->key_start.set_bit(key);
1146
        if (field->key_length() == key_part->length &&
1147
            !(field->flags & BLOB_FLAG))
1148
        {
1149
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1150
          {
1151
            share->keys_for_keyread.set_bit(key);
1152
            field->part_of_key.set_bit(key);
1153
            field->part_of_key_not_clustered.set_bit(key);
1154
          }
1155
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1156
            field->part_of_sortkey.set_bit(key);
1157
        }
1158
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1159
            usable_parts == i)
1160
          usable_parts++;			// For FILESORT
1161
        field->flags|= PART_KEY_FLAG;
1162
        if (key == primary_key)
1163
        {
1164
          field->flags|= PRI_KEY_FLAG;
1165
          /*
1166
            If this field is part of the primary key and all keys contains
1167
            the primary key, then we can use any key to find this column
1168
          */
1169
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1170
          {
1171
            field->part_of_key= share->keys_in_use;
1172
            if (field->part_of_sortkey.is_set(key))
1173
              field->part_of_sortkey= share->keys_in_use;
1174
          }
1175
        }
1176
        if (field->key_length() != key_part->length)
1177
        {
1178
#ifndef TO_BE_DELETED_ON_PRODUCTION
1179
          if (field->type() == MYSQL_TYPE_NEWDECIMAL)
1180
          {
1181
            /*
1182
              Fix a fatal error in decimal key handling that causes crashes
1183
              on Innodb. We fix it by reducing the key length so that
1184
              InnoDB never gets a too big key when searching.
1185
              This allows the end user to do an ALTER TABLE to fix the
1186
              error.
1187
            */
1188
            keyinfo->key_length-= (key_part->length - field->key_length());
1189
            key_part->store_length-= (uint16)(key_part->length -
1190
                                              field->key_length());
1191
            key_part->length= (uint16)field->key_length();
1192
            sql_print_error("Found wrong key definition in %s; "
1193
                            "Please do \"ALTER TABLE '%s' FORCE \" to fix it!",
1194
                            share->table_name.str,
1195
                            share->table_name.str);
1196
            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1197
                                ER_CRASHED_ON_USAGE,
1198
                                "Found wrong key definition in %s; "
1199
                                "Please do \"ALTER TABLE '%s' FORCE\" to fix "
1200
                                "it!",
1201
                                share->table_name.str,
1202
                                share->table_name.str);
1203
            share->crashed= 1;                // Marker for CHECK TABLE
1204
            continue;
1205
          }
1206
#endif
1207
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1208
        }
1209
      }
1210
      keyinfo->usable_key_parts= usable_parts; // Filesort
1211
1212
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1213
                    keyinfo->key_parts);
1214
      share->total_key_length+= keyinfo->key_length;
1215
      /*
1216
        MERGE tables do not have unique indexes. But every key could be
1217
        an unique index on the underlying MyISAM table. (Bug #10400)
1218
      */
1219
      if ((keyinfo->flags & HA_NOSAME) ||
1220
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1221
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1222
    }
1223
    if (primary_key < MAX_KEY &&
1224
	(share->keys_in_use.is_set(primary_key)))
1225
    {
1226
      share->primary_key= primary_key;
1227
      /*
1228
	If we are using an integer as the primary key then allow the user to
1229
	refer to it as '_rowid'
1230
      */
1231
      if (share->key_info[primary_key].key_parts == 1)
1232
      {
1233
	Field *field= share->key_info[primary_key].key_part[0].field;
1234
	if (field && field->result_type() == INT_RESULT)
1235
        {
1236
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1237
	  share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1238
                                      fieldnr);
1239
        }
1240
      }
1241
    }
1242
    else
1243
      share->primary_key = MAX_KEY; // we do not have a primary key
1244
  }
1245
  else
1246
    share->primary_key= MAX_KEY;
1247
  x_free((uchar*) disk_buff);
1248
  disk_buff=0;
1249
  if (new_field_pack_flag <= 1)
1250
  {
1251
    /* Old file format with default as not null */
1252
    uint null_length= (share->null_fields+7)/8;
1253
    bfill(share->default_values + (null_flags - (uchar*) record),
1254
          null_length, 255);
1255
  }
1256
1257
  if (share->found_next_number_field)
1258
  {
1259
    reg_field= *share->found_next_number_field;
1260
    if ((int) (share->next_number_index= (uint)
1261
	       find_ref_key(share->key_info, share->keys,
1262
                            share->default_values, reg_field,
1263
			    &share->next_number_key_offset,
1264
                            &share->next_number_keypart)) < 0)
1265
    {
1266
      /* Wrong field definition */
1267
      error= 4;
1268
      goto err;
1269
    }
1270
    else
1271
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1272
  }
1273
1274
  if (share->blob_fields)
1275
  {
1276
    Field **ptr;
1277
    uint k, *save;
1278
1279
    /* Store offsets to blob fields to find them fast */
1280
    if (!(share->blob_field= save=
1281
	  (uint*) alloc_root(&share->mem_root,
1282
                             (uint) (share->blob_fields* sizeof(uint)))))
1283
      goto err;
1284
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1285
    {
1286
      if ((*ptr)->flags & BLOB_FLAG)
1287
	(*save++)= k;
1288
    }
1289
  }
1290
1291
  /*
1292
    the correct null_bytes can now be set, since bitfields have been taken
1293
    into account
1294
  */
1295
  share->null_bytes= (null_pos - (uchar*) null_flags +
1296
                      (null_bit_pos + 7) / 8);
1297
  share->last_null_bit_pos= null_bit_pos;
1298
1299
  share->db_low_byte_first= handler_file->low_byte_first();
1300
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1301
1302
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1303
                                             share->column_bitmap_size)))
1304
    goto err;
1305
  bitmap_init(&share->all_set, bitmaps, share->fields, FALSE);
1306
  bitmap_set_all(&share->all_set);
1307
1308
  delete handler_file;
1309
#ifndef DBUG_OFF
1310
  if (use_hash)
1311
    (void) hash_check(&share->name_hash);
1312
#endif
1313
  if (buff)
1314
    my_free(buff, MYF(0));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1315
  return (0);
1 by brian
clean slate
1316
1317
 err:
1318
  if (buff)
1319
    my_free(buff, MYF(0));
1320
  share->error= error;
1321
  share->open_errno= my_errno;
1322
  share->errarg= errarg;
1323
  x_free((uchar*) disk_buff);
1324
  delete crypted;
1325
  delete handler_file;
1326
  hash_free(&share->name_hash);
1327
1328
  open_table_error(share, error, share->open_errno, errarg);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1329
  return(error);
1 by brian
clean slate
1330
} /* open_binary_frm */
1331
1332
1333
/*
1334
  Open a table based on a TABLE_SHARE
1335
1336
  SYNOPSIS
1337
    open_table_from_share()
1338
    thd			Thread handler
1339
    share		Table definition
1340
    alias       	Alias for table
1341
    db_stat		open flags (for example HA_OPEN_KEYFILE|
1342
    			HA_OPEN_RNDFILE..) can be 0 (example in
1343
                        ha_example_table)
1344
    prgflag   		READ_ALL etc..
1345
    ha_open_flags	HA_OPEN_ABORT_IF_LOCKED etc..
1346
    outparam       	result table
1347
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1348
                        if OTM_CREATE some errors are ignore
1349
                        if OTM_ALTER HA_OPEN is not called
1350
1351
  RETURN VALUES
1352
   0	ok
1353
   1	Error (see open_table_error)
1354
   2    Error (see open_table_error)
1355
   3    Wrong data in .frm file
1356
   4    Error (see open_table_error)
1357
   5    Error (see open_table_error: charset unavailable)
1358
   7    Table definition has changed in engine
1359
*/
1360
1361
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1362
                          uint db_stat, uint prgflag, uint ha_open_flags,
1363
                          TABLE *outparam, open_table_mode open_mode)
1364
{
1365
  int error;
1366
  uint records, i, bitmap_size;
1367
  bool error_reported= FALSE;
1368
  uchar *record, *bitmaps;
1369
  Field **field_ptr;
1370
1371
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1372
  assert(thd->lex->is_lex_started);
1 by brian
clean slate
1373
1374
  error= 1;
1375
  bzero((char*) outparam, sizeof(*outparam));
1376
  outparam->in_use= thd;
1377
  outparam->s= share;
1378
  outparam->db_stat= db_stat;
1379
  outparam->write_row_record= NULL;
1380
1381
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1382
1383
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
1384
    goto err;
1385
  outparam->quick_keys.init();
1386
  outparam->covering_keys.init();
1387
  outparam->keys_in_use_for_query.init();
1388
1389
  /* Allocate handler */
1390
  outparam->file= 0;
1391
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
1392
  {
1393
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1394
                                          share->db_type())))
1395
      goto err;
1396
  }
1397
  else
1398
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1399
    assert(!db_stat);
1 by brian
clean slate
1400
  }
1401
1402
  error= 4;
1403
  outparam->reginfo.lock_type= TL_UNLOCK;
1404
  outparam->current_lock= F_UNLCK;
1405
  records=0;
1406
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1407
    records=1;
1408
  if (prgflag & (READ_ALL+EXTRA_RECORD))
1409
    records++;
1410
1411
  if (!(record= (uchar*) alloc_root(&outparam->mem_root,
1412
                                   share->rec_buff_length * records)))
1413
    goto err;                                   /* purecov: inspected */
1414
1415
  if (records == 0)
1416
  {
1417
    /* We are probably in hard repair, and the buffers should not be used */
1418
    outparam->record[0]= outparam->record[1]= share->default_values;
1419
  }
1420
  else
1421
  {
1422
    outparam->record[0]= record;
1423
    if (records > 1)
1424
      outparam->record[1]= record+ share->rec_buff_length;
1425
    else
1426
      outparam->record[1]= outparam->record[0];   // Safety
1427
  }
1428
1429
#ifdef HAVE_purify
1430
  /*
1431
    We need this because when we read var-length rows, we are not updating
1432
    bytes after end of varchar
1433
  */
1434
  if (records > 1)
1435
  {
1436
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1437
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
1438
    if (records > 2)
1439
      memcpy(outparam->record[1], share->default_values,
1440
             share->rec_buff_length);
1441
  }
1442
#endif
1443
1444
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1445
                                          (uint) ((share->fields+1)*
1446
                                                  sizeof(Field*)))))
1447
    goto err;                                   /* purecov: inspected */
1448
1449
  outparam->field= field_ptr;
1450
1451
  record= (uchar*) outparam->record[0]-1;	/* Fieldstart = 1 */
1452
  if (share->null_field_first)
1453
    outparam->null_flags= (uchar*) record+1;
1454
  else
1455
    outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
1456
                                    share->null_bytes);
1457
1458
  /* Setup copy of fields from share, but use the right alias and record */
1459
  for (i=0 ; i < share->fields; i++, field_ptr++)
1460
  {
1461
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1462
      goto err;
1463
  }
1464
  (*field_ptr)= 0;                              // End marker
1465
1466
  if (share->found_next_number_field)
1467
    outparam->found_next_number_field=
1468
      outparam->field[(uint) (share->found_next_number_field - share->field)];
1469
  if (share->timestamp_field)
1470
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1471
1472
1473
  /* Fix key->name and key_part->field */
1474
  if (share->key_parts)
1475
  {
1476
    KEY	*key_info, *key_info_end;
1477
    KEY_PART_INFO *key_part;
1478
    uint n_length;
1479
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1480
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1481
      goto err;
1482
    outparam->key_info= key_info;
1483
    key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
1484
    
1485
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1486
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1487
                                                   share->key_parts));
1488
1489
    for (key_info_end= key_info + share->keys ;
1490
         key_info < key_info_end ;
1491
         key_info++)
1492
    {
1493
      KEY_PART_INFO *key_part_end;
1494
1495
      key_info->table= outparam;
1496
      key_info->key_part= key_part;
1497
1498
      for (key_part_end= key_part+ key_info->key_parts ;
1499
           key_part < key_part_end ;
1500
           key_part++)
1501
      {
1502
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1503
1504
        if (field->key_length() != key_part->length &&
1505
            !(field->flags & BLOB_FLAG))
1506
        {
1507
          /*
1508
            We are using only a prefix of the column as a key:
1509
            Create a new field for the key part that matches the index
1510
          */
1511
          field= key_part->field=field->new_field(&outparam->mem_root,
1512
                                                  outparam, 0);
1513
          field->field_length= key_part->length;
1514
        }
1515
      }
1516
    }
1517
  }
1518
1519
  /* Allocate bitmaps */
1520
1521
  bitmap_size= share->column_bitmap_size;
1522
  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1523
    goto err;
1524
  bitmap_init(&outparam->def_read_set,
1525
              (my_bitmap_map*) bitmaps, share->fields, FALSE);
1526
  bitmap_init(&outparam->def_write_set,
1527
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE);
1528
  bitmap_init(&outparam->tmp_set,
1529
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
1530
  outparam->default_column_bitmaps();
1531
1532
  /* The table struct is now initialized;  Open the table */
1533
  error= 2;
1534
  if (db_stat && open_mode != OTM_ALTER)
1535
  {
1536
    int ha_err;
1537
    if ((ha_err= (outparam->file->
1538
                  ha_open(outparam, share->normalized_path.str,
1539
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1540
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1541
                           ((db_stat & HA_WAIT_IF_LOCKED) ||
1542
                            (specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
1543
                           HA_OPEN_WAIT_IF_LOCKED :
1544
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1545
                          HA_OPEN_ABORT_IF_LOCKED :
1546
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1547
    {
1548
      /* Set a flag if the table is crashed and it can be auto. repaired */
1549
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1550
                       outparam->file->auto_repair() &&
1551
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
1552
1553
      switch (ha_err)
1554
      {
1555
        case HA_ERR_NO_SUCH_TABLE:
1556
	  /*
1557
            The table did not exists in storage engine, use same error message
1558
            as if the .frm file didn't exist
1559
          */
1560
	  error= 1;
1561
	  my_errno= ENOENT;
1562
          break;
1563
        case EMFILE:
1564
	  /*
1565
            Too many files opened, use same error message as if the .frm
1566
            file can't open
1567
           */
1568
	  error= 1;
1569
	  my_errno= EMFILE;
1570
          break;
1571
        default:
1572
          outparam->file->print_error(ha_err, MYF(0));
1573
          error_reported= TRUE;
1574
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1575
            error= 7;
1576
          break;
1577
      }
1578
      goto err;                                 /* purecov: inspected */
1579
    }
1580
  }
1581
1582
#if defined(HAVE_purify) && !defined(DBUG_OFF)
1583
  bzero((char*) bitmaps, bitmap_size*3);
1584
#endif
1585
1586
  outparam->no_replicate= outparam->file &&
1587
                          test(outparam->file->ha_table_flags() &
1588
                               HA_HAS_OWN_BINLOGGING);
1589
  thd->status_var.opened_tables++;
1590
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1591
  return (0);
1 by brian
clean slate
1592
1593
 err:
1594
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1595
    open_table_error(share, error, my_errno, 0);
1596
  delete outparam->file;
1597
  outparam->file= 0;				// For easier error checking
1598
  outparam->db_stat=0;
1599
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on bzero'd root
1600
  my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1601
  return (error);
1 by brian
clean slate
1602
}
1603
1604
1605
/*
1606
  Free information allocated by openfrm
1607
1608
  SYNOPSIS
1609
    closefrm()
1610
    table		TABLE object to free
1611
    free_share		Is 1 if we also want to free table_share
1612
*/
1613
1614
int closefrm(register TABLE *table, bool free_share)
1615
{
1616
  int error=0;
1617
1618
  if (table->db_stat)
1619
    error=table->file->close();
1620
  my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
1621
  table->alias= 0;
1622
  if (table->field)
1623
  {
1624
    for (Field **ptr=table->field ; *ptr ; ptr++)
1625
      delete *ptr;
1626
    table->field= 0;
1627
  }
1628
  delete table->file;
1629
  table->file= 0;				/* For easier errorchecking */
1630
  if (free_share)
1631
  {
1632
    if (table->s->tmp_table == NO_TMP_TABLE)
1633
      release_table_share(table->s, RELEASE_NORMAL);
1634
    else
1635
      free_table_share(table->s);
1636
  }
1637
  free_root(&table->mem_root, MYF(0));
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1638
  return(error);
1 by brian
clean slate
1639
}
1640
1641
1642
/* Deallocate temporary blob storage */
1643
1644
void free_blobs(register TABLE *table)
1645
{
1646
  uint *ptr, *end;
1647
  for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
1648
       ptr != end ;
1649
       ptr++)
1650
    ((Field_blob*) table->field[*ptr])->free();
1651
}
1652
1653
1654
	/* Find where a form starts */
1655
	/* if formname is NullS then only formnames is read */
1656
1657
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
1658
{
1659
  uint a_length,names,length;
1660
  uchar *pos,*buf;
1661
  ulong ret_value=0;
1662
1663
  names=uint2korr(head+8);
1664
  a_length=(names+2)*sizeof(char *);		/* Room for two extra */
1665
1666
  if (!save_names)
1667
    a_length=0;
1668
  else
1669
    save_names->type_names=0;			/* Clear if error */
1670
1671
  if (names)
1672
  {
1673
    length=uint2korr(head+4);
1674
    VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0)));
1675
    if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
1676
				  MYF(MY_WME))) ||
1677
	my_read(file, buf+a_length, (size_t) (length+names*4),
1678
		MYF(MY_NABP)))
1679
    {						/* purecov: inspected */
1680
      x_free((uchar*) buf);			/* purecov: inspected */
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1681
      return(0L);				/* purecov: inspected */
1 by brian
clean slate
1682
    }
1683
    pos= buf+a_length+length;
1684
    ret_value=uint4korr(pos);
1685
  }
1686
  if (! save_names)
1687
  {
1688
    if (names)
1689
      my_free((uchar*) buf,MYF(0));
1690
  }
1691
  else if (!names)
1692
    bzero((char*) save_names,sizeof(save_names));
1693
  else
1694
  {
1695
    char *str;
1696
    str=(char *) (buf+a_length);
1697
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
1698
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1699
  return(ret_value);
1 by brian
clean slate
1700
}
1701
1702
1703
/*
1704
  Read string from a file with malloc
1705
1706
  NOTES:
1707
    We add an \0 at end of the read string to make reading of C strings easier
1708
*/
1709
1710
int read_string(File file, uchar**to, size_t length)
1711
{
1712
1713
  x_free(*to);
1714
  if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
1715
      my_read(file, *to, length,MYF(MY_NABP)))
1716
  {
1717
    x_free(*to);                              /* purecov: inspected */
1718
    *to= 0;                                   /* purecov: inspected */
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1719
    return(1);                           /* purecov: inspected */
1 by brian
clean slate
1720
  }
1721
  *((char*) *to+length)= '\0';
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1722
  return (0);
1 by brian
clean slate
1723
} /* read_string */
1724
1725
1726
	/* Add a new form to a form file */
1727
1728
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
1729
		     const char *newname)
1730
{
1731
  uint i,bufflength,maxlength,n_length,length,names;
1732
  ulong endpos,newpos;
1733
  uchar buff[IO_SIZE];
1734
  uchar *pos;
1735
1736
  length=(uint) strlen(newname)+1;
1737
  n_length=uint2korr(fileinfo+4);
1738
  maxlength=uint2korr(fileinfo+6);
1739
  names=uint2korr(fileinfo+8);
1740
  newpos=uint4korr(fileinfo+10);
1741
1742
  if (64+length+n_length+(names+1)*4 > maxlength)
1743
  {						/* Expand file */
1744
    newpos+=IO_SIZE;
1745
    int4store(fileinfo+10,newpos);
1746
    endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1747
    bufflength= (uint) (endpos & (IO_SIZE-1));	/* IO_SIZE is a power of 2 */
1748
1749
    while (endpos > maxlength)
1750
    {
1751
      VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
1752
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1753
	return(0L);
1 by brian
clean slate
1754
      VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1755
		   MYF(0)));
1756
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1757
	return(0);
1 by brian
clean slate
1758
      endpos-=bufflength; bufflength=IO_SIZE;
1759
    }
1760
    bzero(buff,IO_SIZE);			/* Null new block */
1761
    VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
1762
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1763
	return(0L);
1 by brian
clean slate
1764
    maxlength+=IO_SIZE;				/* Fix old ref */
1765
    int2store(fileinfo+6,maxlength);
1766
    for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
1767
	 pos+=4)
1768
    {
1769
      endpos=uint4korr(pos)+IO_SIZE;
1770
      int4store(pos,endpos);
1771
    }
1772
  }
1773
1774
  if (n_length == 1 )
1775
  {						/* First name */
1776
    length++;
1777
    VOID(strxmov((char*) buff,"/",newname,"/",NullS));
1778
  }
1779
  else
1780
    VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1781
  VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
1782
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1783
      (names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
1784
			 names*4, MYF(MY_NABP+MY_WME))) ||
1785
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1786
    return(0L); /* purecov: inspected */
1 by brian
clean slate
1787
1788
  int2store(fileinfo+8,names+1);
1789
  int2store(fileinfo+4,n_length+length);
30 by Brian Aker
Large file and ftruncate() support
1790
  (void)ftruncate(file, newpos);/* Append file with '\0' */
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1791
  return(newpos);
1 by brian
clean slate
1792
} /* make_new_entry */
1793
1794
1795
	/* error message when opening a form file */
1796
1797
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1798
{
1799
  int err_no;
1800
  char buff[FN_REFLEN];
1801
  myf errortype= ME_ERROR+ME_WAITTANG;
1802
1803
  switch (error) {
1804
  case 7:
1805
  case 1:
1806
    if (db_errno == ENOENT)
1807
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1808
    else
1809
    {
1810
      strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1811
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1812
               errortype, buff, db_errno);
1813
    }
1814
    break;
1815
  case 2:
1816
  {
1817
    handler *file= 0;
1818
    const char *datext= "";
1819
    
1820
    if (share->db_type() != NULL)
1821
    {
1822
      if ((file= get_new_handler(share, current_thd->mem_root,
1823
                                 share->db_type())))
1824
      {
1825
        if (!(datext= *file->bas_ext()))
1826
          datext= "";
1827
      }
1828
    }
1829
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1830
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1831
    strxmov(buff, share->normalized_path.str, datext, NullS);
1832
    my_error(err_no,errortype, buff, db_errno);
1833
    delete file;
1834
    break;
1835
  }
1836
  case 5:
1837
  {
1838
    const char *csname= get_charset_name((uint) errarg);
1839
    char tmp[10];
1840
    if (!csname || csname[0] =='?')
1841
    {
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1842
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
1 by brian
clean slate
1843
      csname= tmp;
1844
    }
1845
    my_printf_error(ER_UNKNOWN_COLLATION,
1846
                    "Unknown collation '%s' in table '%-.64s' definition", 
1847
                    MYF(0), csname, share->table_name.str);
1848
    break;
1849
  }
1850
  case 6:
1851
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1852
    my_printf_error(ER_NOT_FORM_FILE,
1853
                    "Table '%-.64s' was created with a different version "
1854
                    "of MySQL and cannot be read", 
1855
                    MYF(0), buff);
1856
    break;
1857
  case 8:
1858
    break;
1859
  default:				/* Better wrong error than none */
1860
  case 4:
1861
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1862
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1863
    break;
1864
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
1865
  return;
1 by brian
clean slate
1866
} /* open_table_error */
1867
1868
1869
	/*
1870
	** fix a str_type to a array type
1871
	** typeparts separated with some char. differents types are separated
1872
	** with a '\0'
1873
	*/
1874
1875
static void
1876
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
1877
		  char **names)
1878
{
1879
  char *type_name, *ptr;
1880
  char chr;
1881
1882
  ptr= *names;
1883
  while (types--)
1884
  {
1885
    point_to_type->name=0;
1886
    point_to_type->type_names= *array;
1887
1888
    if ((chr= *ptr))			/* Test if empty type */
1889
    {
1890
      while ((type_name=strchr(ptr+1,chr)) != NullS)
1891
      {
1892
	*((*array)++) = ptr+1;
1893
	*type_name= '\0';		/* End string */
1894
	ptr=type_name;
1895
      }
1896
      ptr+=2;				/* Skip end mark and last 0 */
1897
    }
1898
    else
1899
      ptr++;
1900
    point_to_type->count= (uint) (*array - point_to_type->type_names);
1901
    point_to_type++;
1902
    *((*array)++)= NullS;		/* End of type */
1903
  }
1904
  *names=ptr;				/* Update end */
1905
  return;
1906
} /* fix_type_pointers */
1907
1908
1909
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1910
{
1911
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1912
  if (!result)
1913
    return 0;
1914
  result->count=strings.elements;
1915
  result->name="";
1916
  uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1917
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1918
    return 0;
1919
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1920
  List_iterator<String> it(strings);
1921
  String *tmp;
1922
  for (uint i=0; (tmp=it++) ; i++)
1923
  {
1924
    result->type_names[i]= tmp->ptr();
1925
    result->type_lengths[i]= tmp->length();
1926
  }
1927
  result->type_names[result->count]= 0;		// End marker
1928
  result->type_lengths[result->count]= 0;
1929
  return result;
1930
}
1931
1932
1933
/*
1934
 Search after a field with given start & length
1935
 If an exact field isn't found, return longest field with starts
1936
 at right position.
1937
 
1938
 NOTES
1939
   This is needed because in some .frm fields 'fieldnr' was saved wrong
1940
1941
 RETURN
1942
   0  error
1943
   #  field number +1
1944
*/
1945
1946
static uint find_field(Field **fields, uchar *record, uint start, uint length)
1947
{
1948
  Field **field;
1949
  uint i, pos;
1950
1951
  pos= 0;
1952
  for (field= fields, i=1 ; *field ; i++,field++)
1953
  {
1954
    if ((*field)->offset(record) == start)
1955
    {
1956
      if ((*field)->key_length() == length)
1957
	return (i);
1958
      if (!pos || fields[pos-1]->pack_length() <
1959
	  (*field)->pack_length())
1960
	pos= i;
1961
    }
1962
  }
1963
  return (pos);
1964
}
1965
1966
1967
	/* Check that the integer is in the internal */
1968
1969
int set_zone(register int nr, int min_zone, int max_zone)
1970
{
1971
  if (nr<=min_zone)
1972
    return (min_zone);
1973
  if (nr>=max_zone)
1974
    return (max_zone);
1975
  return (nr);
1976
} /* set_zone */
1977
1978
	/* Adjust number to next larger disk buffer */
1979
1980
ulong next_io_size(register ulong pos)
1981
{
1982
  register ulong offset;
1983
  if ((offset= pos & (IO_SIZE-1)))
1984
    return pos-offset+IO_SIZE;
1985
  return pos;
1986
} /* next_io_size */
1987
1988
1989
/*
1990
  Store an SQL quoted string.
1991
1992
  SYNOPSIS  
1993
    append_unescaped()
1994
    res		result String
1995
    pos		string to be quoted
1996
    length	it's length
1997
1998
  NOTE
1999
    This function works correctly with utf8 or single-byte charset strings.
2000
    May fail with some multibyte charsets though.
2001
*/
2002
2003
void append_unescaped(String *res, const char *pos, uint length)
2004
{
2005
  const char *end= pos+length;
2006
  res->append('\'');
2007
2008
  for (; pos != end ; pos++)
2009
  {
2010
#if defined(USE_MB) && MYSQL_VERSION_ID < 40100
2011
    uint mblen;
2012
    if (use_mb(default_charset_info) &&
2013
        (mblen= my_ismbchar(default_charset_info, pos, end)))
2014
    {
2015
      res->append(pos, mblen);
2016
      pos+= mblen;
2017
      continue;
2018
    }
2019
#endif
2020
2021
    switch (*pos) {
2022
    case 0:				/* Must be escaped for 'mysql' */
2023
      res->append('\\');
2024
      res->append('0');
2025
      break;
2026
    case '\n':				/* Must be escaped for logs */
2027
      res->append('\\');
2028
      res->append('n');
2029
      break;
2030
    case '\r':
2031
      res->append('\\');		/* This gives better readability */
2032
      res->append('r');
2033
      break;
2034
    case '\\':
2035
      res->append('\\');		/* Because of the sql syntax */
2036
      res->append('\\');
2037
      break;
2038
    case '\'':
2039
      res->append('\'');		/* Because of the sql syntax */
2040
      res->append('\'');
2041
      break;
2042
    default:
2043
      res->append(*pos);
2044
      break;
2045
    }
2046
  }
2047
  res->append('\'');
2048
}
2049
2050
2051
	/* Create a .frm file */
2052
2053
File create_frm(THD *thd, const char *name, const char *db,
2054
                const char *table, uint reclength, uchar *fileinfo,
2055
  		HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
2056
{
2057
  register File file;
2058
  ulong length;
2059
  uchar fill[IO_SIZE];
2060
  int create_flags= O_RDWR | O_TRUNC;
2061
  ulong key_comment_total_bytes= 0;
2062
  uint i;
2063
2064
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2065
    create_flags|= O_EXCL | O_NOFOLLOW;
2066
2067
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
2068
  if (create_info->max_rows > UINT_MAX32)
2069
    create_info->max_rows= UINT_MAX32;
2070
  if (create_info->min_rows > UINT_MAX32)
2071
    create_info->min_rows= UINT_MAX32;
2072
2073
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
2074
  {
2075
    uint key_length, tmp_key_length;
2076
    uint tmp;
2077
    bzero((char*) fileinfo,64);
2078
    /* header */
2079
    fileinfo[0]=(uchar) 254;
2080
    fileinfo[1]= 1;
2081
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
2082
2083
    fileinfo[3]= (uchar) ha_legacy_type(
2084
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
2085
    fileinfo[4]=1;
2086
    int2store(fileinfo+6,IO_SIZE);		/* Next block starts here */
2087
    for (i= 0; i < keys; i++)
2088
    {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2089
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
1 by brian
clean slate
2090
                 (key_info[i].comment.length > 0));
2091
      if (key_info[i].flags & HA_USES_COMMENT)
2092
        key_comment_total_bytes += 2 + key_info[i].comment.length;
2093
    }
2094
    /*
2095
      Keep in sync with pack_keys() in unireg.cc
2096
      For each key:
2097
      8 bytes for the key header
2098
      9 bytes for each key-part (MAX_REF_PARTS)
2099
      NAME_LEN bytes for the name
2100
      1 byte for the NAMES_SEP_CHAR (before the name)
2101
      For all keys:
2102
      6 bytes for the header
2103
      1 byte for the NAMES_SEP_CHAR (after the last name)
2104
      9 extra bytes (padding for safety? alignment?)
2105
      comments
2106
    */
2107
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
2108
                 key_comment_total_bytes);
2109
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
2110
                                  create_info->extra_size));
2111
    int4store(fileinfo+10,length);
2112
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
2113
    int2store(fileinfo+14,tmp_key_length);
2114
    int2store(fileinfo+16,reclength);
2115
    int4store(fileinfo+18,create_info->max_rows);
2116
    int4store(fileinfo+22,create_info->min_rows);
2117
    /* fileinfo[26] is set in mysql_create_frm() */
2118
    fileinfo[27]=2;				// Use long pack-fields
2119
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
2120
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
2121
    int2store(fileinfo+30,create_info->table_options);
2122
    fileinfo[32]=0;				// No filename anymore
2123
    fileinfo[33]=5;                             // Mark for 5.0 frm file
2124
    int4store(fileinfo+34,create_info->avg_row_length);
2125
    fileinfo[38]= (create_info->default_table_charset ?
2126
		   create_info->default_table_charset->number : 0);
2127
    fileinfo[39]= (uchar) ((uint) create_info->transactional |
2128
                           ((uint) create_info->page_checksum << 2));
2129
    fileinfo[40]= (uchar) create_info->row_type;
2130
    /* Next few bytes where for RAID support */
2131
    fileinfo[41]= 0;
2132
    fileinfo[42]= 0;
2133
    fileinfo[43]= 0;
2134
    fileinfo[44]= 0;
2135
    fileinfo[45]= 0;
2136
    fileinfo[46]= 0;
2137
    int4store(fileinfo+47, key_length);
2138
    tmp= MYSQL_VERSION_ID;          // Store to avoid warning from int4store
2139
    int4store(fileinfo+51, tmp);
2140
    int4store(fileinfo+55, create_info->extra_size);
2141
    /*
2142
      59-60 is reserved for extra_rec_buf_length,
2143
      61 for default_part_db_type
2144
    */
2145
    int2store(fileinfo+62, create_info->key_block_size);
2146
    bzero(fill,IO_SIZE);
2147
    for (; length > IO_SIZE ; length-= IO_SIZE)
2148
    {
2149
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
2150
      {
2151
	VOID(my_close(file,MYF(0)));
2152
	VOID(my_delete(name,MYF(0)));
2153
	return(-1);
2154
      }
2155
    }
2156
  }
2157
  else
2158
  {
2159
    if (my_errno == ENOENT)
2160
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2161
    else
2162
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2163
  }
2164
  return (file);
2165
} /* create_frm */
2166
2167
2168
void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
2169
{
2170
  TABLE_SHARE *share= table->s;
2171
2172
  create_info->max_rows= share->max_rows;
2173
  create_info->min_rows= share->min_rows;
2174
  create_info->table_options= share->db_create_options;
2175
  create_info->avg_row_length= share->avg_row_length;
2176
  create_info->row_type= share->row_type;
2177
  create_info->default_storage_media= share->default_storage_media;
2178
  create_info->tablespace= share->tablespace;
2179
  create_info->default_table_charset= share->table_charset;
2180
  create_info->table_charset= 0;
2181
  create_info->comment= share->comment;
2182
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2183
  return;
1 by brian
clean slate
2184
}
2185
2186
int
2187
rename_file_ext(const char * from,const char * to,const char * ext)
2188
{
2189
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
2190
  VOID(strxmov(from_b,from,ext,NullS));
2191
  VOID(strxmov(to_b,to,ext,NullS));
2192
  return (my_rename(from_b,to_b,MYF(MY_WME)));
2193
}
2194
2195
2196
/*
2197
  Allocate string field in MEM_ROOT and return it as String
2198
2199
  SYNOPSIS
2200
    get_field()
2201
    mem   	MEM_ROOT for allocating
2202
    field 	Field for retrieving of string
2203
    res         result String
2204
2205
  RETURN VALUES
2206
    1   string is empty
2207
    0	all ok
2208
*/
2209
2210
bool get_field(MEM_ROOT *mem, Field *field, String *res)
2211
{
2212
  char buff[MAX_FIELD_WIDTH], *to;
2213
  String str(buff,sizeof(buff),&my_charset_bin);
2214
  uint length;
2215
2216
  field->val_str(&str);
2217
  if (!(length= str.length()))
2218
  {
2219
    res->length(0);
2220
    return 1;
2221
  }
2222
  if (!(to= strmake_root(mem, str.ptr(), length)))
2223
    length= 0;                                  // Safety fix
2224
  res->set(to, length, ((Field_str*)field)->charset());
2225
  return 0;
2226
}
2227
2228
2229
/*
2230
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
2231
2232
  SYNOPSIS
2233
    get_field()
2234
    mem   	MEM_ROOT for allocating
2235
    field 	Field for retrieving of string
2236
2237
  RETURN VALUES
2238
    NullS  string is empty
2239
    #      pointer to NULL-terminated string value of field
2240
*/
2241
2242
char *get_field(MEM_ROOT *mem, Field *field)
2243
{
2244
  char buff[MAX_FIELD_WIDTH], *to;
2245
  String str(buff,sizeof(buff),&my_charset_bin);
2246
  uint length;
2247
2248
  field->val_str(&str);
2249
  length= str.length();
2250
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2251
    return NullS;
2252
  memcpy(to,str.ptr(),(uint) length);
2253
  to[length]=0;
2254
  return to;
2255
}
2256
2257
/*
2258
  DESCRIPTION
2259
    given a buffer with a key value, and a map of keyparts
2260
    that are present in this value, returns the length of the value
2261
*/
2262
uint calculate_key_len(TABLE *table, uint key, const uchar *buf,
2263
                       key_part_map keypart_map)
2264
{
2265
  /* works only with key prefixes */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2266
  assert(((keypart_map + 1) & keypart_map) == 0);
1 by brian
clean slate
2267
2268
  KEY *key_info= table->s->key_info+key;
2269
  KEY_PART_INFO *key_part= key_info->key_part;
2270
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
2271
  uint length= 0;
2272
2273
  while (key_part < end_key_part && keypart_map)
2274
  {
2275
    length+= key_part->store_length;
2276
    keypart_map >>= 1;
2277
    key_part++;
2278
  }
2279
  return length;
2280
}
2281
2282
/*
2283
  Check if database name is valid
2284
2285
  SYNPOSIS
2286
    check_db_name()
2287
    org_name		Name of database and length
2288
2289
  NOTES
2290
    If lower_case_table_names is set then database is converted to lower case
2291
2292
  RETURN
2293
    0	ok
2294
    1   error
2295
*/
2296
2297
bool check_db_name(LEX_STRING *org_name)
2298
{
2299
  char *name= org_name->str;
2300
  uint name_length= org_name->length;
2301
2302
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
2303
    return 1;
2304
2305
  if (lower_case_table_names && name != any_db)
2306
    my_casedn_str(files_charset_info, name);
2307
2308
  return check_identifier_name(org_name);
2309
}
2310
2311
2312
/*
2313
  Allow anything as a table name, as long as it doesn't contain an
2314
  ' ' at the end
2315
  returns 1 on error
2316
*/
2317
2318
2319
bool check_table_name(const char *name, uint length)
2320
{
2321
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
2322
    return 1;
2323
  LEX_STRING ident;
2324
  ident.str= (char*) name;
2325
  ident.length= length;
2326
  return check_identifier_name(&ident);
2327
}
2328
2329
2330
/*
2331
  Eventually, a "length" argument should be added
2332
  to this function, and the inner loop changed to
2333
  check_identifier_name() call.
2334
*/
2335
bool check_column_name(const char *name)
2336
{
2337
  uint name_length= 0;  // name length in symbols
2338
  bool last_char_is_space= TRUE;
2339
  
2340
  while (*name)
2341
  {
2342
#if defined(USE_MB) && defined(USE_MB_IDENT)
2343
    last_char_is_space= my_isspace(system_charset_info, *name);
2344
    if (use_mb(system_charset_info))
2345
    {
2346
      int len=my_ismbchar(system_charset_info, name, 
2347
                          name+system_charset_info->mbmaxlen);
2348
      if (len)
2349
      {
2350
        if (len > 3) /* Disallow non-BMP characters */
2351
          return 1;
2352
        name += len;
2353
        name_length++;
2354
        continue;
2355
      }
2356
    }
2357
#else
2358
    last_char_is_space= *name==' ';
2359
#endif
2360
    /*
2361
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
2362
      It is defined as 0xFF, which is a not valid byte in utf8.
2363
      This assert is to catch use of this byte if we decide to
2364
      use non-utf8 as system_character_set.
2365
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2366
    assert(*name != NAMES_SEP_CHAR);
1 by brian
clean slate
2367
    name++;
2368
    name_length++;
2369
  }
2370
  /* Error if empty or too long column name */
2371
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2372
}
2373
2374
2375
/**
2376
  Checks whether a table is intact. Should be done *just* after the table has
2377
  been opened.
2378
2379
  @param[in] table             The table to check
2380
  @param[in] table_f_count     Expected number of columns in the table
2381
  @param[in] table_def         Expected structure of the table (column name
2382
                               and type)
2383
2384
  @retval  FALSE  OK
2385
  @retval  TRUE   There was an error. An error message is output
2386
                  to the error log.  We do not push an error
2387
                  message into the error stack because this
2388
                  function is currently only called at start up,
2389
                  and such errors never reach the user.
2390
*/
2391
2392
my_bool
2393
table_check_intact(TABLE *table, const uint table_f_count,
2394
                   const TABLE_FIELD_W_TYPE *table_def)
2395
{
2396
  uint i;
2397
  my_bool error= FALSE;
2398
  my_bool fields_diff_count;
2399
2400
  fields_diff_count= (table->s->fields != table_f_count);
2401
  if (fields_diff_count)
2402
  {
2403
2404
    /* previous MySQL version */
2405
    if (MYSQL_VERSION_ID > table->s->mysql_version)
2406
    {
2407
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2408
                      table->alias, table_f_count, table->s->fields,
2409
                      table->s->mysql_version, MYSQL_VERSION_ID);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2410
      return(TRUE);
1 by brian
clean slate
2411
    }
2412
    else if (MYSQL_VERSION_ID == table->s->mysql_version)
2413
    {
2414
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
2415
                      table_f_count, table->s->fields);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2416
      return(TRUE);
1 by brian
clean slate
2417
    }
2418
    /*
2419
      Something has definitely changed, but we're running an older
2420
      version of MySQL with new system tables.
2421
      Let's check column definitions. If a column was added at
2422
      the end of the table, then we don't care much since such change
2423
      is backward compatible.
2424
    */
2425
  }
2426
  char buffer[STRING_BUFFER_USUAL_SIZE];
2427
  for (i=0 ; i < table_f_count; i++, table_def++)
2428
  {
2429
    String sql_type(buffer, sizeof(buffer), system_charset_info);
2430
    sql_type.length(0);
2431
    if (i < table->s->fields)
2432
    {
2433
      Field *field= table->field[i];
2434
2435
      if (strncmp(field->field_name, table_def->name.str,
2436
                  table_def->name.length))
2437
      {
2438
        /*
2439
          Name changes are not fatal, we use ordinal numbers to access columns.
2440
          Still this can be a sign of a tampered table, output an error
2441
          to the error log.
2442
        */
2443
        sql_print_error("Incorrect definition of table %s.%s: "
2444
                        "expected column '%s' at position %d, found '%s'.",
2445
                        table->s->db.str, table->alias, table_def->name.str, i,
2446
                        field->field_name);
2447
      }
2448
      field->sql_type(sql_type);
2449
      /*
2450
        Generally, if column types don't match, then something is
2451
        wrong.
2452
2453
        However, we only compare column definitions up to the
2454
        length of the original definition, since we consider the
2455
        following definitions compatible:
2456
2457
        1. DATETIME and DATETIM
2458
        2. INT(11) and INT(11
2459
        3. SET('one', 'two') and SET('one', 'two', 'more')
2460
2461
        For SETs or ENUMs, if the same prefix is there it's OK to
2462
        add more elements - they will get higher ordinal numbers and
2463
        the new table definition is backward compatible with the
2464
        original one.
2465
       */
2466
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2467
                  table_def->type.length - 1))
2468
      {
2469
        sql_print_error("Incorrect definition of table %s.%s: "
2470
                        "expected column '%s' at position %d to have type "
2471
                        "%s, found type %s.", table->s->db.str, table->alias,
2472
                        table_def->name.str, i, table_def->type.str,
2473
                        sql_type.c_ptr_safe());
2474
        error= TRUE;
2475
      }
2476
      else if (table_def->cset.str && !field->has_charset())
2477
      {
2478
        sql_print_error("Incorrect definition of table %s.%s: "
2479
                        "expected the type of column '%s' at position %d "
2480
                        "to have character set '%s' but the type has no "
2481
                        "character set.", table->s->db.str, table->alias,
2482
                        table_def->name.str, i, table_def->cset.str);
2483
        error= TRUE;
2484
      }
2485
      else if (table_def->cset.str &&
2486
               strcmp(field->charset()->csname, table_def->cset.str))
2487
      {
2488
        sql_print_error("Incorrect definition of table %s.%s: "
2489
                        "expected the type of column '%s' at position %d "
2490
                        "to have character set '%s' but found "
2491
                        "character set '%s'.", table->s->db.str, table->alias,
2492
                        table_def->name.str, i, table_def->cset.str,
2493
                        field->charset()->csname);
2494
        error= TRUE;
2495
      }
2496
    }
2497
    else
2498
    {
2499
      sql_print_error("Incorrect definition of table %s.%s: "
2500
                      "expected column '%s' at position %d to have type %s "
2501
                      " but the column is not found.",
2502
                      table->s->db.str, table->alias,
2503
                      table_def->name.str, i, table_def->type.str);
2504
      error= TRUE;
2505
    }
2506
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2507
  return(error);
1 by brian
clean slate
2508
}
2509
2510
2511
/*
2512
  Create Item_field for each column in the table.
2513
2514
  SYNPOSIS
2515
    st_table::fill_item_list()
2516
      item_list          a pointer to an empty list used to store items
2517
2518
  DESCRIPTION
2519
    Create Item_field object for each column in the table and
2520
    initialize it with the corresponding Field. New items are
2521
    created in the current THD memory root.
2522
2523
  RETURN VALUE
2524
    0                    success
2525
    1                    out of memory
2526
*/
2527
2528
bool st_table::fill_item_list(List<Item> *item_list) const
2529
{
2530
  /*
2531
    All Item_field's created using a direct pointer to a field
2532
    are fixed in Item_field constructor.
2533
  */
2534
  for (Field **ptr= field; *ptr; ptr++)
2535
  {
2536
    Item_field *item= new Item_field(*ptr);
2537
    if (!item || item_list->push_back(item))
2538
      return TRUE;
2539
  }
2540
  return FALSE;
2541
}
2542
2543
/*
2544
  Reset an existing list of Item_field items to point to the
2545
  Fields of this table.
2546
2547
  SYNPOSIS
2548
    st_table::fill_item_list()
2549
      item_list          a non-empty list with Item_fields
2550
2551
  DESCRIPTION
2552
    This is a counterpart of fill_item_list used to redirect
2553
    Item_fields to the fields of a newly created table.
2554
    The caller must ensure that number of items in the item_list
2555
    is the same as the number of columns in the table.
2556
*/
2557
2558
void st_table::reset_item_list(List<Item> *item_list) const
2559
{
2560
  List_iterator_fast<Item> it(*item_list);
2561
  for (Field **ptr= field; *ptr; ptr++)
2562
  {
2563
    Item_field *item_field= (Item_field*) it++;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2564
    assert(item_field != 0);
1 by brian
clean slate
2565
    item_field->reset_field(*ptr);
2566
  }
2567
}
2568
2569
2570
/*
2571
  Merge ON expressions for a view
2572
2573
  SYNOPSIS
2574
    merge_on_conds()
2575
    thd             thread handle
2576
    table           table for the VIEW
2577
    is_cascaded     TRUE <=> merge ON expressions from underlying views
2578
2579
  DESCRIPTION
2580
    This function returns the result of ANDing the ON expressions
2581
    of the given view and all underlying views. The ON expressions
2582
    of the underlying views are added only if is_cascaded is TRUE.
2583
2584
  RETURN
2585
    Pointer to the built expression if there is any.
2586
    Otherwise and in the case of a failure NULL is returned.
2587
*/
2588
2589
static Item *
2590
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
2591
{
2592
2593
  Item *cond= NULL;
2594
  if (table->on_expr)
2595
    cond= table->on_expr->copy_andor_structure(thd);
2596
  if (!table->nested_join)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2597
    return(cond);
1 by brian
clean slate
2598
  List_iterator<TABLE_LIST> li(table->nested_join->join_list);
2599
  while (TABLE_LIST *tbl= li++)
2600
  {
2601
    cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
2602
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2603
  return(cond);
1 by brian
clean slate
2604
}
2605
2606
2607
/*
2608
  Find underlying base tables (TABLE_LIST) which represent given
2609
  table_to_find (TABLE)
2610
2611
  SYNOPSIS
2612
    TABLE_LIST::find_underlying_table()
2613
    table_to_find table to find
2614
2615
  RETURN
2616
    0  table is not found
2617
    found table reference
2618
*/
2619
2620
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
2621
{
2622
  /* is this real table and table which we are looking for? */
2623
  if (table == table_to_find && merge_underlying_list == 0)
2624
    return this;
2625
2626
  for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2627
  {
2628
    TABLE_LIST *result;
2629
    if ((result= tbl->find_underlying_table(table_to_find)))
2630
      return result;
2631
  }
2632
  return 0;
2633
}
2634
2635
/*
2636
  cleunup items belonged to view fields translation table
2637
2638
  SYNOPSIS
2639
    TABLE_LIST::cleanup_items()
2640
*/
2641
2642
void TABLE_LIST::cleanup_items()
2643
{
2644
  if (!field_translation)
2645
    return;
2646
2647
  for (Field_translator *transl= field_translation;
2648
       transl < field_translation_end;
2649
       transl++)
2650
    transl->item->walk(&Item::cleanup_processor, 0, 0);
2651
}
2652
2653
2654
/*
2655
  Set insert_values buffer
2656
2657
  SYNOPSIS
2658
    set_insert_values()
2659
    mem_root   memory pool for allocating
2660
2661
  RETURN
2662
    FALSE - OK
2663
    TRUE  - out of memory
2664
*/
2665
2666
bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
2667
{
2668
  if (table)
2669
  {
2670
    if (!table->insert_values &&
2671
        !(table->insert_values= (uchar *)alloc_root(mem_root,
2672
                                                   table->s->rec_buff_length)))
2673
      return TRUE;
2674
  }
2675
2676
  return FALSE;
2677
}
2678
2679
2680
/*
2681
  Test if this is a leaf with respect to name resolution.
2682
2683
  SYNOPSIS
2684
    TABLE_LIST::is_leaf_for_name_resolution()
2685
2686
  DESCRIPTION
2687
    A table reference is a leaf with respect to name resolution if
2688
    it is either a leaf node in a nested join tree (table, view,
2689
    schema table, subquery), or an inner node that represents a
2690
    NATURAL/USING join, or a nested join with materialized join
2691
    columns.
2692
2693
  RETURN
2694
    TRUE if a leaf, FALSE otherwise.
2695
*/
2696
bool TABLE_LIST::is_leaf_for_name_resolution()
2697
{
2698
  return (is_natural_join || is_join_columns_complete || !nested_join);
2699
}
2700
2701
2702
/*
2703
  Retrieve the first (left-most) leaf in a nested join tree with
2704
  respect to name resolution.
2705
2706
  SYNOPSIS
2707
    TABLE_LIST::first_leaf_for_name_resolution()
2708
2709
  DESCRIPTION
2710
    Given that 'this' is a nested table reference, recursively walk
2711
    down the left-most children of 'this' until we reach a leaf
2712
    table reference with respect to name resolution.
2713
2714
  IMPLEMENTATION
2715
    The left-most child of a nested table reference is the last element
2716
    in the list of children because the children are inserted in
2717
    reverse order.
2718
2719
  RETURN
2720
    If 'this' is a nested table reference - the left-most child of
2721
      the tree rooted in 'this',
2722
    else return 'this'
2723
*/
2724
2725
TABLE_LIST *TABLE_LIST::first_leaf_for_name_resolution()
2726
{
2727
  TABLE_LIST *cur_table_ref;
2728
  NESTED_JOIN *cur_nested_join;
2729
2730
  if (is_leaf_for_name_resolution())
2731
    return this;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2732
  assert(nested_join);
1 by brian
clean slate
2733
2734
  for (cur_nested_join= nested_join;
2735
       cur_nested_join;
2736
       cur_nested_join= cur_table_ref->nested_join)
2737
  {
2738
    List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
2739
    cur_table_ref= it++;
2740
    /*
2741
      If the current nested join is a RIGHT JOIN, the operands in
2742
      'join_list' are in reverse order, thus the first operand is
2743
      already at the front of the list. Otherwise the first operand
2744
      is in the end of the list of join operands.
2745
    */
2746
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2747
    {
2748
      TABLE_LIST *next;
2749
      while ((next= it++))
2750
        cur_table_ref= next;
2751
    }
2752
    if (cur_table_ref->is_leaf_for_name_resolution())
2753
      break;
2754
  }
2755
  return cur_table_ref;
2756
}
2757
2758
2759
/*
2760
  Retrieve the last (right-most) leaf in a nested join tree with
2761
  respect to name resolution.
2762
2763
  SYNOPSIS
2764
    TABLE_LIST::last_leaf_for_name_resolution()
2765
2766
  DESCRIPTION
2767
    Given that 'this' is a nested table reference, recursively walk
2768
    down the right-most children of 'this' until we reach a leaf
2769
    table reference with respect to name resolution.
2770
2771
  IMPLEMENTATION
2772
    The right-most child of a nested table reference is the first
2773
    element in the list of children because the children are inserted
2774
    in reverse order.
2775
2776
  RETURN
2777
    - If 'this' is a nested table reference - the right-most child of
2778
      the tree rooted in 'this',
2779
    - else - 'this'
2780
*/
2781
2782
TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
2783
{
2784
  TABLE_LIST *cur_table_ref= this;
2785
  NESTED_JOIN *cur_nested_join;
2786
2787
  if (is_leaf_for_name_resolution())
2788
    return this;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2789
  assert(nested_join);
1 by brian
clean slate
2790
2791
  for (cur_nested_join= nested_join;
2792
       cur_nested_join;
2793
       cur_nested_join= cur_table_ref->nested_join)
2794
  {
2795
    cur_table_ref= cur_nested_join->join_list.head();
2796
    /*
2797
      If the current nested is a RIGHT JOIN, the operands in
2798
      'join_list' are in reverse order, thus the last operand is in the
2799
      end of the list.
2800
    */
2801
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2802
    {
2803
      List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
2804
      TABLE_LIST *next;
2805
      cur_table_ref= it++;
2806
      while ((next= it++))
2807
        cur_table_ref= next;
2808
    }
2809
    if (cur_table_ref->is_leaf_for_name_resolution())
2810
      break;
2811
  }
2812
  return cur_table_ref;
2813
}
2814
2815
2816
Natural_join_column::Natural_join_column(Field_translator *field_param,
2817
                                         TABLE_LIST *tab)
2818
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2819
  assert(tab->field_translation);
1 by brian
clean slate
2820
  view_field= field_param;
2821
  table_field= NULL;
2822
  table_ref= tab;
2823
  is_common= FALSE;
2824
}
2825
2826
2827
Natural_join_column::Natural_join_column(Field *field_param,
2828
                                         TABLE_LIST *tab)
2829
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2830
  assert(tab->table == field_param->table);
1 by brian
clean slate
2831
  table_field= field_param;
2832
  view_field= NULL;
2833
  table_ref= tab;
2834
  is_common= FALSE;
2835
}
2836
2837
2838
const char *Natural_join_column::name()
2839
{
2840
  if (view_field)
2841
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2842
    assert(table_field == NULL);
1 by brian
clean slate
2843
    return view_field->name;
2844
  }
2845
2846
  return table_field->field_name;
2847
}
2848
2849
2850
Item *Natural_join_column::create_item(THD *thd)
2851
{
2852
  if (view_field)
2853
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2854
    assert(table_field == NULL);
1 by brian
clean slate
2855
    return create_view_field(thd, table_ref, &view_field->item,
2856
                             view_field->name);
2857
  }
2858
  return new Item_field(thd, &thd->lex->current_select->context, table_field);
2859
}
2860
2861
2862
Field *Natural_join_column::field()
2863
{
2864
  if (view_field)
2865
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2866
    assert(table_field == NULL);
1 by brian
clean slate
2867
    return NULL;
2868
  }
2869
  return table_field;
2870
}
2871
2872
2873
const char *Natural_join_column::table_name()
2874
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2875
  assert(table_ref);
1 by brian
clean slate
2876
  return table_ref->alias;
2877
}
2878
2879
2880
const char *Natural_join_column::db_name()
2881
{
2882
  /*
2883
    Test that TABLE_LIST::db is the same as st_table_share::db to
2884
    ensure consistency. An exception are I_S schema tables, which
2885
    are inconsistent in this respect.
2886
  */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2887
  assert(!strcmp(table_ref->db,
1 by brian
clean slate
2888
                      table_ref->table->s->db.str) ||
2889
              (table_ref->schema_table &&
2890
               table_ref->table->s->db.str[0] == 0));
2891
  return table_ref->db;
2892
}
2893
2894
2895
void Field_iterator_view::set(TABLE_LIST *table)
2896
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2897
  assert(table->field_translation);
1 by brian
clean slate
2898
  view= table;
2899
  ptr= table->field_translation;
2900
  array_end= table->field_translation_end;
2901
}
2902
2903
2904
const char *Field_iterator_table::name()
2905
{
2906
  return (*ptr)->field_name;
2907
}
2908
2909
2910
Item *Field_iterator_table::create_item(THD *thd)
2911
{
2912
  SELECT_LEX *select= thd->lex->current_select;
2913
2914
  Item_field *item= new Item_field(thd, &select->context, *ptr);
2915
  if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
2916
      !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
2917
  {
2918
    select->non_agg_fields.push_back(item);
2919
    item->marker= select->cur_pos_in_select_list;
2920
  }
2921
  return item;
2922
}
2923
2924
2925
const char *Field_iterator_view::name()
2926
{
2927
  return ptr->name;
2928
}
2929
2930
2931
Item *Field_iterator_view::create_item(THD *thd)
2932
{
2933
  return create_view_field(thd, view, &ptr->item, ptr->name);
2934
}
2935
2936
Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
2937
                        const char *name)
2938
{
2939
  if (view->schema_table_reformed)
2940
  {
2941
    Item *field= *field_ref;
2942
2943
    /*
2944
      Translation table items are always Item_fields and already fixed
2945
      ('mysql_schema_table' function). So we can return directly the
2946
      field. This case happens only for 'show & where' commands.
2947
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2948
    assert(field && field->fixed);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2949
    return(field);
1 by brian
clean slate
2950
  }
2951
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
2952
  return(NULL);
1 by brian
clean slate
2953
}
2954
2955
2956
void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
2957
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2958
  assert(table_ref->join_columns);
1 by brian
clean slate
2959
  column_ref_it.init(*(table_ref->join_columns));
2960
  cur_column_ref= column_ref_it++;
2961
}
2962
2963
2964
void Field_iterator_natural_join::next()
2965
{
2966
  cur_column_ref= column_ref_it++;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2967
  assert(!cur_column_ref || ! cur_column_ref->table_field ||
1 by brian
clean slate
2968
              cur_column_ref->table_ref->table ==
2969
              cur_column_ref->table_field->table);
2970
}
2971
2972
2973
void Field_iterator_table_ref::set_field_iterator()
2974
{
2975
  /*
2976
    If the table reference we are iterating over is a natural join, or it is
2977
    an operand of a natural join, and TABLE_LIST::join_columns contains all
2978
    the columns of the join operand, then we pick the columns from
2979
    TABLE_LIST::join_columns, instead of the  orginial container of the
2980
    columns of the join operator.
2981
  */
2982
  if (table_ref->is_join_columns_complete)
2983
  {
2984
    /* Necesary, but insufficient conditions. */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2985
    assert(table_ref->is_natural_join ||
1 by brian
clean slate
2986
                table_ref->nested_join ||
2987
                table_ref->join_columns &&
2988
                /* This is a merge view. */
2989
                ((table_ref->field_translation &&
2990
                  table_ref->join_columns->elements ==
2991
                  (ulong)(table_ref->field_translation_end -
2992
                          table_ref->field_translation)) ||
2993
                 /* This is stored table or a tmptable view. */
2994
                 (!table_ref->field_translation &&
2995
                  table_ref->join_columns->elements ==
2996
                  table_ref->table->s->fields)));
2997
    field_it= &natural_join_it;
2998
  }
2999
  /* This is a base table or stored view. */
3000
  else
3001
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3002
    assert(table_ref->table);
1 by brian
clean slate
3003
    field_it= &table_field_it;
3004
  }
3005
  field_it->set(table_ref);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3006
  return;
1 by brian
clean slate
3007
}
3008
3009
3010
void Field_iterator_table_ref::set(TABLE_LIST *table)
3011
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3012
  assert(table);
1 by brian
clean slate
3013
  first_leaf= table->first_leaf_for_name_resolution();
3014
  last_leaf=  table->last_leaf_for_name_resolution();
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3015
  assert(first_leaf && last_leaf);
1 by brian
clean slate
3016
  table_ref= first_leaf;
3017
  set_field_iterator();
3018
}
3019
3020
3021
void Field_iterator_table_ref::next()
3022
{
3023
  /* Move to the next field in the current table reference. */
3024
  field_it->next();
3025
  /*
3026
    If all fields of the current table reference are exhausted, move to
3027
    the next leaf table reference.
3028
  */
3029
  if (field_it->end_of_fields() && table_ref != last_leaf)
3030
  {
3031
    table_ref= table_ref->next_name_resolution_table;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3032
    assert(table_ref);
1 by brian
clean slate
3033
    set_field_iterator();
3034
  }
3035
}
3036
3037
3038
const char *Field_iterator_table_ref::table_name()
3039
{
3040
  if (table_ref->is_natural_join)
3041
    return natural_join_it.column_ref()->table_name();
3042
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3043
  assert(!strcmp(table_ref->table_name,
1 by brian
clean slate
3044
                      table_ref->table->s->table_name.str));
3045
  return table_ref->table_name;
3046
}
3047
3048
3049
const char *Field_iterator_table_ref::db_name()
3050
{
3051
  if (table_ref->is_natural_join)
3052
    return natural_join_it.column_ref()->db_name();
3053
3054
  /*
3055
    Test that TABLE_LIST::db is the same as st_table_share::db to
3056
    ensure consistency. An exception are I_S schema tables, which
3057
    are inconsistent in this respect.
3058
  */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3059
  assert(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
1 by brian
clean slate
3060
              (table_ref->schema_table &&
3061
               table_ref->table->s->db.str[0] == 0));
3062
3063
  return table_ref->db;
3064
}
3065
3066
3067
/*
3068
  Create new or return existing column reference to a column of a
3069
  natural/using join.
3070
3071
  SYNOPSIS
3072
    Field_iterator_table_ref::get_or_create_column_ref()
3073
    parent_table_ref  the parent table reference over which the
3074
                      iterator is iterating
3075
3076
  DESCRIPTION
3077
    Create a new natural join column for the current field of the
3078
    iterator if no such column was created, or return an already
3079
    created natural join column. The former happens for base tables or
3080
    views, and the latter for natural/using joins. If a new field is
3081
    created, then the field is added to 'parent_table_ref' if it is
3082
    given, or to the original table referene of the field if
3083
    parent_table_ref == NULL.
3084
3085
  NOTES
3086
    This method is designed so that when a Field_iterator_table_ref
3087
    walks through the fields of a table reference, all its fields
3088
    are created and stored as follows:
3089
    - If the table reference being iterated is a stored table, view or
3090
      natural/using join, store all natural join columns in a list
3091
      attached to that table reference.
3092
    - If the table reference being iterated is a nested join that is
3093
      not natural/using join, then do not materialize its result
3094
      fields. This is OK because for such table references
3095
      Field_iterator_table_ref iterates over the fields of the nested
3096
      table references (recursively). In this way we avoid the storage
3097
      of unnecessay copies of result columns of nested joins.
3098
3099
  RETURN
3100
    #     Pointer to a column of a natural join (or its operand)
3101
    NULL  No memory to allocate the column
3102
*/
3103
3104
Natural_join_column *
3105
Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
3106
{
3107
  Natural_join_column *nj_col;
3108
  bool is_created= TRUE;
3109
  uint field_count;
3110
  TABLE_LIST *add_table_ref= parent_table_ref ?
3111
                             parent_table_ref : table_ref;
3112
3113
  if (field_it == &table_field_it)
3114
  {
3115
    /* The field belongs to a stored table. */
3116
    Field *tmp_field= table_field_it.field();
3117
    nj_col= new Natural_join_column(tmp_field, table_ref);
3118
    field_count= table_ref->table->s->fields;
3119
  }
3120
  else if (field_it == &view_field_it)
3121
  {
3122
    /* The field belongs to a merge view or information schema table. */
3123
    Field_translator *translated_field= view_field_it.field_translator();
3124
    nj_col= new Natural_join_column(translated_field, table_ref);
3125
    field_count= table_ref->field_translation_end -
3126
                 table_ref->field_translation;
3127
  }
3128
  else
3129
  {
3130
    /*
3131
      The field belongs to a NATURAL join, therefore the column reference was
3132
      already created via one of the two constructor calls above. In this case
3133
      we just return the already created column reference.
3134
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3135
    assert(table_ref->is_join_columns_complete);
1 by brian
clean slate
3136
    is_created= FALSE;
3137
    nj_col= natural_join_it.column_ref();
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3138
    assert(nj_col);
1 by brian
clean slate
3139
  }
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3140
  assert(!nj_col->table_field ||
1 by brian
clean slate
3141
              nj_col->table_ref->table == nj_col->table_field->table);
3142
3143
  /*
3144
    If the natural join column was just created add it to the list of
3145
    natural join columns of either 'parent_table_ref' or to the table
3146
    reference that directly contains the original field.
3147
  */
3148
  if (is_created)
3149
  {
3150
    /* Make sure not all columns were materialized. */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3151
    assert(!add_table_ref->is_join_columns_complete);
1 by brian
clean slate
3152
    if (!add_table_ref->join_columns)
3153
    {
3154
      /* Create a list of natural join columns on demand. */
3155
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
3156
        return NULL;
3157
      add_table_ref->is_join_columns_complete= FALSE;
3158
    }
3159
    add_table_ref->join_columns->push_back(nj_col);
3160
    /*
3161
      If new fields are added to their original table reference, mark if
3162
      all fields were added. We do it here as the caller has no easy way
3163
      of knowing when to do it.
3164
      If the fields are being added to parent_table_ref, then the caller
3165
      must take care to mark when all fields are created/added.
3166
    */
3167
    if (!parent_table_ref &&
3168
        add_table_ref->join_columns->elements == field_count)
3169
      add_table_ref->is_join_columns_complete= TRUE;
3170
  }
3171
3172
  return nj_col;
3173
}
3174
3175
3176
/*
3177
  Return an existing reference to a column of a natural/using join.
3178
3179
  SYNOPSIS
3180
    Field_iterator_table_ref::get_natural_column_ref()
3181
3182
  DESCRIPTION
3183
    The method should be called in contexts where it is expected that
3184
    all natural join columns are already created, and that the column
3185
    being retrieved is a Natural_join_column.
3186
3187
  RETURN
3188
    #     Pointer to a column of a natural join (or its operand)
3189
    NULL  No memory to allocate the column
3190
*/
3191
3192
Natural_join_column *
3193
Field_iterator_table_ref::get_natural_column_ref()
3194
{
3195
  Natural_join_column *nj_col;
3196
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3197
  assert(field_it == &natural_join_it);
1 by brian
clean slate
3198
  /*
3199
    The field belongs to a NATURAL join, therefore the column reference was
3200
    already created via one of the two constructor calls above. In this case
3201
    we just return the already created column reference.
3202
  */
3203
  nj_col= natural_join_it.column_ref();
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3204
  assert(nj_col &&
1 by brian
clean slate
3205
              (!nj_col->table_field ||
3206
               nj_col->table_ref->table == nj_col->table_field->table));
3207
  return nj_col;
3208
}
3209
3210
/*****************************************************************************
3211
  Functions to handle column usage bitmaps (read_set, write_set etc...)
3212
*****************************************************************************/
3213
3214
/* Reset all columns bitmaps */
3215
3216
void st_table::clear_column_bitmaps()
3217
{
3218
  /*
3219
    Reset column read/write usage. It's identical to:
3220
    bitmap_clear_all(&table->def_read_set);
3221
    bitmap_clear_all(&table->def_write_set);
3222
  */
3223
  bzero((char*) def_read_set.bitmap, s->column_bitmap_size*2);
3224
  column_bitmaps_set(&def_read_set, &def_write_set);
3225
}
3226
3227
3228
/*
3229
  Tell handler we are going to call position() and rnd_pos() later.
3230
  
3231
  NOTES:
3232
  This is needed for handlers that uses the primary key to find the
3233
  row. In this case we have to extend the read bitmap with the primary
3234
  key fields.
3235
*/
3236
3237
void st_table::prepare_for_position()
3238
{
3239
3240
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
3241
      s->primary_key < MAX_KEY)
3242
  {
3243
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3244
    /* signal change */
3245
    file->column_bitmaps_signal();
3246
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3247
  return;
1 by brian
clean slate
3248
}
3249
3250
3251
/*
3252
  Mark that only fields from one key is used
3253
3254
  NOTE:
3255
    This changes the bitmap to use the tmp bitmap
3256
    After this, you can't access any other columns in the table until
3257
    bitmaps are reset, for example with st_table::clear_column_bitmaps()
3258
    or st_table::restore_column_maps_after_mark_index()
3259
*/
3260
3261
void st_table::mark_columns_used_by_index(uint index)
3262
{
3263
  MY_BITMAP *bitmap= &tmp_set;
3264
3265
  (void) file->extra(HA_EXTRA_KEYREAD);
3266
  bitmap_clear_all(bitmap);
3267
  mark_columns_used_by_index_no_reset(index, bitmap);
3268
  column_bitmaps_set(bitmap, bitmap);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3269
  return;
1 by brian
clean slate
3270
}
3271
3272
3273
/*
3274
  Restore to use normal column maps after key read
3275
3276
  NOTES
3277
    This reverse the change done by mark_columns_used_by_index
3278
3279
  WARNING
3280
    For this to work, one must have the normal table maps in place
3281
    when calling mark_columns_used_by_index
3282
*/
3283
3284
void st_table::restore_column_maps_after_mark_index()
3285
{
3286
3287
  key_read= 0;
3288
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
3289
  default_column_bitmaps();
3290
  file->column_bitmaps_signal();
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3291
  return;
1 by brian
clean slate
3292
}
3293
3294
3295
/*
3296
  mark columns used by key, but don't reset other fields
3297
*/
3298
3299
void st_table::mark_columns_used_by_index_no_reset(uint index,
3300
                                                   MY_BITMAP *bitmap)
3301
{
3302
  KEY_PART_INFO *key_part= key_info[index].key_part;
3303
  KEY_PART_INFO *key_part_end= (key_part +
3304
                                key_info[index].key_parts);
3305
  for (;key_part != key_part_end; key_part++)
3306
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
3307
}
3308
3309
3310
/*
3311
  Mark auto-increment fields as used fields in both read and write maps
3312
3313
  NOTES
3314
    This is needed in insert & update as the auto-increment field is
3315
    always set and sometimes read.
3316
*/
3317
3318
void st_table::mark_auto_increment_column()
3319
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
3320
  assert(found_next_number_field);
1 by brian
clean slate
3321
  /*
3322
    We must set bit in read set as update_auto_increment() is using the
3323
    store() to check overflow of auto_increment values
3324
  */
3325
  bitmap_set_bit(read_set, found_next_number_field->field_index);
3326
  bitmap_set_bit(write_set, found_next_number_field->field_index);
3327
  if (s->next_number_keypart)
3328
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
3329
  file->column_bitmaps_signal();
3330
}
3331
3332
3333
/*
3334
  Mark columns needed for doing an delete of a row
3335
3336
  DESCRIPTON
3337
    Some table engines don't have a cursor on the retrieve rows
3338
    so they need either to use the primary key or all columns to
3339
    be able to delete a row.
3340
3341
    If the engine needs this, the function works as follows:
3342
    - If primary key exits, mark the primary key columns to be read.
3343
    - If not, mark all columns to be read
3344
3345
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
3346
    mark all key columns as 'to-be-read'. This allows the engine to
3347
    loop over the given record to find all keys and doesn't have to
3348
    retrieve the row again.
3349
*/
3350
3351
void st_table::mark_columns_needed_for_delete()
3352
{
3353
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
3354
  {
3355
    Field **reg_field;
3356
    for (reg_field= field ; *reg_field ; reg_field++)
3357
    {
3358
      if ((*reg_field)->flags & PART_KEY_FLAG)
3359
        bitmap_set_bit(read_set, (*reg_field)->field_index);
3360
    }
3361
    file->column_bitmaps_signal();
3362
  }
3363
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
3364
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
3365
  {
3366
    /*
3367
      If the handler has no cursor capabilites, or we have row-based
3368
      replication active for the current statement, we have to read
3369
      either the primary key, the hidden primary key or all columns to
3370
      be able to do an delete
3371
    */
3372
    if (s->primary_key == MAX_KEY)
3373
      file->use_hidden_primary_key();
3374
    else
3375
    {
3376
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3377
      file->column_bitmaps_signal();
3378
    }
3379
  }
3380
}
3381
3382
3383
/*
3384
  Mark columns needed for doing an update of a row
3385
3386
  DESCRIPTON
3387
    Some engines needs to have all columns in an update (to be able to
3388
    build a complete row). If this is the case, we mark all not
3389
    updated columns to be read.
3390
3391
    If this is no the case, we do like in the delete case and mark
3392
    if neeed, either the primary key column or all columns to be read.
3393
    (see mark_columns_needed_for_delete() for details)
3394
3395
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
3396
    mark all USED key columns as 'to-be-read'. This allows the engine to
3397
    loop over the given record to find all changed keys and doesn't have to
3398
    retrieve the row again.
3399
*/
3400
3401
void st_table::mark_columns_needed_for_update()
3402
{
3403
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
3404
  {
3405
    /* Mark all used key columns for read */
3406
    Field **reg_field;
3407
    for (reg_field= field ; *reg_field ; reg_field++)
3408
    {
3409
      /* Merge keys is all keys that had a column refered to in the query */
3410
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
3411
        bitmap_set_bit(read_set, (*reg_field)->field_index);
3412
    }
3413
    file->column_bitmaps_signal();
3414
  }
3415
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
3416
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
3417
  {
3418
    /*
3419
      If the handler has no cursor capabilites, or we have row-based
3420
      logging active for the current statement, we have to read either
3421
      the primary key, the hidden primary key or all columns to be
3422
      able to do an update
3423
    */
3424
    if (s->primary_key == MAX_KEY)
3425
      file->use_hidden_primary_key();
3426
    else
3427
    {
3428
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3429
      file->column_bitmaps_signal();
3430
    }
3431
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3432
  return;
1 by brian
clean slate
3433
}
3434
3435
3436
/*
3437
  Mark columns the handler needs for doing an insert
3438
3439
  For now, this is used to mark fields used by the trigger
3440
  as changed.
3441
*/
3442
3443
void st_table::mark_columns_needed_for_insert()
3444
{
3445
  if (found_next_number_field)
3446
    mark_auto_increment_column();
3447
}
3448
3449
/*
3450
  Cleanup this table for re-execution.
3451
3452
  SYNOPSIS
3453
    TABLE_LIST::reinit_before_use()
3454
*/
3455
3456
void TABLE_LIST::reinit_before_use(THD *thd)
3457
{
3458
  /*
3459
    Reset old pointers to TABLEs: they are not valid since the tables
3460
    were closed in the end of previous prepare or execute call.
3461
  */
3462
  table= 0;
3463
  /* Reset is_schema_table_processed value(needed for I_S tables */
3464
  schema_table_state= NOT_PROCESSED;
3465
3466
  TABLE_LIST *embedded; /* The table at the current level of nesting. */
3467
  TABLE_LIST *parent_embedding= this; /* The parent nested table reference. */
3468
  do
3469
  {
3470
    embedded= parent_embedding;
3471
    if (embedded->prep_on_expr)
3472
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
3473
    parent_embedding= embedded->embedding;
3474
  }
3475
  while (parent_embedding &&
3476
         parent_embedding->nested_join->join_list.head() == embedded);
3477
}
3478
3479
/*
3480
  Return subselect that contains the FROM list this table is taken from
3481
3482
  SYNOPSIS
3483
    TABLE_LIST::containing_subselect()
3484
 
3485
  RETURN
3486
    Subselect item for the subquery that contains the FROM list
3487
    this table is taken from if there is any
3488
    0 - otherwise
3489
3490
*/
3491
3492
Item_subselect *TABLE_LIST::containing_subselect()
3493
{    
3494
  return (select_lex ? select_lex->master_unit()->item : 0);
3495
}
3496
3497
/*
3498
  Compiles the tagged hints list and fills up the bitmasks.
3499
3500
  SYNOPSIS
3501
    process_index_hints()
3502
      table         the TABLE to operate on.
3503
3504
  DESCRIPTION
3505
    The parser collects the index hints for each table in a "tagged list" 
3506
    (TABLE_LIST::index_hints). Using the information in this tagged list
3507
    this function sets the members st_table::keys_in_use_for_query, 
3508
    st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
3509
    st_table::force_index and st_table::covering_keys.
3510
3511
    Current implementation of the runtime does not allow mixing FORCE INDEX
3512
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
3513
    (if non-empty) is appended to the USE INDEX list and a flag is set.
3514
3515
    Multiple hints of the same kind are processed so that each clause 
3516
    is applied to what is computed in the previous clause.
3517
    For example:
3518
        USE INDEX (i1) USE INDEX (i2)
3519
    is equivalent to
3520
        USE INDEX (i1,i2)
3521
    and means "consider only i1 and i2".
3522
        
3523
    Similarly
3524
        USE INDEX () USE INDEX (i1)
3525
    is equivalent to
3526
        USE INDEX (i1)
3527
    and means "consider only the index i1"
3528
3529
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
3530
    not an error.
3531
        
3532
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
3533
    order:
3534
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
3535
      2. All IGNORE INDEX
3536
3537
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
3538
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
3539
3540
    As an optimization if there is a covering index, and we have 
3541
    IGNORE INDEX FOR GROUP/ORDER, and this index is used for the JOIN part, 
3542
    then we have to ignore the IGNORE INDEX FROM GROUP/ORDER.
3543
3544
  RETURN VALUE
3545
    FALSE                no errors found
3546
    TRUE                 found and reported an error.
3547
*/
3548
bool TABLE_LIST::process_index_hints(TABLE *tbl)
3549
{
3550
  /* initialize the result variables */
3551
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
3552
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
3553
3554
  /* index hint list processing */
3555
  if (index_hints)
3556
  {
3557
    key_map index_join[INDEX_HINT_FORCE + 1];
3558
    key_map index_order[INDEX_HINT_FORCE + 1];
3559
    key_map index_group[INDEX_HINT_FORCE + 1];
3560
    Index_hint *hint;
3561
    int type;
3562
    bool have_empty_use_join= FALSE, have_empty_use_order= FALSE, 
3563
         have_empty_use_group= FALSE;
3564
    List_iterator <Index_hint> iter(*index_hints);
3565
3566
    /* initialize temporary variables used to collect hints of each kind */
3567
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
3568
    {
3569
      index_join[type].clear_all();
3570
      index_order[type].clear_all();
3571
      index_group[type].clear_all();
3572
    }
3573
3574
    /* iterate over the hints list */
3575
    while ((hint= iter++))
3576
    {
3577
      uint pos;
3578
3579
      /* process empty USE INDEX () */
3580
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
3581
      {
3582
        if (hint->clause & INDEX_HINT_MASK_JOIN)
3583
        {
3584
          index_join[hint->type].clear_all();
3585
          have_empty_use_join= TRUE;
3586
        }
3587
        if (hint->clause & INDEX_HINT_MASK_ORDER)
3588
        {
3589
          index_order[hint->type].clear_all();
3590
          have_empty_use_order= TRUE;
3591
        }
3592
        if (hint->clause & INDEX_HINT_MASK_GROUP)
3593
        {
3594
          index_group[hint->type].clear_all();
3595
          have_empty_use_group= TRUE;
3596
        }
3597
        continue;
3598
      }
3599
3600
      /* 
3601
        Check if an index with the given name exists and get his offset in 
3602
        the keys bitmask for the table 
3603
      */
3604
      if (tbl->s->keynames.type_names == 0 ||
3605
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3606
                          hint->key_name.length, 1)) <= 0)
3607
      {
3608
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
3609
        return 1;
3610
      }
3611
3612
      pos--;
3613
3614
      /* add to the appropriate clause mask */
3615
      if (hint->clause & INDEX_HINT_MASK_JOIN)
3616
        index_join[hint->type].set_bit (pos);
3617
      if (hint->clause & INDEX_HINT_MASK_ORDER)
3618
        index_order[hint->type].set_bit (pos);
3619
      if (hint->clause & INDEX_HINT_MASK_GROUP)
3620
        index_group[hint->type].set_bit (pos);
3621
    }
3622
3623
    /* cannot mix USE INDEX and FORCE INDEX */
3624
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3625
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3626
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
3627
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
3628
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
3629
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
3630
    {
3631
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
3632
               index_hint_type_name[INDEX_HINT_FORCE]);
3633
      return 1;
3634
    }
3635
3636
    /* process FORCE INDEX as USE INDEX with a flag */
3637
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3638
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3639
        !index_group[INDEX_HINT_FORCE].is_clear_all())
3640
    {
3641
      tbl->force_index= TRUE;
3642
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
3643
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
3644
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
3645
    }
3646
3647
    /* apply USE INDEX */
3648
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
3649
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
3650
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
3651
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
3652
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
3653
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
3654
3655
    /* apply IGNORE INDEX */
3656
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
3657
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
3658
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
3659
  }
3660
3661
  /* make sure covering_keys don't include indexes disabled with a hint */
3662
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
3663
  return 0;
3664
}
3665
3666
3667
size_t max_row_length(TABLE *table, const uchar *data)
3668
{
3669
  TABLE_SHARE *table_s= table->s;
3670
  size_t length= table_s->reclength + 2 * table_s->fields;
3671
  uint *const beg= table_s->blob_field;
3672
  uint *const end= beg + table_s->blob_fields;
3673
3674
  for (uint *ptr= beg ; ptr != end ; ++ptr)
3675
  {
3676
    Field_blob* const blob= (Field_blob*) table->field[*ptr];
3677
    length+= blob->get_length((const uchar*)
3678
                              (data + blob->offset(table->record[0]))) +
3679
      HA_KEY_BLOB_LENGTH;
3680
  }
3681
  return length;
3682
}
3683
3684
/*
3685
  Check type of .frm if we are not going to parse it
3686
3687
  SYNOPSIS
3688
  mysql_frm_type()
3689
  path        path to file
3690
3691
  RETURN
3692
  FRMTYPE_ERROR       error                
3693
  FRMTYPE_TABLE       table                
3694
 */    
3695
3696
frm_type_enum mysql_frm_type(THD *thd, char *path, enum legacy_db_type *dbt)
3697
{   
3698
  File file;
3699
  uchar header[10];     /* This should be optimized */
3700
  int error;
3701
3702
  *dbt= DB_TYPE_UNKNOWN;
3703
3704
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3705
    return(FRMTYPE_ERROR);
1 by brian
clean slate
3706
  error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
3707
  my_close(file, MYF(MY_WME));
3708
3709
  if (error)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3710
    return(FRMTYPE_ERROR);
1 by brian
clean slate
3711
3712
  /*  
3713
    This is just a check for DB_TYPE. We'll return default unknown type
3714
    if the following test is true (arg #3). This should not have effect
3715
    on return value from this function (default FRMTYPE_TABLE)
3716
   */  
3717
  if (header[0] != (uchar) 254 || header[1] != 1 ||
3718
      (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
3719
       (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3720
    return(FRMTYPE_TABLE);
1 by brian
clean slate
3721
3722
  *dbt= (enum legacy_db_type) (uint) *(header + 3);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
3723
  return(FRMTYPE_TABLE);                   // Is probably a .frm table
1 by brian
clean slate
3724
}
3725
3726
3727
/*****************************************************************************
3728
** Instansiate templates
3729
*****************************************************************************/
3730
3731
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3732
template class List<String>;
3733
template class List_iterator<String>;
3734
#endif