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