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