~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
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
19
#include <drizzled/server_includes.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
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
22
#include "tmp_table.h"
23
#include "sj_tmp_table.h"
24
1 by brian
clean slate
25
/* INFORMATION_SCHEMA name */
26
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
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
40
/* Get column name from column hash */
41
42
static uchar *get_field_name(Field **buff, size_t *length,
148 by Brian Aker
my_bool cleanup
43
                             bool not_used __attribute__((unused)))
1 by brian
clean slate
44
{
45
  *length= (uint) strlen((*buff)->field_name);
46
  return (uchar*) (*buff)->field_name;
47
}
48
49
50
/*
51
  Returns pointer to '.frm' extension of the file name.
52
53
  SYNOPSIS
54
    fn_rext()
55
    name       file name
56
57
  DESCRIPTION
58
    Checks file name part starting with the rightmost '.' character,
59
    and returns it if it is equal to '.frm'. 
60
61
  TODO
62
    It is a good idea to get rid of this function modifying the code
63
    to garantee that the functions presently calling fn_rext() always
64
    get arguments in the same format: either with '.frm' or without '.frm'.
65
66
  RETURN VALUES
67
    Pointer to the '.frm' extension. If there is no extension,
68
    or extension is not '.frm', pointer at the end of file name.
69
*/
70
71
char *fn_rext(char *name)
72
{
73
  char *res= strrchr(name, '.');
74
  if (res && !strcmp(res, reg_ext))
75
    return res;
76
  return name + strlen(name);
77
}
78
79
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
80
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
81
  assert(db != NULL);
82
  assert(name != NULL);
1 by brian
clean slate
83
84
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
85
      (my_strcasecmp(system_charset_info,
86
                    INFORMATION_SCHEMA_NAME.str,
87
                    db->str) == 0))
88
  {
89
    return TABLE_CATEGORY_INFORMATION;
90
  }
91
92
  return TABLE_CATEGORY_USER;
93
}
94
95
96
/*
97
  Allocate a setup TABLE_SHARE structure
98
99
  SYNOPSIS
100
    alloc_table_share()
327.2.4 by Brian Aker
Refactoring table.h
101
    TableList		Take database and table name from there
1 by brian
clean slate
102
    key			Table cache key (db \0 table_name \0...)
103
    key_length		Length of key
104
105
  RETURN
106
    0  Error (out of memory)
107
    #  Share
108
*/
109
327.2.4 by Brian Aker
Refactoring table.h
110
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
1 by brian
clean slate
111
                               uint key_length)
112
{
113
  MEM_ROOT mem_root;
114
  TABLE_SHARE *share;
115
  char *key_buff, *path_buff;
116
  char path[FN_REFLEN];
117
  uint path_length;
118
119
  path_length= build_table_filename(path, sizeof(path) - 1,
120
                                    table_list->db,
121
                                    table_list->table_name, "", 0);
122
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
123
  if (multi_alloc_root(&mem_root,
124
                       &share, sizeof(*share),
125
                       &key_buff, key_length,
126
                       &path_buff, path_length + 1,
127
                       NULL))
128
  {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
129
    memset(share, 0, sizeof(*share));
1 by brian
clean slate
130
131
    share->set_table_cache_key(key_buff, key, key_length);
132
133
    share->path.str= path_buff;
134
    share->path.length= path_length;
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
135
    stpcpy(share->path.str, path);
1 by brian
clean slate
136
    share->normalized_path.str=    share->path.str;
137
    share->normalized_path.length= path_length;
138
139
    share->version=       refresh_version;
140
141
    /*
142
      This constant is used to mark that no table map version has been
143
      assigned.  No arithmetic is done on the value: it will be
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
144
      overwritten with a value taken from DRIZZLE_BIN_LOG.
1 by brian
clean slate
145
    */
365.2.4 by Monty Taylor
Updated some Long refs to use stdint constants.
146
    share->table_map_version= UINT64_MAX;
1 by brian
clean slate
147
148
    /*
149
      Since alloc_table_share() can be called without any locking (for
150
      example, ha_create_table... functions), we do not assign a table
151
      map id here.  Instead we assign a value that is not used
152
      elsewhere, and then assign a table map id inside open_table()
153
      under the protection of the LOCK_open mutex.
154
    */
365.2.4 by Monty Taylor
Updated some Long refs to use stdint constants.
155
    share->table_map_id= UINT32_MAX;
1 by brian
clean slate
156
    share->cached_row_logging_check= -1;
157
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
158
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
1 by brian
clean slate
159
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
160
    pthread_cond_init(&share->cond, NULL);
161
  }
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
162
  return(share);
1 by brian
clean slate
163
}
164
165
166
/*
167
  Initialize share for temporary tables
168
169
  SYNOPSIS
170
    init_tmp_table_share()
171
    thd         thread handle
172
    share	Share to fill
173
    key		Table_cache_key, as generated from create_table_def_key.
174
		must start with db name.    
175
    key_length	Length of key
176
    table_name	Table name
177
    path	Path to file (possible in lower case) without .frm
178
179
  NOTES
180
    This is different from alloc_table_share() because temporary tables
181
    don't have to be shared between threads or put into the table def
182
    cache, so we can do some things notable simpler and faster
183
184
    If table is not put in thd->temporary_tables (happens only when
185
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
    use key_length= 0 as neither table_cache_key or key_length will be used).
187
*/
188
189
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
190
                          uint key_length, const char *table_name,
191
                          const char *path)
192
{
193
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
194
  memset(share, 0, sizeof(*share));
1 by brian
clean slate
195
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
196
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
197
  share->tmp_table=              INTERNAL_TMP_TABLE;
198
  share->db.str=                 (char*) key;
199
  share->db.length=		 strlen(key);
200
  share->table_cache_key.str=    (char*) key;
201
  share->table_cache_key.length= key_length;
202
  share->table_name.str=         (char*) table_name;
203
  share->table_name.length=      strlen(table_name);
204
  share->path.str=               (char*) path;
205
  share->normalized_path.str=    (char*) path;
206
  share->path.length= share->normalized_path.length= strlen(path);
207
  share->frm_version= 		 FRM_VER_TRUE_VARCHAR;
208
  /*
209
    Temporary tables are not replicated, but we set up these fields
210
    anyway to be able to catch errors.
211
   */
212
  share->table_map_version= ~(uint64_t)0;
213
  share->cached_row_logging_check= -1;
214
215
  /*
216
    table_map_id is also used for MERGE tables to suppress repeated
217
    compatibility checks.
218
  */
219
  share->table_map_id= (ulong) thd->query_id;
220
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
221
  return;
1 by brian
clean slate
222
}
223
224
225
/*
226
  Free table share and memory used by it
227
228
  SYNOPSIS
229
    free_table_share()
230
    share		Table share
231
232
  NOTES
233
    share->mutex must be locked when we come here if it's not a temp table
234
*/
235
236
void free_table_share(TABLE_SHARE *share)
237
{
238
  MEM_ROOT mem_root;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
239
  assert(share->ref_count == 0);
1 by brian
clean slate
240
241
  /*
242
    If someone is waiting for this to be deleted, inform it about this.
243
    Don't do a delete until we know that no one is refering to this anymore.
244
  */
245
  if (share->tmp_table == NO_TMP_TABLE)
246
  {
247
    /* share->mutex is locked in release_table_share() */
248
    while (share->waiting_on_cond)
249
    {
250
      pthread_cond_broadcast(&share->cond);
251
      pthread_cond_wait(&share->cond, &share->mutex);
252
    }
253
    /* No thread refers to this anymore */
254
    pthread_mutex_unlock(&share->mutex);
255
    pthread_mutex_destroy(&share->mutex);
256
    pthread_cond_destroy(&share->cond);
257
  }
258
  hash_free(&share->name_hash);
259
  
260
  plugin_unlock(NULL, share->db_plugin);
261
  share->db_plugin= NULL;
262
263
  /* We must copy mem_root from share because share is allocated through it */
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
264
  memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
1 by brian
clean slate
265
  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
266
  return;
1 by brian
clean slate
267
}
268
269
/*
270
  Read table definition from a binary / text based .frm file
271
  
272
  SYNOPSIS
273
  open_table_def()
274
  thd		Thread handler
275
  share		Fill this with table definition
276
  db_flags	Bit mask of the following flags: OPEN_VIEW
277
278
  NOTES
279
    This function is called when the table definition is not cached in
280
    table_def_cache
281
    The data is returned in 'share', which is alloced by
282
    alloc_table_share().. The code assumes that share is initialized.
283
284
  RETURN VALUES
285
   0	ok
286
   1	Error (see open_table_error)
287
   2    Error (see open_table_error)
288
   3    Wrong data in .frm file
289
   4    Error (see open_table_error)
290
   5    Error (see open_table_error: charset unavailable)
291
   6    Unknown .frm version
292
*/
293
327.1.9 by Brian Aker
Remove dead function merge_on_conds
294
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags  __attribute__((unused)))
1 by brian
clean slate
295
{
296
  int error, table_type;
297
  bool error_given;
298
  File file;
299
  uchar head[64], *disk_buff;
300
  char	path[FN_REFLEN];
301
  MEM_ROOT **root_ptr, *old_root;
302
303
  error= 1;
304
  error_given= 0;
305
  disk_buff= NULL;
306
307
  strxmov(path, share->normalized_path.str, reg_ext, NullS);
308
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
309
  {
310
    /*
311
      We don't try to open 5.0 unencoded name, if
312
      - non-encoded name contains '@' signs, 
313
        because '@' can be misinterpreted.
314
        It is not clear if '@' is escape character in 5.1,
315
        or a normal character in 5.0.
316
        
317
      - non-encoded db or table name contain "#mysql50#" prefix.
318
        This kind of tables must have been opened only by the
319
        my_open() above.
320
    */
321
    if (strchr(share->table_name.str, '@') ||
322
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
323
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
324
        !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
325
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
326
      goto err_not_open;
327
328
    /* Try unencoded 5.0 name */
329
    uint length;
330
    strxnmov(path, sizeof(path)-1,
331
             mysql_data_home, "/", share->db.str, "/",
332
             share->table_name.str, reg_ext, NullS);
333
    length= unpack_filename(path, path) - reg_ext_length;
334
    /*
335
      The following is a safety test and should never fail
336
      as the old file name should never be longer than the new one.
337
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
338
    assert(length <= share->normalized_path.length);
1 by brian
clean slate
339
    /*
340
      If the old and the new names have the same length,
341
      then table name does not have tricky characters,
342
      so no need to check the old file name.
343
    */
344
    if (length == share->normalized_path.length ||
345
        ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
346
      goto err_not_open;
347
348
    /* Unencoded 5.0 table name found */
349
    path[length]= '\0'; // Remove .frm extension
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
350
    stpcpy(share->normalized_path.str, path);
1 by brian
clean slate
351
    share->normalized_path.length= length;
352
  }
353
354
  error= 4;
355
  if (my_read(file, head, 64, MYF(MY_NABP)))
356
    goto err;
357
358
  if (head[0] == (uchar) 254 && head[1] == 1)
359
  {
360
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
361
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
362
    {
363
      table_type= 1;
364
    }
365
    else
366
    {
367
      error= 6;                                 // Unkown .frm version
368
      goto err;
369
    }
370
  }
371
  else
372
    goto err;
373
374
  /* No handling of text based files yet */
375
  if (table_type == 1)
376
  {
4 by Brian Aker
Remove my_pthread_getspecific_ptr()
377
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
1 by brian
clean slate
378
    old_root= *root_ptr;
379
    *root_ptr= &share->mem_root;
380
    error= open_binary_frm(thd, share, head, file);
381
    *root_ptr= old_root;
382
    error_given= 1;
383
  }
81 by Brian Aker
Small cleanups
384
  else
385
    assert(1);
1 by brian
clean slate
386
387
  share->table_category= get_table_category(& share->db, & share->table_name);
388
389
  if (!error)
390
    thd->status_var.opened_shares++;
391
392
err:
393
  my_close(file, MYF(MY_WME));
394
395
err_not_open:
396
  if (error && !error_given)
397
  {
398
    share->error= error;
399
    open_table_error(share, error, (share->open_errno= my_errno), 0);
400
  }
401
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
402
  return(error);
1 by brian
clean slate
403
}
404
405
406
/*
407
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
408
*/
409
410
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
411
                           File file)
412
{
413
  int error, errarg= 0;
414
  uint new_frm_ver, field_pack_length, new_field_pack_flag;
415
  uint interval_count, interval_parts, read_length, int_length;
416
  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)
417
  uint key_info_length, com_length, null_bit_pos=0;
1 by brian
clean slate
418
  uint extra_rec_buf_length;
419
  uint i,j;
420
  bool use_hash;
421
  uchar forminfo[288];
422
  char *keynames, *names, *comment_pos;
423
  uchar *record;
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
424
  uchar *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
1 by brian
clean slate
425
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
  handler *handler_file= 0;
427
  KEY	*keyinfo;
428
  KEY_PART_INFO *key_part;
429
  Field  **field_ptr, *reg_field;
430
  const char **interval_array;
431
  enum legacy_db_type legacy_db_type;
432
  my_bitmap_map *bitmaps;
433
  uchar *buff= 0;
434
  uchar *field_extra_info= 0;
435
436
  new_field_pack_flag= head[27];
437
  new_frm_ver= (head[2] - FRM_VER);
438
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
439
  disk_buff= 0;
440
441
  error= 3;
442
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
443
    goto err;                                   /* purecov: inspected */
444
  VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
445
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
446
    goto err;
447
448
  share->frm_version= head[2];
449
  /*
450
    Check if .frm file created by MySQL 5.0. In this case we want to
451
    display CHAR fields as CHAR and not as VARCHAR.
452
    We do it this way as we want to keep the old frm version to enable
453
    MySQL 4.1 to read these files.
454
  */
455
  if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
456
    share->frm_version= FRM_VER_TRUE_VARCHAR;
457
81 by Brian Aker
Small cleanups
458
  legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
459
  assert(share->db_plugin == NULL);
1 by brian
clean slate
460
  /*
461
    if the storage engine is dynamic, no point in resolving it by its
462
    dynamically allocated legacy_db_type. We will resolve it later by name.
463
  */
464
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
465
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
466
    share->db_plugin= ha_lock_engine(NULL, 
467
                                     ha_checktype(thd, legacy_db_type, 0, 0));
468
  share->db_create_options= db_create_options= uint2korr(head+30);
469
  share->db_options_in_use= share->db_create_options;
470
  share->mysql_version= uint4korr(head+51);
471
  share->null_field_first= 0;
472
  if (!head[32])				// New frm file in 3.23
473
  {
474
    share->avg_row_length= uint4korr(head+34);
475
    share->transactional= (ha_choice) (head[39] & 3);
476
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
477
    share->row_type= (row_type) head[40];
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
478
    share->block_size= uint4korr(head+43);
1 by brian
clean slate
479
    share->table_charset= get_charset((uint) head[38],MYF(0));
480
    share->null_field_first= 1;
481
  }
482
  if (!share->table_charset)
483
  {
484
    /* unknown charset in head[38] or pre-3.23 frm */
485
    if (use_mb(default_charset_info))
486
    {
487
      /* Warn that we may be changing the size of character columns */
261.3.7 by Monty Taylor
Made the ER() macro always gettext the return value.
488
      sql_print_warning(_("'%s' had no or invalid character set, "
1 by brian
clean slate
489
                        "and default character set is multi-byte, "
261.3.7 by Monty Taylor
Made the ER() macro always gettext the return value.
490
                        "so character column sizes may have changed"),
1 by brian
clean slate
491
                        share->path.str);
492
    }
493
    share->table_charset= default_charset_info;
494
  }
495
  share->db_record_offset= 1;
496
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
497
    share->blob_ptr_size= portable_sizeof_char_ptr;
498
  /* Set temporarily a good value for db_low_byte_first */
409 by Brian Aker
First pass to dump legacy types (wow! this has been a long time coming)
499
  share->db_low_byte_first= true;
1 by brian
clean slate
500
  error=4;
501
  share->max_rows= uint4korr(head+18);
502
  share->min_rows= uint4korr(head+22);
503
504
  /* Read keyinformation */
505
  key_info_length= (uint) uint2korr(head+28);
506
  VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
507
  if (read_string(file,(uchar**) &disk_buff,key_info_length))
508
    goto err;                                   /* purecov: inspected */
509
  if (disk_buff[0] & 0x80)
510
  {
511
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
512
    share->key_parts= key_parts= uint2korr(disk_buff+2);
513
  }
514
  else
515
  {
516
    share->keys=      keys=      disk_buff[0];
517
    share->key_parts= key_parts= disk_buff[1];
518
  }
519
  share->keys_for_keyread.init(0);
520
  share->keys_in_use.init(keys);
521
522
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
523
  if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
524
				    n_length + uint2korr(disk_buff+4))))
525
    goto err;                                   /* purecov: inspected */
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
526
  memset(keyinfo, 0, n_length);
1 by brian
clean slate
527
  share->key_info= keyinfo;
528
  key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
529
  strpos=disk_buff+6;
530
531
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
532
					 sizeof(ulong*)*key_parts)))
533
    goto err;
534
535
  for (i=0 ; i < keys ; i++, keyinfo++)
536
  {
537
    keyinfo->table= 0;                           // Updated in open_frm
538
    if (new_frm_ver >= 3)
539
    {
540
      keyinfo->flags=	   (uint) uint2korr(strpos) ^ HA_NOSAME;
541
      keyinfo->key_length= (uint) uint2korr(strpos+2);
542
      keyinfo->key_parts=  (uint) strpos[4];
543
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
544
      keyinfo->block_size= uint2korr(strpos+6);
545
      strpos+=8;
546
    }
547
548
    keyinfo->key_part=	 key_part;
549
    keyinfo->rec_per_key= rec_per_key;
550
    for (j=keyinfo->key_parts ; j-- ; key_part++)
551
    {
552
      *rec_per_key++=0;
206 by Brian Aker
Removed final uint dead types.
553
      key_part->fieldnr=	(uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
1 by brian
clean slate
554
      key_part->offset= (uint) uint2korr(strpos+2)-1;
555
      key_part->key_type=	(uint) uint2korr(strpos+5);
556
      // key_part->field=	(Field*) 0;	// Will be fixed later
557
      if (new_frm_ver >= 1)
558
      {
559
	key_part->key_part_flag= *(strpos+4);
560
	key_part->length=	(uint) uint2korr(strpos+7);
561
	strpos+=9;
562
      }
563
      else
564
      {
565
	key_part->length=	*(strpos+4);
566
	key_part->key_part_flag=0;
567
	if (key_part->length > 128)
568
	{
569
	  key_part->length&=127;		/* purecov: inspected */
570
	  key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
571
	}
572
	strpos+=7;
573
      }
574
      key_part->store_length=key_part->length;
575
    }
576
  }
577
  keynames=(char*) key_part;
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
578
  strpos+= (stpcpy(keynames, (char *) strpos) - keynames)+1;
1 by brian
clean slate
579
580
  //reading index comments
581
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
582
  {
583
    if (keyinfo->flags & HA_USES_COMMENT)
584
    {
585
      keyinfo->comment.length= uint2korr(strpos);
586
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
587
                                         keyinfo->comment.length);
588
      strpos+= 2 + keyinfo->comment.length;
589
    } 
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
590
    assert(test(keyinfo->flags & HA_USES_COMMENT) == 
1 by brian
clean slate
591
               (keyinfo->comment.length > 0));
592
  }
593
594
  share->reclength = uint2korr((head+16));
595
596
  record_offset= (ulong) (uint2korr(head+6)+
597
                          ((uint2korr(head+14) == 0xffff ?
598
                            uint4korr(head+47) : uint2korr(head+14))));
599
 
600
  if ((n_length= uint4korr(head+55)))
601
  {
602
    /* Read extra data segment */
603
    uchar *next_chunk, *buff_end;
604
    if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
605
      goto err;
31 by Brian Aker
Removed my versions of pread/pwrite from the Kernel
606
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
1 by brian
clean slate
607
    {
608
      goto err;
609
    }
610
    share->connect_string.length= uint2korr(buff);
611
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
612
                                                  (char*) next_chunk + 2,
613
                                                  share->connect_string.
614
                                                  length)))
615
    {
616
      goto err;
617
    }
618
    next_chunk+= share->connect_string.length + 2;
619
    buff_end= buff + n_length;
620
    if (next_chunk + 2 < buff_end)
621
    {
622
      uint str_db_type_length= uint2korr(next_chunk);
623
      LEX_STRING name;
624
      name.str= (char*) next_chunk + 2;
625
      name.length= str_db_type_length;
626
627
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
628
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
629
      {
630
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
631
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
632
            legacy_db_type != ha_legacy_type(
633
                plugin_data(tmp_plugin, handlerton *)))
634
        {
635
          /* bad file, legacy_db_type did not match the name */
636
          my_free(buff, MYF(0));
637
          goto err;
638
        }
639
        /*
640
          tmp_plugin is locked with a local lock.
641
          we unlock the old value of share->db_plugin before
642
          replacing it with a globally locked version of tmp_plugin
643
        */
644
        plugin_unlock(NULL, share->db_plugin);
645
        share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
646
      }
647
      else if (!tmp_plugin)
648
      {
649
        /* purecov: begin inspected */
650
        error= 8;
651
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
652
        my_free(buff, MYF(0));
653
        goto err;
654
        /* purecov: end */
655
      }
656
      next_chunk+= str_db_type_length + 2;
657
    }
658
    if (share->mysql_version >= 50110)
659
    {
660
      /* New auto_partitioned indicator introduced in 5.1.11 */
661
      next_chunk++;
662
    }
663
    if (forminfo[46] == (uchar)255)
664
    {
665
      //reading long table comment
666
      if (next_chunk + 2 > buff_end)
667
      {
668
          my_free(buff, MYF(0));
669
          goto err;
670
      }
671
      share->comment.length = uint2korr(next_chunk);
672
      if (! (share->comment.str= strmake_root(&share->mem_root,
673
                               (char*)next_chunk + 2, share->comment.length)))
674
      {
675
          my_free(buff, MYF(0));
676
          goto err;
677
      }
678
      next_chunk+= 2 + share->comment.length;
679
    }
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
680
    assert(next_chunk <= buff_end);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
681
    if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
1 by brian
clean slate
682
    {
683
      /*
684
       New frm format in mysql_version 5.2.5 (originally in
685
       mysql-5.1.22-ndb-6.2.5)
686
       New column properties added:
687
       COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
688
       TABLESPACE name is now stored in frm
689
      */
690
      if (next_chunk >= buff_end)
691
      {
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
692
        if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
1 by brian
clean slate
693
        {
694
          goto err;
695
        }
696
      }
697
      else
698
      {
699
        const uint format_section_header_size= 8;
700
        uint format_section_len= uint2korr(next_chunk+0);
701
106 by Brian Aker
Tablespace removal.
702
        field_extra_info= next_chunk + format_section_header_size + 1;
1 by brian
clean slate
703
        next_chunk+= format_section_len;
704
      }
705
    }
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
706
    assert (next_chunk <= buff_end);
1 by brian
clean slate
707
    if (next_chunk > buff_end)
708
    {
709
      goto err;
710
    }
711
  }
712
  share->key_block_size= uint2korr(head+62);
713
714
  error=4;
715
  extra_rec_buf_length= uint2korr(head+59);
716
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
717
  share->rec_buff_length= rec_buff_length;
718
  if (!(record= (uchar *) alloc_root(&share->mem_root,
719
                                     rec_buff_length)))
720
    goto err;                                   /* purecov: inspected */
721
  share->default_values= record;
31 by Brian Aker
Removed my versions of pread/pwrite from the Kernel
722
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
1 by brian
clean slate
723
    goto err;                                   /* purecov: inspected */
724
725
  VOID(my_seek(file,pos+288,MY_SEEK_SET,MYF(0)));
726
727
  share->fields= uint2korr(forminfo+258);
728
  pos= uint2korr(forminfo+260);			/* Length of all screens */
729
  n_length= uint2korr(forminfo+268);
730
  interval_count= uint2korr(forminfo+270);
731
  interval_parts= uint2korr(forminfo+272);
732
  int_length= uint2korr(forminfo+274);
733
  share->null_fields= uint2korr(forminfo+282);
734
  com_length= uint2korr(forminfo+284);
735
  if (forminfo[46] != (uchar)255)
736
  {
737
    share->comment.length=  (int) (forminfo[46]);
738
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
                                     share->comment.length);
740
  }
741
742
743
  if (!(field_ptr = (Field **)
744
	alloc_root(&share->mem_root,
745
		   (uint) ((share->fields+1)*sizeof(Field*)+
746
			   interval_count*sizeof(TYPELIB)+
747
			   (share->fields+interval_parts+
748
			    keys+3)*sizeof(char *)+
749
			   (n_length+int_length+com_length)))))
750
    goto err;                                   /* purecov: inspected */
751
752
  share->field= field_ptr;
753
  read_length=(uint) (share->fields * field_pack_length +
754
		      pos+ (uint) (n_length+int_length+com_length));
755
  if (read_string(file,(uchar**) &disk_buff,read_length))
756
    goto err;                                   /* purecov: inspected */
757
  strpos= disk_buff+pos;
758
759
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
760
  interval_array= (const char **) (share->intervals+interval_count);
761
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
762
  if (!interval_count)
763
    share->intervals= 0;			// For better debugging
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
764
  memcpy(names, strpos+(share->fields*field_pack_length),
1 by brian
clean slate
765
	 (uint) (n_length+int_length));
766
  comment_pos= names+(n_length+int_length);
767
  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
768
769
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
770
  if (share->fieldnames.count != share->fields)
771
    goto err;
772
  fix_type_pointers(&interval_array, share->intervals, interval_count,
773
		    &names);
774
775
  {
776
    /* Set ENUM and SET lengths */
777
    TYPELIB *interval;
778
    for (interval= share->intervals;
779
         interval < share->intervals + interval_count;
780
         interval++)
781
    {
782
      uint count= (uint) (interval->count + 1) * sizeof(uint);
783
      if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
784
                                                        count)))
785
        goto err;
786
      for (count= 0; count < interval->count; count++)
787
      {
788
        char *val= (char*) interval->type_names[count];
789
        interval->type_lengths[count]= strlen(val);
790
      }
791
      interval->type_lengths[count]= 0;
792
    }
793
  }
794
795
  if (keynames)
796
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
797
798
 /* Allocate handler */
799
  if (!(handler_file= get_new_handler(share, thd->mem_root,
800
                                      share->db_type())))
801
    goto err;
802
803
  record= share->default_values-1;              /* Fieldstart = 1 */
804
  if (share->null_field_first)
805
  {
806
    null_flags= null_pos= (uchar*) record+1;
807
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
808
    /*
809
      null_bytes below is only correct under the condition that
810
      there are no bit fields.  Correct values is set below after the
811
      table struct is initialized
812
    */
813
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
814
  }
815
816
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
817
  if (use_hash)
818
    use_hash= !hash_init(&share->name_hash,
819
			 system_charset_info,
820
			 share->fields,0,0,
821
			 (hash_get_key) get_field_name,0,0);
822
823
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
824
  {
825
    uint pack_flag, interval_nr, unireg_type, recpos, field_length;
826
    enum_field_types field_type;
827
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
828
    const CHARSET_INFO *charset= NULL;
1 by brian
clean slate
829
    LEX_STRING comment;
830
831
    if (field_extra_info)
832
    {
833
      char tmp= field_extra_info[i];
834
      column_format= (enum column_format_type)
835
                    ((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
836
    }
837
    if (new_frm_ver >= 3)
838
    {
839
      /* new frm file in 4.1 */
840
      field_length= uint2korr(strpos+3);
841
      recpos=	    uint3korr(strpos+5);
842
      pack_flag=    uint2korr(strpos+8);
843
      unireg_type=  (uint) strpos[10];
844
      interval_nr=  (uint) strpos[12];
845
      uint comment_length=uint2korr(strpos+15);
846
      field_type=(enum_field_types) (uint) strpos[13];
847
848
      {
849
        if (!strpos[14])
850
          charset= &my_charset_bin;
851
        else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
852
        {
853
          error= 5; // Unknown or unavailable charset
854
          errarg= (int) strpos[14];
855
          goto err;
856
        }
857
      }
858
      if (!comment_length)
859
      {
860
	comment.str= (char*) "";
861
	comment.length=0;
862
      }
863
      else
864
      {
865
	comment.str=    (char*) comment_pos;
866
	comment.length= comment_length;
867
	comment_pos+=   comment_length;
868
      }
869
    }
870
    else
871
    {
872
      field_length= (uint) strpos[3];
873
      recpos=	    uint2korr(strpos+4),
874
      pack_flag=    uint2korr(strpos+6);
875
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
876
      unireg_type=  (uint) strpos[8];
877
      interval_nr=  (uint) strpos[10];
878
879
      /* old frm file */
880
      field_type= (enum_field_types) f_packtype(pack_flag);
881
      if (f_is_binary(pack_flag))
882
      {
883
        /*
884
          Try to choose the best 4.1 type:
885
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
886
            try to find a binary collation for character set.
887
          - for other types (e.g. BLOB) just use my_charset_bin. 
888
        */
889
        if (!f_is_blob(pack_flag))
890
        {
891
          // 3.23 or 4.0 string
892
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
893
                                               MY_CS_BINSORT, MYF(0))))
894
            charset= &my_charset_bin;
895
        }
896
        else
897
          charset= &my_charset_bin;
898
      }
899
      else
900
        charset= share->table_charset;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
901
      memset(&comment, 0, sizeof(comment));
1 by brian
clean slate
902
    }
903
904
    if (interval_nr && charset->mbminlen > 1)
905
    {
906
      /* Unescape UCS2 intervals from HEX notation */
907
      TYPELIB *interval= share->intervals + interval_nr - 1;
908
      unhex_type2(interval);
909
    }
910
911
    *field_ptr= reg_field=
912
      make_field(share, record+recpos,
205 by Brian Aker
uint32 -> uin32_t
913
		 (uint32_t) field_length,
1 by brian
clean slate
914
		 null_pos, null_bit_pos,
915
		 pack_flag,
916
		 field_type,
917
		 charset,
918
		 (Field::utype) MTYP_TYPENR(unireg_type),
919
		 (interval_nr ?
920
		  share->intervals+interval_nr-1 :
921
		  (TYPELIB*) 0),
922
		 share->fieldnames.type_names[i]);
923
    if (!reg_field)				// Not supported field type
924
    {
925
      error= 4;
926
      goto err;			/* purecov: inspected */
927
    }
928
929
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
930
    reg_field->field_index= i;
931
    reg_field->comment=comment;
932
    if (!(reg_field->flags & NOT_NULL_FLAG))
933
    {
934
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
935
        null_pos++;
936
    }
937
    if (f_no_default(pack_flag))
938
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
939
940
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
941
      share->found_next_number_field= field_ptr;
942
    if (share->timestamp_field == reg_field)
943
      share->timestamp_field_offset= i;
944
945
    if (use_hash)
946
      (void) my_hash_insert(&share->name_hash,
947
                            (uchar*) field_ptr); // never fail
948
  }
949
  *field_ptr=0;					// End marker
950
951
  /* Fix key->name and key_part->field */
952
  if (key_parts)
953
  {
954
    uint primary_key=(uint) (find_type((char*) primary_key_name,
955
				       &share->keynames, 3) - 1);
152 by Brian Aker
longlong replacement
956
    int64_t ha_option= handler_file->ha_table_flags();
1 by brian
clean slate
957
    keyinfo= share->key_info;
958
    key_part= keyinfo->key_part;
959
960
    for (uint key=0 ; key < share->keys ; key++,keyinfo++)
961
    {
962
      uint usable_parts= 0;
963
      keyinfo->name=(char*) share->keynames.type_names[key];
964
965
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
966
      {
967
	/*
968
	  If the UNIQUE key doesn't have NULL columns and is not a part key
969
	  declare this as a primary key.
970
	*/
971
	primary_key=key;
972
	for (i=0 ; i < keyinfo->key_parts ;i++)
973
	{
974
	  uint fieldnr= key_part[i].fieldnr;
975
	  if (!fieldnr ||
976
	      share->field[fieldnr-1]->null_ptr ||
977
	      share->field[fieldnr-1]->key_length() !=
978
	      key_part[i].length)
979
	  {
980
	    primary_key=MAX_KEY;		// Can't be used
981
	    break;
982
	  }
983
	}
984
      }
985
986
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
987
      {
988
        Field *field;
989
	if (new_field_pack_flag <= 1)
206 by Brian Aker
Removed final uint dead types.
990
	  key_part->fieldnr= (uint16_t) find_field(share->field,
1 by brian
clean slate
991
                                                 share->default_values,
992
                                                 (uint) key_part->offset,
993
                                                 (uint) key_part->length);
994
	if (!key_part->fieldnr)
995
        {
996
          error= 4;                             // Wrong file
997
          goto err;
998
        }
999
        field= key_part->field= share->field[key_part->fieldnr-1];
1000
        key_part->type= field->key_type();
1001
        if (field->null_ptr)
1002
        {
1003
          key_part->null_offset=(uint) ((uchar*) field->null_ptr -
1004
                                        share->default_values);
1005
          key_part->null_bit= field->null_bit;
1006
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1007
          keyinfo->flags|=HA_NULL_PART_KEY;
1008
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1009
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1010
        }
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
1011
        if (field->type() == DRIZZLE_TYPE_BLOB ||
1012
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
1 by brian
clean slate
1013
        {
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
1014
          if (field->type() == DRIZZLE_TYPE_BLOB)
1 by brian
clean slate
1015
            key_part->key_part_flag|= HA_BLOB_PART;
1016
          else
1017
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1018
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1019
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1020
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1021
        }
1022
        if (i == 0 && key != primary_key)
1023
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1024
                           (keyinfo->key_parts == 1)) ?
1025
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1026
        if (i == 0)
1027
          field->key_start.set_bit(key);
1028
        if (field->key_length() == key_part->length &&
1029
            !(field->flags & BLOB_FLAG))
1030
        {
1031
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1032
          {
1033
            share->keys_for_keyread.set_bit(key);
1034
            field->part_of_key.set_bit(key);
1035
            field->part_of_key_not_clustered.set_bit(key);
1036
          }
1037
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1038
            field->part_of_sortkey.set_bit(key);
1039
        }
1040
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1041
            usable_parts == i)
1042
          usable_parts++;			// For FILESORT
1043
        field->flags|= PART_KEY_FLAG;
1044
        if (key == primary_key)
1045
        {
1046
          field->flags|= PRI_KEY_FLAG;
1047
          /*
1048
            If this field is part of the primary key and all keys contains
1049
            the primary key, then we can use any key to find this column
1050
          */
1051
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1052
          {
1053
            field->part_of_key= share->keys_in_use;
1054
            if (field->part_of_sortkey.is_set(key))
1055
              field->part_of_sortkey= share->keys_in_use;
1056
          }
1057
        }
1058
        if (field->key_length() != key_part->length)
1059
        {
1060
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1061
        }
1062
      }
1063
      keyinfo->usable_key_parts= usable_parts; // Filesort
1064
1065
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1066
                    keyinfo->key_parts);
1067
      share->total_key_length+= keyinfo->key_length;
1068
      /*
1069
        MERGE tables do not have unique indexes. But every key could be
1070
        an unique index on the underlying MyISAM table. (Bug #10400)
1071
      */
1072
      if ((keyinfo->flags & HA_NOSAME) ||
1073
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1074
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1075
    }
1076
    if (primary_key < MAX_KEY &&
1077
	(share->keys_in_use.is_set(primary_key)))
1078
    {
1079
      share->primary_key= primary_key;
1080
      /*
1081
	If we are using an integer as the primary key then allow the user to
1082
	refer to it as '_rowid'
1083
      */
1084
      if (share->key_info[primary_key].key_parts == 1)
1085
      {
1086
	Field *field= share->key_info[primary_key].key_part[0].field;
1087
	if (field && field->result_type() == INT_RESULT)
1088
        {
1089
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1090
	  share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1091
                                      fieldnr);
1092
        }
1093
      }
1094
    }
1095
    else
1096
      share->primary_key = MAX_KEY; // we do not have a primary key
1097
  }
1098
  else
1099
    share->primary_key= MAX_KEY;
1100
  x_free((uchar*) disk_buff);
1101
  disk_buff=0;
1102
  if (new_field_pack_flag <= 1)
1103
  {
1104
    /* Old file format with default as not null */
1105
    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:
1106
    memset(share->default_values + (null_flags - (uchar*) record), 
1 by brian
clean slate
1107
          null_length, 255);
1108
  }
1109
1110
  if (share->found_next_number_field)
1111
  {
1112
    reg_field= *share->found_next_number_field;
1113
    if ((int) (share->next_number_index= (uint)
1114
	       find_ref_key(share->key_info, share->keys,
1115
                            share->default_values, reg_field,
1116
			    &share->next_number_key_offset,
1117
                            &share->next_number_keypart)) < 0)
1118
    {
1119
      /* Wrong field definition */
1120
      error= 4;
1121
      goto err;
1122
    }
1123
    else
1124
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1125
  }
1126
1127
  if (share->blob_fields)
1128
  {
1129
    Field **ptr;
1130
    uint k, *save;
1131
1132
    /* Store offsets to blob fields to find them fast */
1133
    if (!(share->blob_field= save=
1134
	  (uint*) alloc_root(&share->mem_root,
1135
                             (uint) (share->blob_fields* sizeof(uint)))))
1136
      goto err;
1137
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1138
    {
1139
      if ((*ptr)->flags & BLOB_FLAG)
1140
	(*save++)= k;
1141
    }
1142
  }
1143
1144
  /*
1145
    the correct null_bytes can now be set, since bitfields have been taken
1146
    into account
1147
  */
1148
  share->null_bytes= (null_pos - (uchar*) null_flags +
1149
                      (null_bit_pos + 7) / 8);
1150
  share->last_null_bit_pos= null_bit_pos;
1151
1152
  share->db_low_byte_first= handler_file->low_byte_first();
1153
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1154
1155
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1156
                                             share->column_bitmap_size)))
1157
    goto err;
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1158
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
1 by brian
clean slate
1159
  bitmap_set_all(&share->all_set);
1160
1161
  delete handler_file;
1162
  if (buff)
1163
    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
1164
  return (0);
1 by brian
clean slate
1165
1166
 err:
1167
  if (buff)
1168
    my_free(buff, MYF(0));
1169
  share->error= error;
1170
  share->open_errno= my_errno;
1171
  share->errarg= errarg;
1172
  x_free((uchar*) disk_buff);
1173
  delete handler_file;
1174
  hash_free(&share->name_hash);
1175
1176
  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
1177
  return(error);
1 by brian
clean slate
1178
} /* open_binary_frm */
1179
1180
1181
/*
1182
  Open a table based on a TABLE_SHARE
1183
1184
  SYNOPSIS
1185
    open_table_from_share()
1186
    thd			Thread handler
1187
    share		Table definition
1188
    alias       	Alias for table
1189
    db_stat		open flags (for example HA_OPEN_KEYFILE|
1190
    			HA_OPEN_RNDFILE..) can be 0 (example in
1191
                        ha_example_table)
1192
    prgflag   		READ_ALL etc..
1193
    ha_open_flags	HA_OPEN_ABORT_IF_LOCKED etc..
1194
    outparam       	result table
1195
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1196
                        if OTM_CREATE some errors are ignore
1197
                        if OTM_ALTER HA_OPEN is not called
1198
1199
  RETURN VALUES
1200
   0	ok
1201
   1	Error (see open_table_error)
1202
   2    Error (see open_table_error)
1203
   3    Wrong data in .frm file
1204
   4    Error (see open_table_error)
1205
   5    Error (see open_table_error: charset unavailable)
1206
   7    Table definition has changed in engine
1207
*/
1208
1209
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1210
                          uint db_stat, uint prgflag, uint ha_open_flags,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1211
                          Table *outparam, open_table_mode open_mode)
1 by brian
clean slate
1212
{
1213
  int error;
1214
  uint records, i, bitmap_size;
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1215
  bool error_reported= false;
1 by brian
clean slate
1216
  uchar *record, *bitmaps;
1217
  Field **field_ptr;
1218
1219
  /* 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
1220
  assert(thd->lex->is_lex_started);
1 by brian
clean slate
1221
1222
  error= 1;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1223
  memset(outparam, 0, sizeof(*outparam));
1 by brian
clean slate
1224
  outparam->in_use= thd;
1225
  outparam->s= share;
1226
  outparam->db_stat= db_stat;
1227
  outparam->write_row_record= NULL;
1228
1229
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1230
1231
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
1232
    goto err;
1233
  outparam->quick_keys.init();
1234
  outparam->covering_keys.init();
1235
  outparam->keys_in_use_for_query.init();
1236
1237
  /* Allocate handler */
1238
  outparam->file= 0;
1239
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
1240
  {
1241
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1242
                                          share->db_type())))
1243
      goto err;
1244
  }
1245
  else
1246
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1247
    assert(!db_stat);
1 by brian
clean slate
1248
  }
1249
1250
  error= 4;
1251
  outparam->reginfo.lock_type= TL_UNLOCK;
1252
  outparam->current_lock= F_UNLCK;
1253
  records=0;
1254
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1255
    records=1;
1256
  if (prgflag & (READ_ALL+EXTRA_RECORD))
1257
    records++;
1258
1259
  if (!(record= (uchar*) alloc_root(&outparam->mem_root,
1260
                                   share->rec_buff_length * records)))
1261
    goto err;                                   /* purecov: inspected */
1262
1263
  if (records == 0)
1264
  {
1265
    /* We are probably in hard repair, and the buffers should not be used */
1266
    outparam->record[0]= outparam->record[1]= share->default_values;
1267
  }
1268
  else
1269
  {
1270
    outparam->record[0]= record;
1271
    if (records > 1)
1272
      outparam->record[1]= record+ share->rec_buff_length;
1273
    else
1274
      outparam->record[1]= outparam->record[0];   // Safety
1275
  }
1276
1277
#ifdef HAVE_purify
1278
  /*
1279
    We need this because when we read var-length rows, we are not updating
1280
    bytes after end of varchar
1281
  */
1282
  if (records > 1)
1283
  {
1284
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1285
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
1286
    if (records > 2)
1287
      memcpy(outparam->record[1], share->default_values,
1288
             share->rec_buff_length);
1289
  }
1290
#endif
1291
1292
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1293
                                          (uint) ((share->fields+1)*
1294
                                                  sizeof(Field*)))))
1295
    goto err;                                   /* purecov: inspected */
1296
1297
  outparam->field= field_ptr;
1298
1299
  record= (uchar*) outparam->record[0]-1;	/* Fieldstart = 1 */
1300
  if (share->null_field_first)
1301
    outparam->null_flags= (uchar*) record+1;
1302
  else
1303
    outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
1304
                                    share->null_bytes);
1305
1306
  /* Setup copy of fields from share, but use the right alias and record */
1307
  for (i=0 ; i < share->fields; i++, field_ptr++)
1308
  {
1309
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1310
      goto err;
1311
  }
1312
  (*field_ptr)= 0;                              // End marker
1313
1314
  if (share->found_next_number_field)
1315
    outparam->found_next_number_field=
1316
      outparam->field[(uint) (share->found_next_number_field - share->field)];
1317
  if (share->timestamp_field)
1318
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1319
1320
1321
  /* Fix key->name and key_part->field */
1322
  if (share->key_parts)
1323
  {
1324
    KEY	*key_info, *key_info_end;
1325
    KEY_PART_INFO *key_part;
1326
    uint n_length;
1327
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1328
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1329
      goto err;
1330
    outparam->key_info= key_info;
1331
    key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
1332
    
1333
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1334
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1335
                                                   share->key_parts));
1336
1337
    for (key_info_end= key_info + share->keys ;
1338
         key_info < key_info_end ;
1339
         key_info++)
1340
    {
1341
      KEY_PART_INFO *key_part_end;
1342
1343
      key_info->table= outparam;
1344
      key_info->key_part= key_part;
1345
1346
      for (key_part_end= key_part+ key_info->key_parts ;
1347
           key_part < key_part_end ;
1348
           key_part++)
1349
      {
1350
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1351
1352
        if (field->key_length() != key_part->length &&
1353
            !(field->flags & BLOB_FLAG))
1354
        {
1355
          /*
1356
            We are using only a prefix of the column as a key:
1357
            Create a new field for the key part that matches the index
1358
          */
1359
          field= key_part->field=field->new_field(&outparam->mem_root,
1360
                                                  outparam, 0);
1361
          field->field_length= key_part->length;
1362
        }
1363
      }
1364
    }
1365
  }
1366
1367
  /* Allocate bitmaps */
1368
1369
  bitmap_size= share->column_bitmap_size;
1370
  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1371
    goto err;
1372
  bitmap_init(&outparam->def_read_set,
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1373
              (my_bitmap_map*) bitmaps, share->fields, false);
1 by brian
clean slate
1374
  bitmap_init(&outparam->def_write_set,
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1375
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1 by brian
clean slate
1376
  bitmap_init(&outparam->tmp_set,
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1377
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1 by brian
clean slate
1378
  outparam->default_column_bitmaps();
1379
1380
  /* The table struct is now initialized;  Open the table */
1381
  error= 2;
1382
  if (db_stat && open_mode != OTM_ALTER)
1383
  {
1384
    int ha_err;
1385
    if ((ha_err= (outparam->file->
1386
                  ha_open(outparam, share->normalized_path.str,
1387
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1388
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
362 by Brian Aker
No more dead special flags...
1389
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
1 by brian
clean slate
1390
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1391
                          HA_OPEN_ABORT_IF_LOCKED :
1392
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1393
    {
1394
      /* Set a flag if the table is crashed and it can be auto. repaired */
1395
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1396
                       outparam->file->auto_repair() &&
1397
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
1398
1399
      switch (ha_err)
1400
      {
1401
        case HA_ERR_NO_SUCH_TABLE:
1402
	  /*
1403
            The table did not exists in storage engine, use same error message
1404
            as if the .frm file didn't exist
1405
          */
1406
	  error= 1;
1407
	  my_errno= ENOENT;
1408
          break;
1409
        case EMFILE:
1410
	  /*
1411
            Too many files opened, use same error message as if the .frm
1412
            file can't open
1413
           */
1414
	  error= 1;
1415
	  my_errno= EMFILE;
1416
          break;
1417
        default:
1418
          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
1419
          error_reported= true;
1 by brian
clean slate
1420
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1421
            error= 7;
1422
          break;
1423
      }
1424
      goto err;                                 /* purecov: inspected */
1425
    }
1426
  }
1427
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1428
#if defined(HAVE_purify) 
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1429
  memset(bitmaps, 0, bitmap_size*3);
1 by brian
clean slate
1430
#endif
1431
1432
  outparam->no_replicate= outparam->file &&
1433
                          test(outparam->file->ha_table_flags() &
1434
                               HA_HAS_OWN_BINLOGGING);
1435
  thd->status_var.opened_tables++;
1436
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
1437
  return (0);
1 by brian
clean slate
1438
1439
 err:
1440
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1441
    open_table_error(share, error, my_errno, 0);
1442
  delete outparam->file;
1443
  outparam->file= 0;				// For easier error checking
1444
  outparam->db_stat=0;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
1445
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1 by brian
clean slate
1446
  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
1447
  return (error);
1 by brian
clean slate
1448
}
1449
1450
1451
/*
1452
  Free information allocated by openfrm
1453
1454
  SYNOPSIS
1455
    closefrm()
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1456
    table		Table object to free
1 by brian
clean slate
1457
    free_share		Is 1 if we also want to free table_share
1458
*/
1459
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1460
int closefrm(register Table *table, bool free_share)
1 by brian
clean slate
1461
{
1462
  int error=0;
1463
1464
  if (table->db_stat)
1465
    error=table->file->close();
1466
  my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
1467
  table->alias= 0;
1468
  if (table->field)
1469
  {
1470
    for (Field **ptr=table->field ; *ptr ; ptr++)
1471
      delete *ptr;
1472
    table->field= 0;
1473
  }
1474
  delete table->file;
1475
  table->file= 0;				/* For easier errorchecking */
1476
  if (free_share)
1477
  {
1478
    if (table->s->tmp_table == NO_TMP_TABLE)
1479
      release_table_share(table->s, RELEASE_NORMAL);
1480
    else
1481
      free_table_share(table->s);
1482
  }
1483
  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
1484
  return(error);
1 by brian
clean slate
1485
}
1486
1487
1488
/* Deallocate temporary blob storage */
1489
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1490
void free_blobs(register Table *table)
1 by brian
clean slate
1491
{
1492
  uint *ptr, *end;
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
1493
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1 by brian
clean slate
1494
       ptr != end ;
1495
       ptr++)
1496
    ((Field_blob*) table->field[*ptr])->free();
1497
}
1498
1499
1500
	/* Find where a form starts */
1501
	/* if formname is NullS then only formnames is read */
1502
1503
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
1504
{
1505
  uint a_length,names,length;
1506
  uchar *pos,*buf;
1507
  ulong ret_value=0;
1508
1509
  names=uint2korr(head+8);
1510
  a_length=(names+2)*sizeof(char *);		/* Room for two extra */
1511
1512
  if (!save_names)
1513
    a_length=0;
1514
  else
1515
    save_names->type_names=0;			/* Clear if error */
1516
1517
  if (names)
1518
  {
1519
    length=uint2korr(head+4);
1520
    VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0)));
1521
    if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
1522
				  MYF(MY_WME))) ||
1523
	my_read(file, buf+a_length, (size_t) (length+names*4),
1524
		MYF(MY_NABP)))
1525
    {						/* purecov: inspected */
1526
      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
1527
      return(0L);				/* purecov: inspected */
1 by brian
clean slate
1528
    }
1529
    pos= buf+a_length+length;
1530
    ret_value=uint4korr(pos);
1531
  }
1532
  if (! save_names)
1533
  {
1534
    if (names)
1535
      my_free((uchar*) buf,MYF(0));
1536
  }
1537
  else if (!names)
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1538
    memset(save_names, 0, sizeof(save_names));
1 by brian
clean slate
1539
  else
1540
  {
1541
    char *str;
1542
    str=(char *) (buf+a_length);
1543
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
1544
  }
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
1545
  return(ret_value);
1 by brian
clean slate
1546
}
1547
1548
1549
/*
1550
  Read string from a file with malloc
1551
1552
  NOTES:
1553
    We add an \0 at end of the read string to make reading of C strings easier
1554
*/
1555
1556
int read_string(File file, uchar**to, size_t length)
1557
{
1558
1559
  x_free(*to);
1560
  if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
1561
      my_read(file, *to, length,MYF(MY_NABP)))
1562
  {
1563
    x_free(*to);                              /* purecov: inspected */
1564
    *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
1565
    return(1);                           /* purecov: inspected */
1 by brian
clean slate
1566
  }
1567
  *((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
1568
  return (0);
1 by brian
clean slate
1569
} /* read_string */
1570
1571
1572
	/* Add a new form to a form file */
1573
1574
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
1575
		     const char *newname)
1576
{
1577
  uint i,bufflength,maxlength,n_length,length,names;
1578
  ulong endpos,newpos;
1579
  uchar buff[IO_SIZE];
1580
  uchar *pos;
1581
1582
  length=(uint) strlen(newname)+1;
1583
  n_length=uint2korr(fileinfo+4);
1584
  maxlength=uint2korr(fileinfo+6);
1585
  names=uint2korr(fileinfo+8);
1586
  newpos=uint4korr(fileinfo+10);
1587
1588
  if (64+length+n_length+(names+1)*4 > maxlength)
1589
  {						/* Expand file */
1590
    newpos+=IO_SIZE;
1591
    int4store(fileinfo+10,newpos);
1592
    endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1593
    bufflength= (uint) (endpos & (IO_SIZE-1));	/* IO_SIZE is a power of 2 */
1594
1595
    while (endpos > maxlength)
1596
    {
1597
      VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
1598
      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
1599
	return(0L);
1 by brian
clean slate
1600
      VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1601
		   MYF(0)));
1602
      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
1603
	return(0);
1 by brian
clean slate
1604
      endpos-=bufflength; bufflength=IO_SIZE;
1605
    }
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
1606
    memset(buff, 0, IO_SIZE);			/* Null new block */
1 by brian
clean slate
1607
    VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
1608
    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
1609
	return(0L);
1 by brian
clean slate
1610
    maxlength+=IO_SIZE;				/* Fix old ref */
1611
    int2store(fileinfo+6,maxlength);
1612
    for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
1613
	 pos+=4)
1614
    {
1615
      endpos=uint4korr(pos)+IO_SIZE;
1616
      int4store(pos,endpos);
1617
    }
1618
  }
1619
1620
  if (n_length == 1 )
1621
  {						/* First name */
1622
    length++;
1623
    VOID(strxmov((char*) buff,"/",newname,"/",NullS));
1624
  }
1625
  else
1626
    VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1627
  VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
1628
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1629
      (names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
1630
			 names*4, MYF(MY_NABP+MY_WME))) ||
1631
      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
1632
    return(0L); /* purecov: inspected */
1 by brian
clean slate
1633
1634
  int2store(fileinfo+8,names+1);
1635
  int2store(fileinfo+4,n_length+length);
30 by Brian Aker
Large file and ftruncate() support
1636
  (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
1637
  return(newpos);
1 by brian
clean slate
1638
} /* make_new_entry */
1639
1640
1641
	/* error message when opening a form file */
1642
1643
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1644
{
1645
  int err_no;
1646
  char buff[FN_REFLEN];
1647
  myf errortype= ME_ERROR+ME_WAITTANG;
1648
1649
  switch (error) {
1650
  case 7:
1651
  case 1:
1652
    if (db_errno == ENOENT)
1653
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1654
    else
1655
    {
1656
      strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1657
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1658
               errortype, buff, db_errno);
1659
    }
1660
    break;
1661
  case 2:
1662
  {
1663
    handler *file= 0;
1664
    const char *datext= "";
1665
    
1666
    if (share->db_type() != NULL)
1667
    {
1668
      if ((file= get_new_handler(share, current_thd->mem_root,
1669
                                 share->db_type())))
1670
      {
1671
        if (!(datext= *file->bas_ext()))
1672
          datext= "";
1673
      }
1674
    }
1675
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1676
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1677
    strxmov(buff, share->normalized_path.str, datext, NullS);
1678
    my_error(err_no,errortype, buff, db_errno);
1679
    delete file;
1680
    break;
1681
  }
1682
  case 5:
1683
  {
1684
    const char *csname= get_charset_name((uint) errarg);
1685
    char tmp[10];
1686
    if (!csname || csname[0] =='?')
1687
    {
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
1688
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
1 by brian
clean slate
1689
      csname= tmp;
1690
    }
1691
    my_printf_error(ER_UNKNOWN_COLLATION,
261.3.8 by Monty Taylor
Added strings from table.cc.
1692
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
1 by brian
clean slate
1693
                    MYF(0), csname, share->table_name.str);
1694
    break;
1695
  }
1696
  case 6:
1697
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1698
    my_printf_error(ER_NOT_FORM_FILE,
261.3.8 by Monty Taylor
Added strings from table.cc.
1699
                    _("Table '%-.64s' was created with a different version "
1700
                    "of MySQL and cannot be read"), 
1 by brian
clean slate
1701
                    MYF(0), buff);
1702
    break;
1703
  case 8:
1704
    break;
1705
  default:				/* Better wrong error than none */
1706
  case 4:
1707
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
1708
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1709
    break;
1710
  }
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
1711
  return;
1 by brian
clean slate
1712
} /* open_table_error */
1713
1714
1715
	/*
1716
	** fix a str_type to a array type
1717
	** typeparts separated with some char. differents types are separated
1718
	** with a '\0'
1719
	*/
1720
1721
static void
1722
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
1723
		  char **names)
1724
{
1725
  char *type_name, *ptr;
1726
  char chr;
1727
1728
  ptr= *names;
1729
  while (types--)
1730
  {
1731
    point_to_type->name=0;
1732
    point_to_type->type_names= *array;
1733
1734
    if ((chr= *ptr))			/* Test if empty type */
1735
    {
1736
      while ((type_name=strchr(ptr+1,chr)) != NullS)
1737
      {
1738
	*((*array)++) = ptr+1;
1739
	*type_name= '\0';		/* End string */
1740
	ptr=type_name;
1741
      }
1742
      ptr+=2;				/* Skip end mark and last 0 */
1743
    }
1744
    else
1745
      ptr++;
1746
    point_to_type->count= (uint) (*array - point_to_type->type_names);
1747
    point_to_type++;
1748
    *((*array)++)= NullS;		/* End of type */
1749
  }
1750
  *names=ptr;				/* Update end */
1751
  return;
1752
} /* fix_type_pointers */
1753
1754
1755
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1756
{
1757
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1758
  if (!result)
1759
    return 0;
1760
  result->count=strings.elements;
1761
  result->name="";
1762
  uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1763
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1764
    return 0;
1765
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1766
  List_iterator<String> it(strings);
1767
  String *tmp;
1768
  for (uint i=0; (tmp=it++) ; i++)
1769
  {
1770
    result->type_names[i]= tmp->ptr();
1771
    result->type_lengths[i]= tmp->length();
1772
  }
1773
  result->type_names[result->count]= 0;		// End marker
1774
  result->type_lengths[result->count]= 0;
1775
  return result;
1776
}
1777
1778
1779
/*
1780
 Search after a field with given start & length
1781
 If an exact field isn't found, return longest field with starts
1782
 at right position.
1783
 
1784
 NOTES
1785
   This is needed because in some .frm fields 'fieldnr' was saved wrong
1786
1787
 RETURN
1788
   0  error
1789
   #  field number +1
1790
*/
1791
1792
static uint find_field(Field **fields, uchar *record, uint start, uint length)
1793
{
1794
  Field **field;
1795
  uint i, pos;
1796
1797
  pos= 0;
1798
  for (field= fields, i=1 ; *field ; i++,field++)
1799
  {
1800
    if ((*field)->offset(record) == start)
1801
    {
1802
      if ((*field)->key_length() == length)
1803
	return (i);
1804
      if (!pos || fields[pos-1]->pack_length() <
1805
	  (*field)->pack_length())
1806
	pos= i;
1807
    }
1808
  }
1809
  return (pos);
1810
}
1811
1812
1813
	/* Check that the integer is in the internal */
1814
1815
int set_zone(register int nr, int min_zone, int max_zone)
1816
{
1817
  if (nr<=min_zone)
1818
    return (min_zone);
1819
  if (nr>=max_zone)
1820
    return (max_zone);
1821
  return (nr);
1822
} /* set_zone */
1823
1824
	/* Adjust number to next larger disk buffer */
1825
1826
ulong next_io_size(register ulong pos)
1827
{
1828
  register ulong offset;
1829
  if ((offset= pos & (IO_SIZE-1)))
1830
    return pos-offset+IO_SIZE;
1831
  return pos;
1832
} /* next_io_size */
1833
1834
1835
/*
1836
  Store an SQL quoted string.
1837
1838
  SYNOPSIS  
1839
    append_unescaped()
1840
    res		result String
1841
    pos		string to be quoted
1842
    length	it's length
1843
1844
  NOTE
1845
    This function works correctly with utf8 or single-byte charset strings.
1846
    May fail with some multibyte charsets though.
1847
*/
1848
1849
void append_unescaped(String *res, const char *pos, uint length)
1850
{
1851
  const char *end= pos+length;
1852
  res->append('\'');
1853
1854
  for (; pos != end ; pos++)
1855
  {
193 by Brian Aker
Cleanup on "VERSION" issues. Table FRM exists and prevents modifying back
1856
#if defined(USE_MB)
1 by brian
clean slate
1857
    uint mblen;
1858
    if (use_mb(default_charset_info) &&
1859
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1860
    {
1861
      res->append(pos, mblen);
1862
      pos+= mblen;
1863
      continue;
1864
    }
1865
#endif
1866
1867
    switch (*pos) {
1868
    case 0:				/* Must be escaped for 'mysql' */
1869
      res->append('\\');
1870
      res->append('0');
1871
      break;
1872
    case '\n':				/* Must be escaped for logs */
1873
      res->append('\\');
1874
      res->append('n');
1875
      break;
1876
    case '\r':
1877
      res->append('\\');		/* This gives better readability */
1878
      res->append('r');
1879
      break;
1880
    case '\\':
1881
      res->append('\\');		/* Because of the sql syntax */
1882
      res->append('\\');
1883
      break;
1884
    case '\'':
1885
      res->append('\'');		/* Because of the sql syntax */
1886
      res->append('\'');
1887
      break;
1888
    default:
1889
      res->append(*pos);
1890
      break;
1891
    }
1892
  }
1893
  res->append('\'');
1894
}
1895
1896
1897
	/* Create a .frm file */
1898
1899
File create_frm(THD *thd, const char *name, const char *db,
1900
                const char *table, uint reclength, uchar *fileinfo,
1901
  		HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
1902
{
1903
  register File file;
1904
  ulong length;
1905
  uchar fill[IO_SIZE];
1906
  int create_flags= O_RDWR | O_TRUNC;
1907
  ulong key_comment_total_bytes= 0;
1908
  uint i;
1909
1910
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1911
    create_flags|= O_EXCL | O_NOFOLLOW;
1912
1913
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
163 by Brian Aker
Merge Monty's code.
1914
  if (create_info->max_rows > UINT32_MAX)
1915
    create_info->max_rows= UINT32_MAX;
1916
  if (create_info->min_rows > UINT32_MAX)
1917
    create_info->min_rows= UINT32_MAX;
1 by brian
clean slate
1918
1919
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
1920
  {
1921
    uint key_length, tmp_key_length;
1922
    uint tmp;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1923
    memset(fileinfo, 0, 64);
1 by brian
clean slate
1924
    /* header */
1925
    fileinfo[0]=(uchar) 254;
1926
    fileinfo[1]= 1;
1927
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
1928
1929
    fileinfo[3]= (uchar) ha_legacy_type(
1930
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
1931
    fileinfo[4]=1;
1932
    int2store(fileinfo+6,IO_SIZE);		/* Next block starts here */
1933
    for (i= 0; i < keys; i++)
1934
    {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1935
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
1 by brian
clean slate
1936
                 (key_info[i].comment.length > 0));
1937
      if (key_info[i].flags & HA_USES_COMMENT)
1938
        key_comment_total_bytes += 2 + key_info[i].comment.length;
1939
    }
1940
    /*
1941
      Keep in sync with pack_keys() in unireg.cc
1942
      For each key:
1943
      8 bytes for the key header
1944
      9 bytes for each key-part (MAX_REF_PARTS)
1945
      NAME_LEN bytes for the name
1946
      1 byte for the NAMES_SEP_CHAR (before the name)
1947
      For all keys:
1948
      6 bytes for the header
1949
      1 byte for the NAMES_SEP_CHAR (after the last name)
1950
      9 extra bytes (padding for safety? alignment?)
1951
      comments
1952
    */
1953
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
1954
                 key_comment_total_bytes);
1955
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
1956
                                  create_info->extra_size));
1957
    int4store(fileinfo+10,length);
1958
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
1959
    int2store(fileinfo+14,tmp_key_length);
1960
    int2store(fileinfo+16,reclength);
1961
    int4store(fileinfo+18,create_info->max_rows);
1962
    int4store(fileinfo+22,create_info->min_rows);
1963
    /* fileinfo[26] is set in mysql_create_frm() */
1964
    fileinfo[27]=2;				// Use long pack-fields
1965
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
1966
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
1967
    int2store(fileinfo+30,create_info->table_options);
1968
    fileinfo[32]=0;				// No filename anymore
1969
    fileinfo[33]=5;                             // Mark for 5.0 frm file
1970
    int4store(fileinfo+34,create_info->avg_row_length);
1971
    fileinfo[38]= (create_info->default_table_charset ?
1972
		   create_info->default_table_charset->number : 0);
408 by Brian Aker
Removed dead bits to HA_CREATE_INFO
1973
    fileinfo[39]= (uchar) create_info->page_checksum;
1 by brian
clean slate
1974
    fileinfo[40]= (uchar) create_info->row_type;
1975
    /* Next few bytes where for RAID support */
1976
    fileinfo[41]= 0;
1977
    fileinfo[42]= 0;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
1978
    int4store(fileinfo+43,create_info->block_size);
1979
 
1 by brian
clean slate
1980
    fileinfo[44]= 0;
1981
    fileinfo[45]= 0;
1982
    fileinfo[46]= 0;
1983
    int4store(fileinfo+47, key_length);
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
1984
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
1 by brian
clean slate
1985
    int4store(fileinfo+51, tmp);
1986
    int4store(fileinfo+55, create_info->extra_size);
1987
    /*
1988
      59-60 is reserved for extra_rec_buf_length,
1989
      61 for default_part_db_type
1990
    */
1991
    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.
1992
    memset(fill, 0, IO_SIZE);
1 by brian
clean slate
1993
    for (; length > IO_SIZE ; length-= IO_SIZE)
1994
    {
1995
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
1996
      {
1997
	VOID(my_close(file,MYF(0)));
1998
	VOID(my_delete(name,MYF(0)));
1999
	return(-1);
2000
      }
2001
    }
2002
  }
2003
  else
2004
  {
2005
    if (my_errno == ENOENT)
2006
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2007
    else
2008
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2009
  }
2010
  return (file);
2011
} /* create_frm */
2012
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2013
/*
2014
  Set up column usage bitmaps for a temporary table
2015
2016
  IMPLEMENTATION
2017
    For temporary tables, we need one bitmap with all columns set and
2018
    a tmp_set bitmap to be used by things like filesort.
2019
*/
2020
2021
void Table::setup_tmp_table_column_bitmaps(uchar *bitmaps)
2022
{
2023
  uint field_count= s->fields;
2024
2025
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
2026
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
2027
2028
  /* write_set and all_set are copies of read_set */
2029
  def_write_set= def_read_set;
2030
  s->all_set= def_read_set;
2031
  bitmap_set_all(&this->s->all_set);
2032
  default_column_bitmaps();
2033
}
2034
2035
2036
2037
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
2038
{
2039
  create_info->max_rows= s->max_rows;
2040
  create_info->min_rows= s->min_rows;
2041
  create_info->table_options= s->db_create_options;
2042
  create_info->avg_row_length= s->avg_row_length;
2043
  create_info->block_size= s->block_size;
2044
  create_info->row_type= s->row_type;
2045
  create_info->default_table_charset= s->table_charset;
1 by brian
clean slate
2046
  create_info->table_charset= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2047
  create_info->comment= s->comment;
1 by brian
clean slate
2048
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
2049
  return;
1 by brian
clean slate
2050
}
2051
2052
int
2053
rename_file_ext(const char * from,const char * to,const char * ext)
2054
{
2055
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
2056
  VOID(strxmov(from_b,from,ext,NullS));
2057
  VOID(strxmov(to_b,to,ext,NullS));
2058
  return (my_rename(from_b,to_b,MYF(MY_WME)));
2059
}
2060
2061
2062
/*
2063
  Allocate string field in MEM_ROOT and return it as String
2064
2065
  SYNOPSIS
2066
    get_field()
2067
    mem   	MEM_ROOT for allocating
2068
    field 	Field for retrieving of string
2069
    res         result String
2070
2071
  RETURN VALUES
2072
    1   string is empty
2073
    0	all ok
2074
*/
2075
2076
bool get_field(MEM_ROOT *mem, Field *field, String *res)
2077
{
2078
  char buff[MAX_FIELD_WIDTH], *to;
2079
  String str(buff,sizeof(buff),&my_charset_bin);
2080
  uint length;
2081
2082
  field->val_str(&str);
2083
  if (!(length= str.length()))
2084
  {
2085
    res->length(0);
2086
    return 1;
2087
  }
2088
  if (!(to= strmake_root(mem, str.ptr(), length)))
2089
    length= 0;                                  // Safety fix
2090
  res->set(to, length, ((Field_str*)field)->charset());
2091
  return 0;
2092
}
2093
2094
2095
/*
2096
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
2097
2098
  SYNOPSIS
2099
    get_field()
2100
    mem   	MEM_ROOT for allocating
2101
    field 	Field for retrieving of string
2102
2103
  RETURN VALUES
2104
    NullS  string is empty
2105
    #      pointer to NULL-terminated string value of field
2106
*/
2107
2108
char *get_field(MEM_ROOT *mem, Field *field)
2109
{
2110
  char buff[MAX_FIELD_WIDTH], *to;
2111
  String str(buff,sizeof(buff),&my_charset_bin);
2112
  uint length;
2113
2114
  field->val_str(&str);
2115
  length= str.length();
2116
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2117
    return NullS;
2118
  memcpy(to,str.ptr(),(uint) length);
2119
  to[length]=0;
2120
  return to;
2121
}
2122
2123
/*
2124
  DESCRIPTION
2125
    given a buffer with a key value, and a map of keyparts
2126
    that are present in this value, returns the length of the value
2127
*/
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2128
uint calculate_key_len(Table *table, uint key,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
2129
                       const uchar *buf __attribute__((unused)),
1 by brian
clean slate
2130
                       key_part_map keypart_map)
2131
{
2132
  /* works only with key prefixes */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2133
  assert(((keypart_map + 1) & keypart_map) == 0);
1 by brian
clean slate
2134
2135
  KEY *key_info= table->s->key_info+key;
2136
  KEY_PART_INFO *key_part= key_info->key_part;
2137
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
2138
  uint length= 0;
2139
2140
  while (key_part < end_key_part && keypart_map)
2141
  {
2142
    length+= key_part->store_length;
2143
    keypart_map >>= 1;
2144
    key_part++;
2145
  }
2146
  return length;
2147
}
2148
2149
/*
2150
  Check if database name is valid
2151
2152
  SYNPOSIS
2153
    check_db_name()
2154
    org_name		Name of database and length
2155
2156
  NOTES
2157
    If lower_case_table_names is set then database is converted to lower case
2158
2159
  RETURN
2160
    0	ok
2161
    1   error
2162
*/
2163
2164
bool check_db_name(LEX_STRING *org_name)
2165
{
2166
  char *name= org_name->str;
2167
  uint name_length= org_name->length;
2168
2169
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
2170
    return 1;
2171
2172
  if (lower_case_table_names && name != any_db)
2173
    my_casedn_str(files_charset_info, name);
2174
2175
  return check_identifier_name(org_name);
2176
}
2177
2178
2179
/*
2180
  Allow anything as a table name, as long as it doesn't contain an
2181
  ' ' at the end
2182
  returns 1 on error
2183
*/
2184
2185
2186
bool check_table_name(const char *name, uint length)
2187
{
2188
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
2189
    return 1;
2190
  LEX_STRING ident;
2191
  ident.str= (char*) name;
2192
  ident.length= length;
2193
  return check_identifier_name(&ident);
2194
}
2195
2196
2197
/*
2198
  Eventually, a "length" argument should be added
2199
  to this function, and the inner loop changed to
2200
  check_identifier_name() call.
2201
*/
2202
bool check_column_name(const char *name)
2203
{
2204
  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
2205
  bool last_char_is_space= true;
1 by brian
clean slate
2206
  
2207
  while (*name)
2208
  {
2209
#if defined(USE_MB) && defined(USE_MB_IDENT)
2210
    last_char_is_space= my_isspace(system_charset_info, *name);
2211
    if (use_mb(system_charset_info))
2212
    {
2213
      int len=my_ismbchar(system_charset_info, name, 
2214
                          name+system_charset_info->mbmaxlen);
2215
      if (len)
2216
      {
2217
        if (len > 3) /* Disallow non-BMP characters */
2218
          return 1;
2219
        name += len;
2220
        name_length++;
2221
        continue;
2222
      }
2223
    }
2224
#else
2225
    last_char_is_space= *name==' ';
2226
#endif
2227
    /*
2228
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
2229
      It is defined as 0xFF, which is a not valid byte in utf8.
2230
      This assert is to catch use of this byte if we decide to
2231
      use non-utf8 as system_character_set.
2232
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2233
    assert(*name != NAMES_SEP_CHAR);
1 by brian
clean slate
2234
    name++;
2235
    name_length++;
2236
  }
2237
  /* Error if empty or too long column name */
2238
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2239
}
2240
2241
2242
/**
2243
  Checks whether a table is intact. Should be done *just* after the table has
2244
  been opened.
2245
2246
  @param[in] table             The table to check
2247
  @param[in] table_f_count     Expected number of columns in the table
2248
  @param[in] table_def         Expected structure of the table (column name
2249
                               and type)
2250
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2251
  @retval  false  OK
1 by brian
clean slate
2252
  @retval  TRUE   There was an error. An error message is output
2253
                  to the error log.  We do not push an error
2254
                  message into the error stack because this
2255
                  function is currently only called at start up,
2256
                  and such errors never reach the user.
2257
*/
2258
148 by Brian Aker
my_bool cleanup
2259
bool
327.2.3 by Brian Aker
Refactoring of class Table
2260
Table::table_check_intact(const uint table_f_count,
2261
                          const TABLE_FIELD_W_TYPE *table_def)
1 by brian
clean slate
2262
{
2263
  uint i;
148 by Brian Aker
my_bool cleanup
2264
  bool error= false;
2265
  bool fields_diff_count;
1 by brian
clean slate
2266
327.2.3 by Brian Aker
Refactoring of class Table
2267
  fields_diff_count= (s->fields != table_f_count);
1 by brian
clean slate
2268
  if (fields_diff_count)
2269
  {
2270
2271
    /* previous MySQL version */
327.2.3 by Brian Aker
Refactoring of class Table
2272
    if (DRIZZLE_VERSION_ID > s->mysql_version)
1 by brian
clean slate
2273
    {
2274
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
327.2.3 by Brian Aker
Refactoring of class Table
2275
                      alias, table_f_count, s->fields,
2276
                      s->mysql_version, DRIZZLE_VERSION_ID);
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2277
      return(true);
1 by brian
clean slate
2278
    }
327.2.3 by Brian Aker
Refactoring of class Table
2279
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
1 by brian
clean slate
2280
    {
327.2.3 by Brian Aker
Refactoring of class Table
2281
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2282
                      table_f_count, s->fields);
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2283
      return(true);
1 by brian
clean slate
2284
    }
2285
    /*
2286
      Something has definitely changed, but we're running an older
2287
      version of MySQL with new system tables.
2288
      Let's check column definitions. If a column was added at
2289
      the end of the table, then we don't care much since such change
2290
      is backward compatible.
2291
    */
2292
  }
2293
  char buffer[STRING_BUFFER_USUAL_SIZE];
2294
  for (i=0 ; i < table_f_count; i++, table_def++)
2295
  {
2296
    String sql_type(buffer, sizeof(buffer), system_charset_info);
2297
    sql_type.length(0);
327.2.3 by Brian Aker
Refactoring of class Table
2298
    if (i < s->fields)
1 by brian
clean slate
2299
    {
327.2.3 by Brian Aker
Refactoring of class Table
2300
      Field *field= this->field[i];
1 by brian
clean slate
2301
2302
      if (strncmp(field->field_name, table_def->name.str,
2303
                  table_def->name.length))
2304
      {
2305
        /*
2306
          Name changes are not fatal, we use ordinal numbers to access columns.
2307
          Still this can be a sign of a tampered table, output an error
2308
          to the error log.
2309
        */
261.3.8 by Monty Taylor
Added strings from table.cc.
2310
        sql_print_error(_("Incorrect definition of table %s.%s: "
2311
                        "expected column '%s' at position %d, found '%s'."),
327.2.3 by Brian Aker
Refactoring of class Table
2312
                        s->db.str, alias, table_def->name.str, i,
1 by brian
clean slate
2313
                        field->field_name);
2314
      }
2315
      field->sql_type(sql_type);
2316
      /*
2317
        Generally, if column types don't match, then something is
2318
        wrong.
2319
2320
        However, we only compare column definitions up to the
2321
        length of the original definition, since we consider the
2322
        following definitions compatible:
2323
2324
        1. DATETIME and DATETIM
2325
        2. INT(11) and INT(11
2326
        3. SET('one', 'two') and SET('one', 'two', 'more')
2327
2328
        For SETs or ENUMs, if the same prefix is there it's OK to
2329
        add more elements - they will get higher ordinal numbers and
2330
        the new table definition is backward compatible with the
2331
        original one.
2332
       */
2333
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2334
                  table_def->type.length - 1))
2335
      {
261.3.8 by Monty Taylor
Added strings from table.cc.
2336
        sql_print_error(_("Incorrect definition of table %s.%s: "
1 by brian
clean slate
2337
                        "expected column '%s' at position %d to have type "
327.2.3 by Brian Aker
Refactoring of class Table
2338
                        "%s, found type %s."), s->db.str, alias,
1 by brian
clean slate
2339
                        table_def->name.str, i, table_def->type.str,
2340
                        sql_type.c_ptr_safe());
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2341
        error= true;
1 by brian
clean slate
2342
      }
2343
      else if (table_def->cset.str && !field->has_charset())
2344
      {
261.3.8 by Monty Taylor
Added strings from table.cc.
2345
        sql_print_error(_("Incorrect definition of table %s.%s: "
1 by brian
clean slate
2346
                        "expected the type of column '%s' at position %d "
2347
                        "to have character set '%s' but the type has no "
327.2.3 by Brian Aker
Refactoring of class Table
2348
                        "character set."), s->db.str, alias,
1 by brian
clean slate
2349
                        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
2350
        error= true;
1 by brian
clean slate
2351
      }
2352
      else if (table_def->cset.str &&
2353
               strcmp(field->charset()->csname, table_def->cset.str))
2354
      {
261.3.8 by Monty Taylor
Added strings from table.cc.
2355
        sql_print_error(_("Incorrect definition of table %s.%s: "
1 by brian
clean slate
2356
                        "expected the type of column '%s' at position %d "
2357
                        "to have character set '%s' but found "
327.2.3 by Brian Aker
Refactoring of class Table
2358
                        "character set '%s'."), s->db.str, alias,
1 by brian
clean slate
2359
                        table_def->name.str, i, table_def->cset.str,
2360
                        field->charset()->csname);
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2361
        error= true;
1 by brian
clean slate
2362
      }
2363
    }
2364
    else
2365
    {
261.3.8 by Monty Taylor
Added strings from table.cc.
2366
      sql_print_error(_("Incorrect definition of table %s.%s: "
1 by brian
clean slate
2367
                      "expected column '%s' at position %d to have type %s "
261.3.8 by Monty Taylor
Added strings from table.cc.
2368
                      " but the column is not found."),
327.2.3 by Brian Aker
Refactoring of class Table
2369
                      s->db.str, alias,
1 by brian
clean slate
2370
                      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
2371
      error= true;
1 by brian
clean slate
2372
    }
2373
  }
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
2374
  return(error);
1 by brian
clean slate
2375
}
2376
2377
2378
/*
2379
  Create Item_field for each column in the table.
2380
2381
  SYNPOSIS
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2382
    Table::fill_item_list()
1 by brian
clean slate
2383
      item_list          a pointer to an empty list used to store items
2384
2385
  DESCRIPTION
2386
    Create Item_field object for each column in the table and
2387
    initialize it with the corresponding Field. New items are
2388
    created in the current THD memory root.
2389
2390
  RETURN VALUE
2391
    0                    success
2392
    1                    out of memory
2393
*/
2394
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2395
bool Table::fill_item_list(List<Item> *item_list) const
1 by brian
clean slate
2396
{
2397
  /*
2398
    All Item_field's created using a direct pointer to a field
2399
    are fixed in Item_field constructor.
2400
  */
2401
  for (Field **ptr= field; *ptr; ptr++)
2402
  {
2403
    Item_field *item= new Item_field(*ptr);
2404
    if (!item || item_list->push_back(item))
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2405
      return true;
1 by brian
clean slate
2406
  }
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2407
  return false;
1 by brian
clean slate
2408
}
2409
2410
/*
2411
  Reset an existing list of Item_field items to point to the
2412
  Fields of this table.
2413
2414
  SYNPOSIS
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2415
    Table::fill_item_list()
1 by brian
clean slate
2416
      item_list          a non-empty list with Item_fields
2417
2418
  DESCRIPTION
2419
    This is a counterpart of fill_item_list used to redirect
2420
    Item_fields to the fields of a newly created table.
2421
    The caller must ensure that number of items in the item_list
2422
    is the same as the number of columns in the table.
2423
*/
2424
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2425
void Table::reset_item_list(List<Item> *item_list) const
1 by brian
clean slate
2426
{
2427
  List_iterator_fast<Item> it(*item_list);
2428
  for (Field **ptr= field; *ptr; ptr++)
2429
  {
2430
    Item_field *item_field= (Item_field*) it++;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2431
    assert(item_field != 0);
1 by brian
clean slate
2432
    item_field->reset_field(*ptr);
2433
  }
2434
}
2435
2436
2437
/*
327.2.4 by Brian Aker
Refactoring table.h
2438
  Find underlying base tables (TableList) which represent given
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2439
  table_to_find (Table)
1 by brian
clean slate
2440
2441
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2442
    TableList::find_underlying_table()
1 by brian
clean slate
2443
    table_to_find table to find
2444
2445
  RETURN
2446
    0  table is not found
2447
    found table reference
2448
*/
2449
327.2.4 by Brian Aker
Refactoring table.h
2450
TableList *TableList::find_underlying_table(Table *table_to_find)
1 by brian
clean slate
2451
{
2452
  /* is this real table and table which we are looking for? */
2453
  if (table == table_to_find && merge_underlying_list == 0)
2454
    return this;
2455
327.2.4 by Brian Aker
Refactoring table.h
2456
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
1 by brian
clean slate
2457
  {
327.2.4 by Brian Aker
Refactoring table.h
2458
    TableList *result;
1 by brian
clean slate
2459
    if ((result= tbl->find_underlying_table(table_to_find)))
2460
      return result;
2461
  }
2462
  return 0;
2463
}
2464
2465
/*
2466
  cleunup items belonged to view fields translation table
2467
2468
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2469
    TableList::cleanup_items()
1 by brian
clean slate
2470
*/
2471
327.2.4 by Brian Aker
Refactoring table.h
2472
void TableList::cleanup_items()
1 by brian
clean slate
2473
{
2474
  if (!field_translation)
2475
    return;
2476
2477
  for (Field_translator *transl= field_translation;
2478
       transl < field_translation_end;
2479
       transl++)
2480
    transl->item->walk(&Item::cleanup_processor, 0, 0);
2481
}
2482
2483
2484
/*
2485
  Set insert_values buffer
2486
2487
  SYNOPSIS
2488
    set_insert_values()
2489
    mem_root   memory pool for allocating
2490
2491
  RETURN
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2492
    false - OK
1 by brian
clean slate
2493
    TRUE  - out of memory
2494
*/
2495
327.2.4 by Brian Aker
Refactoring table.h
2496
bool TableList::set_insert_values(MEM_ROOT *mem_root)
1 by brian
clean slate
2497
{
2498
  if (table)
2499
  {
2500
    if (!table->insert_values &&
2501
        !(table->insert_values= (uchar *)alloc_root(mem_root,
2502
                                                   table->s->rec_buff_length)))
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2503
      return true;
1 by brian
clean slate
2504
  }
2505
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2506
  return false;
1 by brian
clean slate
2507
}
2508
2509
2510
/*
2511
  Test if this is a leaf with respect to name resolution.
2512
2513
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2514
    TableList::is_leaf_for_name_resolution()
1 by brian
clean slate
2515
2516
  DESCRIPTION
2517
    A table reference is a leaf with respect to name resolution if
2518
    it is either a leaf node in a nested join tree (table, view,
2519
    schema table, subquery), or an inner node that represents a
2520
    NATURAL/USING join, or a nested join with materialized join
2521
    columns.
2522
2523
  RETURN
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2524
    TRUE if a leaf, false otherwise.
1 by brian
clean slate
2525
*/
327.2.4 by Brian Aker
Refactoring table.h
2526
bool TableList::is_leaf_for_name_resolution()
1 by brian
clean slate
2527
{
2528
  return (is_natural_join || is_join_columns_complete || !nested_join);
2529
}
2530
2531
2532
/*
2533
  Retrieve the first (left-most) leaf in a nested join tree with
2534
  respect to name resolution.
2535
2536
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2537
    TableList::first_leaf_for_name_resolution()
1 by brian
clean slate
2538
2539
  DESCRIPTION
2540
    Given that 'this' is a nested table reference, recursively walk
2541
    down the left-most children of 'this' until we reach a leaf
2542
    table reference with respect to name resolution.
2543
2544
  IMPLEMENTATION
2545
    The left-most child of a nested table reference is the last element
2546
    in the list of children because the children are inserted in
2547
    reverse order.
2548
2549
  RETURN
2550
    If 'this' is a nested table reference - the left-most child of
2551
      the tree rooted in 'this',
2552
    else return 'this'
2553
*/
2554
327.2.4 by Brian Aker
Refactoring table.h
2555
TableList *TableList::first_leaf_for_name_resolution()
1 by brian
clean slate
2556
{
327.2.4 by Brian Aker
Refactoring table.h
2557
  TableList *cur_table_ref= NULL;
2558
  nested_join_st *cur_nested_join;
1 by brian
clean slate
2559
2560
  if (is_leaf_for_name_resolution())
2561
    return this;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2562
  assert(nested_join);
1 by brian
clean slate
2563
2564
  for (cur_nested_join= nested_join;
2565
       cur_nested_join;
2566
       cur_nested_join= cur_table_ref->nested_join)
2567
  {
327.2.4 by Brian Aker
Refactoring table.h
2568
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
1 by brian
clean slate
2569
    cur_table_ref= it++;
2570
    /*
2571
      If the current nested join is a RIGHT JOIN, the operands in
2572
      'join_list' are in reverse order, thus the first operand is
2573
      already at the front of the list. Otherwise the first operand
2574
      is in the end of the list of join operands.
2575
    */
2576
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2577
    {
327.2.4 by Brian Aker
Refactoring table.h
2578
      TableList *next;
1 by brian
clean slate
2579
      while ((next= it++))
2580
        cur_table_ref= next;
2581
    }
2582
    if (cur_table_ref->is_leaf_for_name_resolution())
2583
      break;
2584
  }
2585
  return cur_table_ref;
2586
}
2587
2588
2589
/*
2590
  Retrieve the last (right-most) leaf in a nested join tree with
2591
  respect to name resolution.
2592
2593
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2594
    TableList::last_leaf_for_name_resolution()
1 by brian
clean slate
2595
2596
  DESCRIPTION
2597
    Given that 'this' is a nested table reference, recursively walk
2598
    down the right-most children of 'this' until we reach a leaf
2599
    table reference with respect to name resolution.
2600
2601
  IMPLEMENTATION
2602
    The right-most child of a nested table reference is the first
2603
    element in the list of children because the children are inserted
2604
    in reverse order.
2605
2606
  RETURN
2607
    - If 'this' is a nested table reference - the right-most child of
2608
      the tree rooted in 'this',
2609
    - else - 'this'
2610
*/
2611
327.2.4 by Brian Aker
Refactoring table.h
2612
TableList *TableList::last_leaf_for_name_resolution()
1 by brian
clean slate
2613
{
327.2.4 by Brian Aker
Refactoring table.h
2614
  TableList *cur_table_ref= this;
2615
  nested_join_st *cur_nested_join;
1 by brian
clean slate
2616
2617
  if (is_leaf_for_name_resolution())
2618
    return this;
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2619
  assert(nested_join);
1 by brian
clean slate
2620
2621
  for (cur_nested_join= nested_join;
2622
       cur_nested_join;
2623
       cur_nested_join= cur_table_ref->nested_join)
2624
  {
2625
    cur_table_ref= cur_nested_join->join_list.head();
2626
    /*
2627
      If the current nested is a RIGHT JOIN, the operands in
2628
      'join_list' are in reverse order, thus the last operand is in the
2629
      end of the list.
2630
    */
2631
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2632
    {
327.2.4 by Brian Aker
Refactoring table.h
2633
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
2634
      TableList *next;
1 by brian
clean slate
2635
      cur_table_ref= it++;
2636
      while ((next= it++))
2637
        cur_table_ref= next;
2638
    }
2639
    if (cur_table_ref->is_leaf_for_name_resolution())
2640
      break;
2641
  }
2642
  return cur_table_ref;
2643
}
2644
2645
2646
/*****************************************************************************
2647
  Functions to handle column usage bitmaps (read_set, write_set etc...)
2648
*****************************************************************************/
2649
2650
/* Reset all columns bitmaps */
2651
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2652
void Table::clear_column_bitmaps()
1 by brian
clean slate
2653
{
2654
  /*
2655
    Reset column read/write usage. It's identical to:
2656
    bitmap_clear_all(&table->def_read_set);
2657
    bitmap_clear_all(&table->def_write_set);
2658
  */
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
2659
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
1 by brian
clean slate
2660
  column_bitmaps_set(&def_read_set, &def_write_set);
2661
}
2662
2663
2664
/*
2665
  Tell handler we are going to call position() and rnd_pos() later.
2666
  
2667
  NOTES:
2668
  This is needed for handlers that uses the primary key to find the
2669
  row. In this case we have to extend the read bitmap with the primary
2670
  key fields.
2671
*/
2672
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2673
void Table::prepare_for_position()
1 by brian
clean slate
2674
{
2675
2676
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2677
      s->primary_key < MAX_KEY)
2678
  {
2679
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
2680
    /* signal change */
2681
    file->column_bitmaps_signal();
2682
  }
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
2683
  return;
1 by brian
clean slate
2684
}
2685
2686
2687
/*
2688
  Mark that only fields from one key is used
2689
2690
  NOTE:
2691
    This changes the bitmap to use the tmp bitmap
2692
    After this, you can't access any other columns in the table until
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2693
    bitmaps are reset, for example with Table::clear_column_bitmaps()
2694
    or Table::restore_column_maps_after_mark_index()
1 by brian
clean slate
2695
*/
2696
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2697
void Table::mark_columns_used_by_index(uint index)
1 by brian
clean slate
2698
{
2699
  MY_BITMAP *bitmap= &tmp_set;
2700
2701
  (void) file->extra(HA_EXTRA_KEYREAD);
2702
  bitmap_clear_all(bitmap);
2703
  mark_columns_used_by_index_no_reset(index, bitmap);
2704
  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
2705
  return;
1 by brian
clean slate
2706
}
2707
2708
2709
/*
2710
  Restore to use normal column maps after key read
2711
2712
  NOTES
2713
    This reverse the change done by mark_columns_used_by_index
2714
2715
  WARNING
2716
    For this to work, one must have the normal table maps in place
2717
    when calling mark_columns_used_by_index
2718
*/
2719
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2720
void Table::restore_column_maps_after_mark_index()
1 by brian
clean slate
2721
{
2722
2723
  key_read= 0;
2724
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2725
  default_column_bitmaps();
2726
  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
2727
  return;
1 by brian
clean slate
2728
}
2729
2730
2731
/*
2732
  mark columns used by key, but don't reset other fields
2733
*/
2734
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2735
void Table::mark_columns_used_by_index_no_reset(uint index,
1 by brian
clean slate
2736
                                                   MY_BITMAP *bitmap)
2737
{
2738
  KEY_PART_INFO *key_part= key_info[index].key_part;
2739
  KEY_PART_INFO *key_part_end= (key_part +
2740
                                key_info[index].key_parts);
2741
  for (;key_part != key_part_end; key_part++)
2742
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
2743
}
2744
2745
2746
/*
2747
  Mark auto-increment fields as used fields in both read and write maps
2748
2749
  NOTES
2750
    This is needed in insert & update as the auto-increment field is
2751
    always set and sometimes read.
2752
*/
2753
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2754
void Table::mark_auto_increment_column()
1 by brian
clean slate
2755
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2756
  assert(found_next_number_field);
1 by brian
clean slate
2757
  /*
2758
    We must set bit in read set as update_auto_increment() is using the
2759
    store() to check overflow of auto_increment values
2760
  */
2761
  bitmap_set_bit(read_set, found_next_number_field->field_index);
2762
  bitmap_set_bit(write_set, found_next_number_field->field_index);
2763
  if (s->next_number_keypart)
2764
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
2765
  file->column_bitmaps_signal();
2766
}
2767
2768
2769
/*
2770
  Mark columns needed for doing an delete of a row
2771
2772
  DESCRIPTON
2773
    Some table engines don't have a cursor on the retrieve rows
2774
    so they need either to use the primary key or all columns to
2775
    be able to delete a row.
2776
2777
    If the engine needs this, the function works as follows:
2778
    - If primary key exits, mark the primary key columns to be read.
2779
    - If not, mark all columns to be read
2780
2781
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2782
    mark all key columns as 'to-be-read'. This allows the engine to
2783
    loop over the given record to find all keys and doesn't have to
2784
    retrieve the row again.
2785
*/
2786
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2787
void Table::mark_columns_needed_for_delete()
1 by brian
clean slate
2788
{
2789
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2790
  {
2791
    Field **reg_field;
2792
    for (reg_field= field ; *reg_field ; reg_field++)
2793
    {
2794
      if ((*reg_field)->flags & PART_KEY_FLAG)
2795
        bitmap_set_bit(read_set, (*reg_field)->field_index);
2796
    }
2797
    file->column_bitmaps_signal();
2798
  }
2799
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
2800
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
2801
  {
2802
    /*
2803
      If the handler has no cursor capabilites, or we have row-based
2804
      replication active for the current statement, we have to read
2805
      either the primary key, the hidden primary key or all columns to
2806
      be able to do an delete
2807
    */
2808
    if (s->primary_key == MAX_KEY)
2809
      file->use_hidden_primary_key();
2810
    else
2811
    {
2812
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
2813
      file->column_bitmaps_signal();
2814
    }
2815
  }
2816
}
2817
2818
2819
/*
2820
  Mark columns needed for doing an update of a row
2821
2822
  DESCRIPTON
2823
    Some engines needs to have all columns in an update (to be able to
2824
    build a complete row). If this is the case, we mark all not
2825
    updated columns to be read.
2826
2827
    If this is no the case, we do like in the delete case and mark
2828
    if neeed, either the primary key column or all columns to be read.
2829
    (see mark_columns_needed_for_delete() for details)
2830
2831
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2832
    mark all USED key columns as 'to-be-read'. This allows the engine to
2833
    loop over the given record to find all changed keys and doesn't have to
2834
    retrieve the row again.
2835
*/
2836
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2837
void Table::mark_columns_needed_for_update()
1 by brian
clean slate
2838
{
2839
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2840
  {
2841
    /* Mark all used key columns for read */
2842
    Field **reg_field;
2843
    for (reg_field= field ; *reg_field ; reg_field++)
2844
    {
2845
      /* Merge keys is all keys that had a column refered to in the query */
2846
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
2847
        bitmap_set_bit(read_set, (*reg_field)->field_index);
2848
    }
2849
    file->column_bitmaps_signal();
2850
  }
2851
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
2852
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
2853
  {
2854
    /*
2855
      If the handler has no cursor capabilites, or we have row-based
2856
      logging active for the current statement, we have to read either
2857
      the primary key, the hidden primary key or all columns to be
2858
      able to do an update
2859
    */
2860
    if (s->primary_key == MAX_KEY)
2861
      file->use_hidden_primary_key();
2862
    else
2863
    {
2864
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
2865
      file->column_bitmaps_signal();
2866
    }
2867
  }
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
2868
  return;
1 by brian
clean slate
2869
}
2870
2871
2872
/*
2873
  Mark columns the handler needs for doing an insert
2874
2875
  For now, this is used to mark fields used by the trigger
2876
  as changed.
2877
*/
2878
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2879
void Table::mark_columns_needed_for_insert()
1 by brian
clean slate
2880
{
2881
  if (found_next_number_field)
2882
    mark_auto_increment_column();
2883
}
2884
2885
/*
2886
  Cleanup this table for re-execution.
2887
2888
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2889
    TableList::reinit_before_use()
1 by brian
clean slate
2890
*/
2891
327.2.4 by Brian Aker
Refactoring table.h
2892
void TableList::reinit_before_use(THD *thd)
1 by brian
clean slate
2893
{
2894
  /*
2895
    Reset old pointers to TABLEs: they are not valid since the tables
2896
    were closed in the end of previous prepare or execute call.
2897
  */
2898
  table= 0;
2899
  /* Reset is_schema_table_processed value(needed for I_S tables */
2900
  schema_table_state= NOT_PROCESSED;
2901
327.2.4 by Brian Aker
Refactoring table.h
2902
  TableList *embedded; /* The table at the current level of nesting. */
2903
  TableList *parent_embedding= this; /* The parent nested table reference. */
1 by brian
clean slate
2904
  do
2905
  {
2906
    embedded= parent_embedding;
2907
    if (embedded->prep_on_expr)
2908
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
2909
    parent_embedding= embedded->embedding;
2910
  }
2911
  while (parent_embedding &&
2912
         parent_embedding->nested_join->join_list.head() == embedded);
2913
}
2914
2915
/*
2916
  Return subselect that contains the FROM list this table is taken from
2917
2918
  SYNOPSIS
327.2.4 by Brian Aker
Refactoring table.h
2919
    TableList::containing_subselect()
1 by brian
clean slate
2920
 
2921
  RETURN
2922
    Subselect item for the subquery that contains the FROM list
2923
    this table is taken from if there is any
2924
    0 - otherwise
2925
2926
*/
2927
327.2.4 by Brian Aker
Refactoring table.h
2928
Item_subselect *TableList::containing_subselect()
1 by brian
clean slate
2929
{    
2930
  return (select_lex ? select_lex->master_unit()->item : 0);
2931
}
2932
2933
/*
2934
  Compiles the tagged hints list and fills up the bitmasks.
2935
2936
  SYNOPSIS
2937
    process_index_hints()
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2938
      table         the Table to operate on.
1 by brian
clean slate
2939
2940
  DESCRIPTION
2941
    The parser collects the index hints for each table in a "tagged list" 
327.2.4 by Brian Aker
Refactoring table.h
2942
    (TableList::index_hints). Using the information in this tagged list
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2943
    this function sets the members Table::keys_in_use_for_query, 
2944
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
2945
    Table::force_index and Table::covering_keys.
1 by brian
clean slate
2946
2947
    Current implementation of the runtime does not allow mixing FORCE INDEX
2948
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
2949
    (if non-empty) is appended to the USE INDEX list and a flag is set.
2950
2951
    Multiple hints of the same kind are processed so that each clause 
2952
    is applied to what is computed in the previous clause.
2953
    For example:
2954
        USE INDEX (i1) USE INDEX (i2)
2955
    is equivalent to
2956
        USE INDEX (i1,i2)
2957
    and means "consider only i1 and i2".
2958
        
2959
    Similarly
2960
        USE INDEX () USE INDEX (i1)
2961
    is equivalent to
2962
        USE INDEX (i1)
2963
    and means "consider only the index i1"
2964
2965
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
2966
    not an error.
2967
        
2968
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
2969
    order:
2970
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
2971
      2. All IGNORE INDEX
2972
2973
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
2974
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
2975
2976
    As an optimization if there is a covering index, and we have 
327.2.3 by Brian Aker
Refactoring of class Table
2977
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part, 
2978
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
1 by brian
clean slate
2979
2980
  RETURN VALUE
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2981
    false                no errors found
1 by brian
clean slate
2982
    TRUE                 found and reported an error.
2983
*/
327.2.4 by Brian Aker
Refactoring table.h
2984
bool TableList::process_index_hints(Table *tbl)
1 by brian
clean slate
2985
{
2986
  /* initialize the result variables */
2987
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
2988
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
2989
2990
  /* index hint list processing */
2991
  if (index_hints)
2992
  {
2993
    key_map index_join[INDEX_HINT_FORCE + 1];
2994
    key_map index_order[INDEX_HINT_FORCE + 1];
2995
    key_map index_group[INDEX_HINT_FORCE + 1];
2996
    Index_hint *hint;
2997
    int type;
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
2998
    bool have_empty_use_join= false, have_empty_use_order= false, 
2999
         have_empty_use_group= false;
1 by brian
clean slate
3000
    List_iterator <Index_hint> iter(*index_hints);
3001
3002
    /* initialize temporary variables used to collect hints of each kind */
3003
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
3004
    {
3005
      index_join[type].clear_all();
3006
      index_order[type].clear_all();
3007
      index_group[type].clear_all();
3008
    }
3009
3010
    /* iterate over the hints list */
3011
    while ((hint= iter++))
3012
    {
3013
      uint pos;
3014
3015
      /* process empty USE INDEX () */
3016
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
3017
      {
3018
        if (hint->clause & INDEX_HINT_MASK_JOIN)
3019
        {
3020
          index_join[hint->type].clear_all();
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
3021
          have_empty_use_join= true;
1 by brian
clean slate
3022
        }
3023
        if (hint->clause & INDEX_HINT_MASK_ORDER)
3024
        {
3025
          index_order[hint->type].clear_all();
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
3026
          have_empty_use_order= true;
1 by brian
clean slate
3027
        }
3028
        if (hint->clause & INDEX_HINT_MASK_GROUP)
3029
        {
3030
          index_group[hint->type].clear_all();
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
3031
          have_empty_use_group= true;
1 by brian
clean slate
3032
        }
3033
        continue;
3034
      }
3035
3036
      /* 
3037
        Check if an index with the given name exists and get his offset in 
3038
        the keys bitmask for the table 
3039
      */
3040
      if (tbl->s->keynames.type_names == 0 ||
3041
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3042
                          hint->key_name.length, 1)) <= 0)
3043
      {
3044
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
3045
        return 1;
3046
      }
3047
3048
      pos--;
3049
3050
      /* add to the appropriate clause mask */
3051
      if (hint->clause & INDEX_HINT_MASK_JOIN)
3052
        index_join[hint->type].set_bit (pos);
3053
      if (hint->clause & INDEX_HINT_MASK_ORDER)
3054
        index_order[hint->type].set_bit (pos);
3055
      if (hint->clause & INDEX_HINT_MASK_GROUP)
3056
        index_group[hint->type].set_bit (pos);
3057
    }
3058
3059
    /* cannot mix USE INDEX and FORCE INDEX */
3060
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3061
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3062
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
3063
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
3064
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
3065
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
3066
    {
3067
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
3068
               index_hint_type_name[INDEX_HINT_FORCE]);
3069
      return 1;
3070
    }
3071
3072
    /* process FORCE INDEX as USE INDEX with a flag */
3073
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3074
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3075
        !index_group[INDEX_HINT_FORCE].is_clear_all())
3076
    {
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
3077
      tbl->force_index= true;
1 by brian
clean slate
3078
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
3079
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
3080
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
3081
    }
3082
3083
    /* apply USE INDEX */
3084
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
3085
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
3086
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
3087
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
3088
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
3089
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
3090
3091
    /* apply IGNORE INDEX */
3092
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
3093
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
3094
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
3095
  }
3096
3097
  /* make sure covering_keys don't include indexes disabled with a hint */
3098
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
3099
  return 0;
3100
}
3101
3102
354 by Brian Aker
Refactor of Table methods.
3103
size_t Table::max_row_length(const uchar *data)
1 by brian
clean slate
3104
{
354 by Brian Aker
Refactor of Table methods.
3105
  size_t length= getRecordLength() + 2 * sizeFields();
3106
  uint *const beg= getBlobField();
3107
  uint *const end= beg + sizeBlobFields();
1 by brian
clean slate
3108
3109
  for (uint *ptr= beg ; ptr != end ; ++ptr)
3110
  {
354 by Brian Aker
Refactor of Table methods.
3111
    Field_blob* const blob= (Field_blob*) field[*ptr];
1 by brian
clean slate
3112
    length+= blob->get_length((const uchar*)
354 by Brian Aker
Refactor of Table methods.
3113
                              (data + blob->offset(record[0]))) +
1 by brian
clean slate
3114
      HA_KEY_BLOB_LENGTH;
3115
  }
3116
  return length;
3117
}
3118
3119
/*
3120
  Check type of .frm if we are not going to parse it
3121
3122
  SYNOPSIS
3123
  mysql_frm_type()
3124
  path        path to file
3125
3126
  RETURN
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3127
  false       error
3128
  true       table
77.1.45 by Monty Taylor
Warning fixes.
3129
*/
1 by brian
clean slate
3130
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3131
bool mysql_frm_type(THD *thd __attribute__((unused)),
3132
                    char *path, enum legacy_db_type *dbt)
77.1.45 by Monty Taylor
Warning fixes.
3133
{
1 by brian
clean slate
3134
  File file;
3135
  uchar header[10];     /* This should be optimized */
3136
  int error;
3137
3138
  *dbt= DB_TYPE_UNKNOWN;
3139
3140
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3141
    return false;
1 by brian
clean slate
3142
  error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
3143
  my_close(file, MYF(MY_WME));
3144
3145
  if (error)
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3146
    return false;
1 by brian
clean slate
3147
3148
  /*  
3149
    This is just a check for DB_TYPE. We'll return default unknown type
3150
    if the following test is true (arg #3). This should not have effect
3151
    on return value from this function (default FRMTYPE_TABLE)
3152
   */  
3153
  if (header[0] != (uchar) 254 || header[1] != 1 ||
3154
      (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
3155
       (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3156
    return true;
1 by brian
clean slate
3157
3158
  *dbt= (enum legacy_db_type) (uint) *(header + 3);
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3159
  return true;                   // Is probably a .frm table
1 by brian
clean slate
3160
}
3161
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3162
/****************************************************************************
3163
 Functions for creating temporary tables.
3164
****************************************************************************/
3165
3166
3167
/* Prototypes */
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3168
void free_tmp_table(THD *thd, Table *entry);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3169
3170
/**
3171
  Create field for temporary table from given field.
3172
3173
  @param thd	       Thread handler
3174
  @param org_field    field from which new field will be created
3175
  @param name         New field name
3176
  @param table	       Temporary table
3177
  @param item	       !=NULL if item->result_field should point to new field.
3178
                      This is relevant for how fill_record() is going to work:
3179
                      If item != NULL then fill_record() will update
3180
                      the record in the original table.
3181
                      If item == NULL then fill_record() will update
3182
                      the temporary table
3183
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
3184
                               field instead of blob.
3185
3186
  @retval
3187
    NULL		on error
3188
  @retval
3189
    new_created field
3190
*/
3191
3192
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3193
                                   const char *name, Table *table,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3194
                                   Item_field *item, uint convert_blob_length)
3195
{
3196
  Field *new_field;
3197
3198
  /* 
3199
    Make sure that the blob fits into a Field_varstring which has 
3200
    2-byte lenght. 
3201
  */
3202
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
3203
      (org_field->flags & BLOB_FLAG))
3204
    new_field= new Field_varstring(convert_blob_length,
3205
                                   org_field->maybe_null(),
3206
                                   org_field->field_name, table->s,
3207
                                   org_field->charset());
3208
  else
3209
    new_field= org_field->new_field(thd->mem_root, table,
3210
                                    table == org_field->table);
3211
  if (new_field)
3212
  {
3213
    new_field->init(table);
3214
    new_field->orig_table= org_field->orig_table;
3215
    if (item)
3216
      item->result_field= new_field;
3217
    else
3218
      new_field->field_name= name;
3219
    new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
3220
    if (org_field->maybe_null() || (item && item->maybe_null))
3221
      new_field->flags&= ~NOT_NULL_FLAG;	// Because of outer join
3222
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
3223
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
3224
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
3225
      ((Field_double *) new_field)->not_fixed= true;
3226
  }
3227
  return new_field;
3228
}
3229
3230
/**
3231
  Create field for temporary table using type of given item.
3232
3233
  @param thd                   Thread handler
3234
  @param item                  Item to create a field for
3235
  @param table                 Temporary table
3236
  @param copy_func             If set and item is a function, store copy of
3237
                               item in this array
3238
  @param modify_item           1 if item->result_field should point to new
3239
                               item. This is relevent for how fill_record()
3240
                               is going to work:
3241
                               If modify_item is 1 then fill_record() will
3242
                               update the record in the original table.
3243
                               If modify_item is 0 then fill_record() will
3244
                               update the temporary table
3245
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
3246
                               field instead of blob.
3247
3248
  @retval
3249
    0  on error
3250
  @retval
3251
    new_created field
3252
*/
3253
3254
static Field *create_tmp_field_from_item(THD *thd __attribute__((unused)),
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3255
                                         Item *item, Table *table,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3256
                                         Item ***copy_func, bool modify_item,
3257
                                         uint convert_blob_length)
3258
{
3259
  bool maybe_null= item->maybe_null;
3260
  Field *new_field;
3261
3262
  switch (item->result_type()) {
3263
  case REAL_RESULT:
3264
    new_field= new Field_double(item->max_length, maybe_null,
3265
                                item->name, item->decimals, true);
3266
    break;
3267
  case INT_RESULT:
3268
    /* 
3269
      Select an integer type with the minimal fit precision.
3270
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
3271
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
3272
      Field_long : make them Field_int64_t.  
3273
    */
3274
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
3275
      new_field=new Field_int64_t(item->max_length, maybe_null,
3276
                                   item->name, item->unsigned_flag);
3277
    else
3278
      new_field=new Field_long(item->max_length, maybe_null,
3279
                               item->name, item->unsigned_flag);
3280
    break;
3281
  case STRING_RESULT:
3282
    assert(item->collation.collation);
3283
  
3284
    enum enum_field_types type;
3285
    /*
3286
      DATE/TIME fields have STRING_RESULT result type. 
3287
      To preserve type they needed to be handled separately.
3288
    */
3289
    if ((type= item->field_type()) == DRIZZLE_TYPE_DATETIME ||
3290
        type == DRIZZLE_TYPE_TIME || type == DRIZZLE_TYPE_NEWDATE ||
3291
        type == DRIZZLE_TYPE_TIMESTAMP)
3292
      new_field= item->tmp_table_field_from_field_type(table, 1);
3293
    /* 
3294
      Make sure that the blob fits into a Field_varstring which has 
3295
      2-byte lenght. 
3296
    */
3297
    else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
3298
             convert_blob_length <= Field_varstring::MAX_SIZE && 
3299
             convert_blob_length)
3300
      new_field= new Field_varstring(convert_blob_length, maybe_null,
3301
                                     item->name, table->s,
3302
                                     item->collation.collation);
3303
    else
3304
      new_field= item->make_string_field(table);
3305
    new_field->set_derivation(item->collation.derivation);
3306
    break;
3307
  case DECIMAL_RESULT:
3308
  {
3309
    uint8_t dec= item->decimals;
3310
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
3311
    uint32_t len= item->max_length;
3312
3313
    /*
3314
      Trying to put too many digits overall in a DECIMAL(prec,dec)
3315
      will always throw a warning. We must limit dec to
3316
      DECIMAL_MAX_SCALE however to prevent an assert() later.
3317
    */
3318
3319
    if (dec > 0)
3320
    {
3321
      signed int overflow;
3322
3323
      dec= min(dec, (uint8_t)DECIMAL_MAX_SCALE);
3324
3325
      /*
3326
        If the value still overflows the field with the corrected dec,
3327
        we'll throw out decimals rather than integers. This is still
3328
        bad and of course throws a truncation warning.
3329
        +1: for decimal point
3330
      */
3331
3332
      overflow= my_decimal_precision_to_length(intg + dec, dec,
3333
                                               item->unsigned_flag) - len;
3334
3335
      if (overflow > 0)
3336
        dec= max(0, dec - overflow);            // too long, discard fract
3337
      else
3338
        len -= item->decimals - dec;            // corrected value fits
3339
    }
3340
3341
    new_field= new Field_new_decimal(len, maybe_null, item->name,
3342
                                     dec, item->unsigned_flag);
3343
    break;
3344
  }
3345
  case ROW_RESULT:
3346
  default:
3347
    // This case should never be choosen
3348
    assert(0);
3349
    new_field= 0;
3350
    break;
3351
  }
3352
  if (new_field)
3353
    new_field->init(table);
3354
    
3355
  if (copy_func && item->is_result_field())
3356
    *((*copy_func)++) = item;			// Save for copy_funcs
3357
  if (modify_item)
3358
    item->set_result_field(new_field);
3359
  if (item->type() == Item::NULL_ITEM)
3360
    new_field->is_created_from_null_item= true;
3361
  return new_field;
3362
}
3363
3364
3365
/**
3366
  Create field for information schema table.
3367
3368
  @param thd		Thread handler
3369
  @param table		Temporary table
3370
  @param item		Item to create a field for
3371
3372
  @retval
3373
    0			on error
3374
  @retval
3375
    new_created field
3376
*/
3377
3378
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3379
                                   Item *item, Table *table)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3380
{
3381
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3382
  {
3383
    Field *field;
3384
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
3385
      field= new Field_blob(item->max_length, item->maybe_null,
3386
                            item->name, item->collation.collation);
3387
    else
3388
      field= new Field_varstring(item->max_length, item->maybe_null,
3389
                                 item->name,
3390
                                 table->s, item->collation.collation);
3391
    if (field)
3392
      field->init(table);
3393
    return field;
3394
  }
3395
  return item->tmp_table_field_from_field_type(table, 0);
3396
}
3397
3398
3399
/**
3400
  Create field for temporary table.
3401
3402
  @param thd		Thread handler
3403
  @param table		Temporary table
3404
  @param item		Item to create a field for
3405
  @param type		Type of item (normally item->type)
3406
  @param copy_func	If set and item is a function, store copy of item
3407
                       in this array
3408
  @param from_field    if field will be created using other field as example,
3409
                       pointer example field will be written here
3410
  @param default_field	If field has a default value field, store it here
3411
  @param group		1 if we are going to do a relative group by on result
3412
  @param modify_item	1 if item->result_field should point to new item.
3413
                       This is relevent for how fill_record() is going to
3414
                       work:
3415
                       If modify_item is 1 then fill_record() will update
3416
                       the record in the original table.
3417
                       If modify_item is 0 then fill_record() will update
3418
                       the temporary table
3419
  @param convert_blob_length If >0 create a varstring(convert_blob_length)
3420
                             field instead of blob.
3421
3422
  @retval
3423
    0			on error
3424
  @retval
3425
    new_created field
3426
*/
3427
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3428
Field *create_tmp_field(THD *thd, Table *table,Item *item, Item::Type type,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3429
                        Item ***copy_func, Field **from_field,
3430
                        Field **default_field,
3431
                        bool group, bool modify_item,
3432
                        bool table_cant_handle_bit_fields __attribute__((unused)),
3433
                        bool make_copy_field,
3434
                        uint convert_blob_length)
3435
{
3436
  Field *result;
3437
  Item::Type orig_type= type;
3438
  Item *orig_item= 0;
3439
3440
  if (type != Item::FIELD_ITEM &&
3441
      item->real_item()->type() == Item::FIELD_ITEM)
3442
  {
3443
    orig_item= item;
3444
    item= item->real_item();
3445
    type= Item::FIELD_ITEM;
3446
  }
3447
3448
  switch (type) {
3449
  case Item::SUM_FUNC_ITEM:
3450
  {
3451
    Item_sum *item_sum=(Item_sum*) item;
3452
    result= item_sum->create_tmp_field(group, table, convert_blob_length);
3453
    if (!result)
3454
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3455
    return result;
3456
  }
3457
  case Item::FIELD_ITEM:
3458
  case Item::DEFAULT_VALUE_ITEM:
3459
  {
3460
    Item_field *field= (Item_field*) item;
3461
    bool orig_modify= modify_item;
3462
    if (orig_type == Item::REF_ITEM)
3463
      modify_item= 0;
3464
    /*
3465
      If item have to be able to store NULLs but underlaid field can't do it,
3466
      create_tmp_field_from_field() can't be used for tmp field creation.
3467
    */
3468
    if (field->maybe_null && !field->field->maybe_null())
3469
    {
3470
      result= create_tmp_field_from_item(thd, item, table, NULL,
3471
                                         modify_item, convert_blob_length);
3472
      *from_field= field->field;
3473
      if (result && modify_item)
3474
        field->result_field= result;
3475
    } 
3476
    else
3477
      result= create_tmp_field_from_field(thd, (*from_field= field->field),
3478
                                          orig_item ? orig_item->name :
3479
                                          item->name,
3480
                                          table,
3481
                                          modify_item ? field :
3482
                                          NULL,
3483
                                          convert_blob_length);
3484
    if (orig_type == Item::REF_ITEM && orig_modify)
3485
      ((Item_ref*)orig_item)->set_result_field(result);
3486
    if (field->field->eq_def(result))
3487
      *default_field= field->field;
3488
    return result;
3489
  }
3490
  /* Fall through */
3491
  case Item::FUNC_ITEM:
3492
    /* Fall through */
3493
  case Item::COND_ITEM:
3494
  case Item::FIELD_AVG_ITEM:
3495
  case Item::FIELD_STD_ITEM:
3496
  case Item::SUBSELECT_ITEM:
3497
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
3498
  case Item::PROC_ITEM:
3499
  case Item::INT_ITEM:
3500
  case Item::REAL_ITEM:
3501
  case Item::DECIMAL_ITEM:
3502
  case Item::STRING_ITEM:
3503
  case Item::REF_ITEM:
3504
  case Item::NULL_ITEM:
3505
  case Item::VARBIN_ITEM:
3506
    if (make_copy_field)
3507
    {
3508
      assert(((Item_result_field*)item)->result_field);
3509
      *from_field= ((Item_result_field*)item)->result_field;
3510
    }
3511
    return create_tmp_field_from_item(thd, item, table,
3512
                                      (make_copy_field ? 0 : copy_func),
3513
                                       modify_item, convert_blob_length);
3514
  case Item::TYPE_HOLDER:  
3515
    result= ((Item_type_holder *)item)->make_field_by_type(table);
3516
    result->set_derivation(item->collation.derivation);
3517
    return result;
3518
  default:					// Dosen't have to be stored
3519
    return 0;
3520
  }
3521
}
3522
3523
/**
3524
  Create a temp table according to a field list.
3525
3526
  Given field pointers are changed to point at tmp_table for
3527
  send_fields. The table object is self contained: it's
3528
  allocated in its own memory root, as well as Field objects
3529
  created for table columns.
3530
  This function will replace Item_sum items in 'fields' list with
3531
  corresponding Item_field items, pointing at the fields in the
3532
  temporary table, unless this was prohibited by true
3533
  value of argument save_sum_fields. The Item_field objects
3534
  are created in THD memory root.
3535
3536
  @param thd                  thread handle
3537
  @param param                a description used as input to create the table
3538
  @param fields               list of items that will be used to define
3539
                              column types of the table (also see NOTES)
3540
  @param group                TODO document
3541
  @param distinct             should table rows be distinct
3542
  @param save_sum_fields      see NOTES
3543
  @param select_options
3544
  @param rows_limit
3545
  @param table_alias          possible name of the temporary table that can
3546
                              be used for name resolving; can be "".
3547
*/
3548
3549
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3550
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3551
#define RATIO_TO_PACK_ROWS	       2
3552
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
3553
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3554
Table *
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3555
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
327.2.3 by Brian Aker
Refactoring of class Table
3556
		 order_st *group, bool distinct, bool save_sum_fields,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3557
		 uint64_t select_options, ha_rows rows_limit,
3558
		 char *table_alias)
3559
{
3560
  MEM_ROOT *mem_root_save, own_root;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3561
  Table *table;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3562
  TABLE_SHARE *share;
3563
  uint	i,field_count,null_count,null_pack_length;
3564
  uint  copy_func_count= param->func_count;
3565
  uint  hidden_null_count, hidden_null_pack_length, hidden_field_count;
3566
  uint  blob_count,group_null_items, string_count;
3567
  uint  temp_pool_slot=MY_BIT_NONE;
3568
  uint fieldnr= 0;
3569
  ulong reclength, string_total_length;
3570
  bool  using_unique_constraint= 0;
3571
  bool  use_packed_rows= 0;
3572
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
3573
  char  *tmpname,path[FN_REFLEN];
3574
  uchar	*pos, *group_buff, *bitmaps;
3575
  uchar *null_flags;
3576
  Field **reg_field, **from_field, **default_field;
3577
  uint *blob_field;
3578
  Copy_field *copy=0;
3579
  KEY *keyinfo;
3580
  KEY_PART_INFO *key_part_info;
3581
  Item **copy_func;
3582
  MI_COLUMNDEF *recinfo;
3583
  uint total_uneven_bit_length= 0;
3584
  bool force_copy_fields= param->force_copy_fields;
3585
3586
  status_var_increment(thd->status_var.created_tmp_tables);
3587
3588
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3589
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
3590
3591
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
3592
    sprintf(path, "%s_%lx_%i", tmp_file_prefix,
3593
            current_pid, temp_pool_slot);
3594
  else
3595
  {
3596
    /* if we run out of slots or we are not using tempool */
3597
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
3598
            thd->thread_id, thd->tmp_table++);
3599
  }
3600
3601
  /*
3602
    No need to change table name to lower case as we are only creating
3603
    MyISAM or HEAP tables here
3604
  */
3605
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
3606
3607
3608
  if (group)
3609
  {
3610
    if (!param->quick_group)
3611
      group=0;					// Can't use group key
327.2.3 by Brian Aker
Refactoring of class Table
3612
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3613
    {
3614
      /*
3615
        marker == 4 means two things:
3616
        - store NULLs in the key, and
3617
        - convert BIT fields to 64-bit long, needed because MEMORY tables
3618
          can't index BIT fields.
3619
      */
3620
      (*tmp->item)->marker= 4;
3621
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
3622
	using_unique_constraint=1;
3623
    }
3624
    if (param->group_length >= MAX_BLOB_WIDTH)
3625
      using_unique_constraint=1;
3626
    if (group)
3627
      distinct=0;				// Can't use distinct
3628
  }
3629
3630
  field_count=param->field_count+param->func_count+param->sum_func_count;
3631
  hidden_field_count=param->hidden_field_count;
3632
3633
  /*
3634
    When loose index scan is employed as access method, it already
3635
    computes all groups and the result of all aggregate functions. We
3636
    make space for the items of the aggregate function in the list of
3637
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
3638
    these items are stored in the temporary table.
3639
  */
3640
  if (param->precomputed_group_by)
3641
    copy_func_count+= param->sum_func_count;
3642
  
3643
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3644
3645
  if (!multi_alloc_root(&own_root,
3646
                        &table, sizeof(*table),
3647
                        &share, sizeof(*share),
3648
                        &reg_field, sizeof(Field*) * (field_count+1),
3649
                        &default_field, sizeof(Field*) * (field_count),
3650
                        &blob_field, sizeof(uint)*(field_count+1),
3651
                        &from_field, sizeof(Field*)*field_count,
3652
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
3653
                        &param->keyinfo, sizeof(*param->keyinfo),
3654
                        &key_part_info,
3655
                        sizeof(*key_part_info)*(param->group_parts+1),
3656
                        &param->start_recinfo,
3657
                        sizeof(*param->recinfo)*(field_count*2+4),
3658
                        &tmpname, (uint) strlen(path)+1,
3659
                        &group_buff, (group && ! using_unique_constraint ?
3660
                                      param->group_length : 0),
3661
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3662
                        NullS))
3663
  {
3664
    if (temp_pool_slot != MY_BIT_NONE)
3665
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3666
    return(NULL);				/* purecov: inspected */
3667
  }
3668
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
3669
  if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
3670
  {
3671
    if (temp_pool_slot != MY_BIT_NONE)
3672
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3673
    free_root(&own_root, MYF(0));               /* purecov: inspected */
3674
    return(NULL);				/* purecov: inspected */
3675
  }
3676
  param->items_to_copy= copy_func;
3677
  stpcpy(tmpname,path);
3678
  /* make table according to fields */
3679
3680
  memset(table, 0, sizeof(*table));
3681
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
3682
  memset(default_field, 0, sizeof(Field*) * (field_count));
3683
  memset(from_field, 0, sizeof(Field*)*field_count);
3684
3685
  table->mem_root= own_root;
3686
  mem_root_save= thd->mem_root;
3687
  thd->mem_root= &table->mem_root;
3688
3689
  table->field=reg_field;
3690
  table->alias= table_alias;
3691
  table->reginfo.lock_type=TL_WRITE;	/* Will be updated */
3692
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
3693
  table->map=1;
3694
  table->temp_pool_slot = temp_pool_slot;
3695
  table->copy_blobs= 1;
3696
  table->in_use= thd;
3697
  table->quick_keys.init();
3698
  table->covering_keys.init();
3699
  table->keys_in_use_for_query.init();
3700
3701
  table->setShare(share);
3702
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
3703
  share->blob_field= blob_field;
3704
  share->blob_ptr_size= portable_sizeof_char_ptr;
3705
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3706
  share->table_charset= param->table_charset;
3707
  share->primary_key= MAX_KEY;               // Indicate no primary key
3708
  share->keys_for_keyread.init();
3709
  share->keys_in_use.init();
3710
3711
  /* Calculate which type of fields we will store in the temporary table */
3712
3713
  reclength= string_total_length= 0;
3714
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
3715
  param->using_indirect_summary_function=0;
3716
3717
  List_iterator_fast<Item> li(fields);
3718
  Item *item;
3719
  Field **tmp_from_field=from_field;
3720
  while ((item=li++))
3721
  {
3722
    Item::Type type=item->type();
3723
    if (not_all_columns)
3724
    {
3725
      if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
3726
      {
3727
        if (item->used_tables() & OUTER_REF_TABLE_BIT)
3728
          item->update_used_tables();
3729
        if (type == Item::SUBSELECT_ITEM ||
3730
            (item->used_tables() & ~OUTER_REF_TABLE_BIT))
3731
        {
3732
	  /*
3733
	    Mark that the we have ignored an item that refers to a summary
3734
	    function. We need to know this if someone is going to use
3735
	    DISTINCT on the result.
3736
	  */
3737
	  param->using_indirect_summary_function=1;
3738
	  continue;
3739
        }
3740
      }
3741
      if (item->const_item() && (int) hidden_field_count <= 0)
3742
        continue; // We don't have to store this
3743
    }
3744
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
3745
    {						/* Can't calc group yet */
3746
      ((Item_sum*) item)->result_field=0;
3747
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
3748
      {
3749
	Item **argp= ((Item_sum*) item)->args + i;
3750
	Item *arg= *argp;
3751
	if (!arg->const_item())
3752
	{
3753
	  Field *new_field=
3754
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
3755
                             tmp_from_field, &default_field[fieldnr],
3756
                             group != 0,not_all_columns,
3757
                             distinct, 0,
3758
                             param->convert_blob_length);
3759
	  if (!new_field)
3760
	    goto err;					// Should be OOM
3761
	  tmp_from_field++;
3762
	  reclength+=new_field->pack_length();
3763
	  if (new_field->flags & BLOB_FLAG)
3764
	  {
3765
	    *blob_field++= fieldnr;
3766
	    blob_count++;
3767
	  }
3768
	  *(reg_field++)= new_field;
3769
          if (new_field->real_type() == DRIZZLE_TYPE_VARCHAR)
3770
          {
3771
            string_count++;
3772
            string_total_length+= new_field->pack_length();
3773
          }
3774
          thd->mem_root= mem_root_save;
3775
          thd->change_item_tree(argp, new Item_field(new_field));
3776
          thd->mem_root= &table->mem_root;
3777
	  if (!(new_field->flags & NOT_NULL_FLAG))
3778
          {
3779
	    null_count++;
3780
            /*
3781
              new_field->maybe_null() is still false, it will be
3782
              changed below. But we have to setup Item_field correctly
3783
            */
3784
            (*argp)->maybe_null=1;
3785
          }
3786
          new_field->field_index= fieldnr++;
3787
	}
3788
      }
3789
    }
3790
    else
3791
    {
3792
      /*
3793
	The last parameter to create_tmp_field() is a bit tricky:
3794
3795
	We need to set it to 0 in union, to get fill_record() to modify the
3796
	temporary table.
3797
	We need to set it to 1 on multi-table-update and in select to
3798
	write rows to the temporary table.
3799
	We here distinguish between UNION and multi-table-updates by the fact
3800
	that in the later case group is set to the row pointer.
3801
      */
3802
      Field *new_field= (param->schema_table) ?
3803
        create_tmp_field_for_schema(thd, item, table) :
3804
        create_tmp_field(thd, table, item, type, &copy_func,
3805
                         tmp_from_field, &default_field[fieldnr],
3806
                         group != 0,
3807
                         !force_copy_fields &&
3808
                           (not_all_columns || group !=0),
3809
                         /*
3810
                           If item->marker == 4 then we force create_tmp_field
3811
                           to create a 64-bit longs for BIT fields because HEAP
3812
                           tables can't index BIT fields directly. We do the same
3813
                           for distinct, as we want the distinct index to be
3814
                           usable in this case too.
3815
                         */
3816
                         item->marker == 4 || param->bit_fields_as_long,
3817
                         force_copy_fields,
3818
                         param->convert_blob_length);
3819
3820
      if (!new_field)
3821
      {
3822
	if (thd->is_fatal_error)
3823
	  goto err;				// Got OOM
3824
	continue;				// Some kindf of const item
3825
      }
3826
      if (type == Item::SUM_FUNC_ITEM)
3827
	((Item_sum *) item)->result_field= new_field;
3828
      tmp_from_field++;
3829
      reclength+=new_field->pack_length();
3830
      if (!(new_field->flags & NOT_NULL_FLAG))
3831
	null_count++;
3832
      if (new_field->flags & BLOB_FLAG)
3833
      {
3834
        *blob_field++= fieldnr;
3835
	blob_count++;
3836
      }
3837
      if (item->marker == 4 && item->maybe_null)
3838
      {
3839
	group_null_items++;
3840
	new_field->flags|= GROUP_FLAG;
3841
      }
3842
      new_field->field_index= fieldnr++;
3843
      *(reg_field++)= new_field;
3844
    }
3845
    if (!--hidden_field_count)
3846
    {
3847
      /*
3848
        This was the last hidden field; Remember how many hidden fields could
3849
        have null
3850
      */
3851
      hidden_null_count=null_count;
3852
      /*
3853
	We need to update hidden_field_count as we may have stored group
3854
	functions with constant arguments
3855
      */
3856
      param->hidden_field_count= fieldnr;
3857
      null_count= 0;
3858
    }
3859
  }
3860
  assert(fieldnr == (uint) (reg_field - table->field));
3861
  assert(field_count >= (uint) (reg_field - table->field));
3862
  field_count= fieldnr;
3863
  *reg_field= 0;
3864
  *blob_field= 0;				// End marker
3865
  share->fields= field_count;
3866
3867
  /* If result table is small; use a heap */
3868
  /* future: storage engine selection can be made dynamic? */
3869
  if (blob_count || using_unique_constraint ||
3870
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3871
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
3872
  {
3873
    share->db_plugin= ha_lock_engine(0, myisam_hton);
3874
    table->file= get_new_handler(share, &table->mem_root,
3875
                                 share->db_type());
3876
    if (group &&
3877
	(param->group_parts > table->file->max_key_parts() ||
3878
	 param->group_length > table->file->max_key_length()))
3879
      using_unique_constraint=1;
3880
  }
3881
  else
3882
  {
3883
    share->db_plugin= ha_lock_engine(0, heap_hton);
3884
    table->file= get_new_handler(share, &table->mem_root,
3885
                                 share->db_type());
3886
  }
3887
  if (!table->file)
3888
    goto err;
3889
3890
3891
  if (!using_unique_constraint)
3892
    reclength+= group_null_items;	// null flag is stored separately
3893
3894
  share->blob_fields= blob_count;
3895
  if (blob_count == 0)
3896
  {
3897
    /* We need to ensure that first byte is not 0 for the delete link */
3898
    if (param->hidden_field_count)
3899
      hidden_null_count++;
3900
    else
3901
      null_count++;
3902
  }
3903
  hidden_null_pack_length=(hidden_null_count+7)/8;
3904
  null_pack_length= (hidden_null_pack_length +
3905
                     (null_count + total_uneven_bit_length + 7) / 8);
3906
  reclength+=null_pack_length;
3907
  if (!reclength)
3908
    reclength=1;				// Dummy select
3909
  /* Use packed rows if there is blobs or a lot of space to gain */
3910
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
3911
    use_packed_rows= 1;
3912
3913
  share->reclength= reclength;
3914
  {
3915
    uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
3916
    share->rec_buff_length= alloc_length;
3917
    if (!(table->record[0]= (uchar*)
3918
                            alloc_root(&table->mem_root, alloc_length*3)))
3919
      goto err;
3920
    table->record[1]= table->record[0]+alloc_length;
3921
    share->default_values= table->record[1]+alloc_length;
3922
  }
3923
  copy_func[0]=0;				// End marker
3924
  param->func_count= copy_func - param->items_to_copy; 
3925
3926
  table->setup_tmp_table_column_bitmaps(bitmaps);
3927
3928
  recinfo=param->start_recinfo;
3929
  null_flags=(uchar*) table->record[0];
3930
  pos=table->record[0]+ null_pack_length;
3931
  if (null_pack_length)
3932
  {
3933
    memset(recinfo, 0, sizeof(*recinfo));
3934
    recinfo->type=FIELD_NORMAL;
3935
    recinfo->length=null_pack_length;
3936
    recinfo++;
3937
    memset(null_flags, 255, null_pack_length);	// Set null fields
3938
3939
    table->null_flags= (uchar*) table->record[0];
3940
    share->null_fields= null_count+ hidden_null_count;
3941
    share->null_bytes= null_pack_length;
3942
  }
3943
  null_count= (blob_count == 0) ? 1 : 0;
3944
  hidden_field_count=param->hidden_field_count;
3945
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
3946
  {
3947
    Field *field= *reg_field;
3948
    uint length;
3949
    memset(recinfo, 0, sizeof(*recinfo));
3950
3951
    if (!(field->flags & NOT_NULL_FLAG))
3952
    {
3953
      if (field->flags & GROUP_FLAG && !using_unique_constraint)
3954
      {
3955
	/*
3956
	  We have to reserve one byte here for NULL bits,
3957
	  as this is updated by 'end_update()'
3958
	*/
3959
	*pos++=0;				// Null is stored here
3960
	recinfo->length=1;
3961
	recinfo->type=FIELD_NORMAL;
3962
	recinfo++;
3963
	memset(recinfo, 0, sizeof(*recinfo));
3964
      }
3965
      else
3966
      {
3967
	recinfo->null_bit= 1 << (null_count & 7);
3968
	recinfo->null_pos= null_count/8;
3969
      }
3970
      field->move_field(pos,null_flags+null_count/8,
3971
			1 << (null_count & 7));
3972
      null_count++;
3973
    }
3974
    else
3975
      field->move_field(pos,(uchar*) 0,0);
3976
    field->reset();
3977
3978
    /*
3979
      Test if there is a default field value. The test for ->ptr is to skip
3980
      'offset' fields generated by initalize_tables
3981
    */
3982
    if (default_field[i] && default_field[i]->ptr)
3983
    {
3984
      /* 
3985
         default_field[i] is set only in the cases  when 'field' can
3986
         inherit the default value that is defined for the field referred
3987
         by the Item_field object from which 'field' has been created.
3988
      */
3989
      my_ptrdiff_t diff;
3990
      Field *orig_field= default_field[i];
3991
      /* Get the value from default_values */
3992
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
3993
                            orig_field->table->record[0]);
3994
      orig_field->move_field_offset(diff);      // Points now at default_values
3995
      if (orig_field->is_real_null())
3996
        field->set_null();
3997
      else
3998
      {
3999
        field->set_notnull();
4000
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
4001
      }
4002
      orig_field->move_field_offset(-diff);     // Back to record[0]
4003
    } 
4004
4005
    if (from_field[i])
4006
    {						/* Not a table Item */
4007
      copy->set(field,from_field[i],save_sum_fields);
4008
      copy++;
4009
    }
4010
    length=field->pack_length();
4011
    pos+= length;
4012
4013
    /* Make entry for create table */
4014
    recinfo->length=length;
4015
    if (field->flags & BLOB_FLAG)
4016
      recinfo->type= (int) FIELD_BLOB;
4017
    else
4018
      recinfo->type=FIELD_NORMAL;
4019
    if (!--hidden_field_count)
4020
      null_count=(null_count+7) & ~7;		// move to next byte
4021
4022
    // fix table name in field entry
4023
    field->table_name= &table->alias;
4024
  }
4025
4026
  param->copy_field_end=copy;
4027
  param->recinfo=recinfo;
4028
  store_record(table,s->default_values);        // Make empty default record
4029
4030
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)		// No limit
4031
    share->max_rows= ~(ha_rows) 0;
4032
  else
4033
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
4034
                                 min(thd->variables.tmp_table_size,
4035
                                     thd->variables.max_heap_table_size) :
4036
                                 thd->variables.tmp_table_size) /
4037
			         share->reclength);
4038
  set_if_bigger(share->max_rows,1);		// For dummy start options
4039
  /*
4040
    Push the LIMIT clause to the temporary table creation, so that we
4041
    materialize only up to 'rows_limit' records instead of all result records.
4042
  */
4043
  set_if_smaller(share->max_rows, rows_limit);
4044
  param->end_write_records= rows_limit;
4045
4046
  keyinfo= param->keyinfo;
4047
4048
  if (group)
4049
  {
4050
    table->group=group;				/* Table is grouped by key */
4051
    param->group_buff=group_buff;
4052
    share->keys=1;
4053
    share->uniques= test(using_unique_constraint);
4054
    table->key_info=keyinfo;
4055
    keyinfo->key_part=key_part_info;
4056
    keyinfo->flags=HA_NOSAME;
4057
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
4058
    keyinfo->key_length=0;
4059
    keyinfo->rec_per_key=0;
4060
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
4061
    keyinfo->name= (char*) "group_key";
327.2.3 by Brian Aker
Refactoring of class Table
4062
    order_st *cur_group= group;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4063
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
4064
    {
4065
      Field *field=(*cur_group->item)->get_tmp_table_field();
4066
      bool maybe_null=(*cur_group->item)->maybe_null;
4067
      key_part_info->null_bit=0;
4068
      key_part_info->field=  field;
4069
      key_part_info->offset= field->offset(table->record[0]);
4070
      key_part_info->length= (uint16_t) field->key_length();
4071
      key_part_info->type=   (uint8_t) field->key_type();
4072
      key_part_info->key_type =
4073
	((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
4074
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
4075
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
4076
	0 : FIELDFLAG_BINARY;
4077
      if (!using_unique_constraint)
4078
      {
4079
	cur_group->buff=(char*) group_buff;
4080
	if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
4081
                                                     group_buff +
4082
                                                     test(maybe_null),
4083
                                                     field->null_ptr,
4084
                                                     field->null_bit)))
4085
	  goto err; /* purecov: inspected */
4086
	if (maybe_null)
4087
	{
4088
	  /*
4089
	    To be able to group on NULL, we reserved place in group_buff
4090
	    for the NULL flag just before the column. (see above).
4091
	    The field data is after this flag.
4092
	    The NULL flag is updated in 'end_update()' and 'end_write()'
4093
	  */
4094
	  keyinfo->flags|= HA_NULL_ARE_EQUAL;	// def. that NULL == NULL
4095
	  key_part_info->null_bit=field->null_bit;
4096
	  key_part_info->null_offset= (uint) (field->null_ptr -
4097
					      (uchar*) table->record[0]);
4098
          cur_group->buff++;                        // Pointer to field data
4099
	  group_buff++;                         // Skipp null flag
4100
	}
4101
        /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
4102
        key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
4103
	group_buff+= cur_group->field->pack_length();
4104
      }
4105
      keyinfo->key_length+=  key_part_info->length;
4106
    }
4107
  }
4108
4109
  if (distinct && field_count != param->hidden_field_count)
4110
  {
4111
    /*
4112
      Create an unique key or an unique constraint over all columns
4113
      that should be in the result.  In the temporary table, there are
4114
      'param->hidden_field_count' extra columns, whose null bits are stored
4115
      in the first 'hidden_null_pack_length' bytes of the row.
4116
    */
4117
    if (blob_count)
4118
    {
4119
      /*
4120
        Special mode for index creation in MyISAM used to support unique
4121
        indexes on blobs with arbitrary length. Such indexes cannot be
4122
        used for lookups.
4123
      */
4124
      share->uniques= 1;
4125
    }
4126
    null_pack_length-=hidden_null_pack_length;
4127
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
4128
			 (share->uniques ? test(null_pack_length) : 0));
4129
    table->distinct= 1;
4130
    share->keys= 1;
4131
    if (!(key_part_info= (KEY_PART_INFO*)
4132
          alloc_root(&table->mem_root,
4133
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
4134
      goto err;
4135
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
4136
    table->key_info=keyinfo;
4137
    keyinfo->key_part=key_part_info;
4138
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
4139
    keyinfo->key_length=(uint16_t) reclength;
4140
    keyinfo->name= (char*) "distinct_key";
4141
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
4142
    keyinfo->rec_per_key=0;
4143
4144
    /*
4145
      Create an extra field to hold NULL bits so that unique indexes on
4146
      blobs can distinguish NULL from 0. This extra field is not needed
4147
      when we do not use UNIQUE indexes for blobs.
4148
    */
4149
    if (null_pack_length && share->uniques)
4150
    {
4151
      key_part_info->null_bit=0;
4152
      key_part_info->offset=hidden_null_pack_length;
4153
      key_part_info->length=null_pack_length;
4154
      key_part_info->field= new Field_varstring(table->record[0],
4155
                                                (uint32_t) key_part_info->length,
4156
                                                0,
4157
                                                (uchar*) 0,
4158
                                                (uint) 0,
4159
                                                Field::NONE,
4160
                                                NullS, 
4161
                                                table->s,
4162
                                                &my_charset_bin);
4163
      if (!key_part_info->field)
4164
        goto err;
4165
      key_part_info->field->init(table);
4166
      key_part_info->key_type=FIELDFLAG_BINARY;
4167
      key_part_info->type=    HA_KEYTYPE_BINARY;
4168
      key_part_info++;
4169
    }
4170
    /* Create a distinct key over the columns we are going to return */
4171
    for (i=param->hidden_field_count, reg_field=table->field + i ;
4172
	 i < field_count;
4173
	 i++, reg_field++, key_part_info++)
4174
    {
4175
      key_part_info->null_bit=0;
4176
      key_part_info->field=    *reg_field;
4177
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
4178
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
4179
      /* TODO:
4180
        The below method of computing the key format length of the
4181
        key part is a copy/paste from opt_range.cc, and table.cc.
4182
        This should be factored out, e.g. as a method of Field.
4183
        In addition it is not clear if any of the Field::*_length
4184
        methods is supposed to compute the same length. If so, it
4185
        might be reused.
4186
      */
4187
      key_part_info->store_length= key_part_info->length;
4188
4189
      if ((*reg_field)->real_maybe_null())
4190
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
4191
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
4192
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
4193
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
4194
4195
      key_part_info->type=     (uint8_t) (*reg_field)->key_type();
4196
      key_part_info->key_type =
4197
	((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
4198
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
4199
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
4200
	0 : FIELDFLAG_BINARY;
4201
    }
4202
  }
4203
4204
  if (thd->is_fatal_error)				// If end of memory
4205
    goto err;					 /* purecov: inspected */
4206
  share->db_record_offset= 1;
4207
  if (share->db_type() == myisam_hton)
4208
  {
4209
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
4210
				       &param->recinfo, select_options))
4211
      goto err;
4212
  }
4213
  if (table->open_tmp_table())
4214
    goto err;
4215
4216
  thd->mem_root= mem_root_save;
4217
4218
  return(table);
4219
4220
err:
4221
  thd->mem_root= mem_root_save;
4222
  table->free_tmp_table(thd);                    /* purecov: inspected */
4223
  if (temp_pool_slot != MY_BIT_NONE)
4224
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4225
  return(NULL);				/* purecov: inspected */
4226
}
4227
4228
/****************************************************************************/
4229
4230
/**
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4231
  Create a reduced Table object with properly set up Field list from a
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4232
  list of field definitions.
4233
4234
    The created table doesn't have a table handler associated with
4235
    it, has no keys, no group/distinct, no copy_funcs array.
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4236
    The sole purpose of this Table object is to use the power of Field
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4237
    class to read/write data to/from table->record[0]. Then one can store
4238
    the record in any container (RB tree, hash, etc).
4239
    The table is created in THD mem_root, so are the table's fields.
4240
    Consequently, if you don't BLOB fields, you don't need to free it.
4241
4242
  @param thd         connection handle
4243
  @param field_list  list of column definitions
4244
4245
  @return
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4246
    0 if out of memory, Table object in case of success
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4247
*/
4248
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4249
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4250
{
4251
  uint field_count= field_list.elements;
4252
  uint blob_count= 0;
4253
  Field **field;
4254
  Create_field *cdef;                           /* column definition */
4255
  uint record_length= 0;
4256
  uint null_count= 0;                 /* number of columns which may be null */
4257
  uint null_pack_length;              /* NULL representation array length */
4258
  uint *blob_field;
4259
  uchar *bitmaps;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4260
  Table *table;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4261
  TABLE_SHARE *share;
4262
4263
  if (!multi_alloc_root(thd->mem_root,
4264
                        &table, sizeof(*table),
4265
                        &share, sizeof(*share),
4266
                        &field, (field_count + 1) * sizeof(Field*),
4267
                        &blob_field, (field_count+1) *sizeof(uint),
4268
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4269
                        NullS))
4270
    return 0;
4271
4272
  memset(table, 0, sizeof(*table));
4273
  memset(share, 0, sizeof(*share));
4274
  table->field= field;
4275
  table->s= share;
4276
  share->blob_field= blob_field;
4277
  share->fields= field_count;
4278
  share->blob_ptr_size= portable_sizeof_char_ptr;
4279
  table->setup_tmp_table_column_bitmaps(bitmaps);
4280
4281
  /* Create all fields and calculate the total length of record */
4282
  List_iterator_fast<Create_field> it(field_list);
4283
  while ((cdef= it++))
4284
  {
4285
    *field= make_field(share, 0, cdef->length,
4286
                       (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4287
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4288
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4289
                       cdef->unireg_check,
4290
                       cdef->interval, cdef->field_name);
4291
    if (!*field)
4292
      goto error;
4293
    (*field)->init(table);
4294
    record_length+= (*field)->pack_length();
4295
    if (! ((*field)->flags & NOT_NULL_FLAG))
4296
      null_count++;
4297
4298
    if ((*field)->flags & BLOB_FLAG)
4299
      share->blob_field[blob_count++]= (uint) (field - table->field);
4300
4301
    field++;
4302
  }
4303
  *field= NULL;                             /* mark the end of the list */
4304
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
4305
  share->blob_fields= blob_count;
4306
4307
  null_pack_length= (null_count + 7)/8;
4308
  share->reclength= record_length + null_pack_length;
4309
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4310
  table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
4311
  if (!table->record[0])
4312
    goto error;
4313
4314
  if (null_pack_length)
4315
  {
4316
    table->null_flags= (uchar*) table->record[0];
4317
    share->null_fields= null_count;
4318
    share->null_bytes= null_pack_length;
4319
  }
4320
4321
  table->in_use= thd;           /* field->reset() may access table->in_use */
4322
  {
4323
    /* Set up field pointers */
4324
    uchar *null_pos= table->record[0];
4325
    uchar *field_pos= null_pos + share->null_bytes;
4326
    uint null_bit= 1;
4327
4328
    for (field= table->field; *field; ++field)
4329
    {
4330
      Field *cur_field= *field;
4331
      if ((cur_field->flags & NOT_NULL_FLAG))
4332
        cur_field->move_field(field_pos);
4333
      else
4334
      {
4335
        cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
4336
        null_bit<<= 1;
4337
        if (null_bit == (1 << 8))
4338
        {
4339
          ++null_pos;
4340
          null_bit= 1;
4341
        }
4342
      }
4343
      cur_field->reset();
4344
4345
      field_pos+= cur_field->pack_length();
4346
    }
4347
  }
4348
  return table;
4349
error:
4350
  for (field= table->field; *field; ++field)
4351
    delete *field;                         /* just invokes field destructor */
4352
  return 0;
4353
}
4354
4355
4356
bool Table::open_tmp_table()
4357
{
4358
  int error;
4359
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4360
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4361
  {
4362
    file->print_error(error,MYF(0)); /* purecov: inspected */
4363
    db_stat=0;
4364
    return(1);
4365
  }
4366
  (void) file->extra(HA_EXTRA_QUICK);		/* Faster */
4367
  return(0);
4368
}
4369
4370
4371
/*
4372
  Create MyISAM temporary table
4373
4374
  SYNOPSIS
4375
    create_myisam_tmp_table()
4376
      keyinfo         Description of the index (there is always one index)
4377
      start_recinfo   MyISAM's column descriptions
4378
      recinfo INOUT   End of MyISAM's column descriptions
4379
      options         Option bits
4380
   
4381
  DESCRIPTION
4382
    Create a MyISAM temporary table according to passed description. The is
4383
    assumed to have one unique index or constraint.
4384
4385
    The passed array or MI_COLUMNDEF structures must have this form:
4386
4387
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4388
         when there are many nullable columns)
4389
      2. Table columns
4390
      3. One free MI_COLUMNDEF element (*recinfo points here)
4391
   
4392
    This function may use the free element to create hash column for unique
4393
    constraint.
4394
4395
   RETURN
4396
     false - OK
4397
     true  - Error
4398
*/
4399
4400
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
4401
                                    MI_COLUMNDEF *start_recinfo,
4402
                                    MI_COLUMNDEF **recinfo, 
4403
				    uint64_t options)
4404
{
4405
  int error;
4406
  MI_KEYDEF keydef;
4407
  MI_UNIQUEDEF uniquedef;
4408
  TABLE_SHARE *share= s;
4409
4410
  if (share->keys)
4411
  {						// Get keys for ni_create
4412
    bool using_unique_constraint=0;
4413
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4414
                                            sizeof(*seg) * keyinfo->key_parts);
4415
    if (!seg)
4416
      goto err;
4417
4418
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4419
    if (keyinfo->key_length >= file->max_key_length() ||
4420
	keyinfo->key_parts > file->max_key_parts() ||
4421
	share->uniques)
4422
    {
4423
      /* Can't create a key; Make a unique constraint instead of a key */
4424
      share->keys=    0;
4425
      share->uniques= 1;
4426
      using_unique_constraint=1;
4427
      memset(&uniquedef, 0, sizeof(uniquedef));
4428
      uniquedef.keysegs=keyinfo->key_parts;
4429
      uniquedef.seg=seg;
4430
      uniquedef.null_are_equal=1;
4431
4432
      /* Create extra column for hash value */
4433
      memset(*recinfo, 0, sizeof(**recinfo));
4434
      (*recinfo)->type= FIELD_CHECK;
4435
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4436
      (*recinfo)++;
4437
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
4438
    }
4439
    else
4440
    {
4441
      /* Create an unique key */
4442
      memset(&keydef, 0, sizeof(keydef));
4443
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4444
      keydef.keysegs=  keyinfo->key_parts;
4445
      keydef.seg= seg;
4446
    }
4447
    for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
4448
    {
4449
      Field *field=keyinfo->key_part[i].field;
4450
      seg->flag=     0;
4451
      seg->language= field->charset()->number;
4452
      seg->length=   keyinfo->key_part[i].length;
4453
      seg->start=    keyinfo->key_part[i].offset;
4454
      if (field->flags & BLOB_FLAG)
4455
      {
4456
	seg->type=
4457
	((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4458
	 HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4459
	seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
4460
	seg->flag= HA_BLOB_PART;
4461
	seg->length=0;			// Whole blob in unique constraint
4462
      }
4463
      else
4464
      {
4465
	seg->type= keyinfo->key_part[i].type;
4466
      }
4467
      if (!(field->flags & NOT_NULL_FLAG))
4468
      {
4469
	seg->null_bit= field->null_bit;
4470
	seg->null_pos= (uint) (field->null_ptr - (uchar*) record[0]);
4471
	/*
4472
	  We are using a GROUP BY on something that contains NULL
4473
	  In this case we have to tell MyISAM that two NULL should
4474
	  on INSERT be regarded at the same value
4475
	*/
4476
	if (!using_unique_constraint)
4477
	  keydef.flag|= HA_NULL_ARE_EQUAL;
4478
      }
4479
    }
4480
  }
4481
  MI_CREATE_INFO create_info;
4482
  memset(&create_info, 0, sizeof(create_info));
4483
4484
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4485
      OPTION_BIG_TABLES)
4486
    create_info.data_file_length= ~(uint64_t) 0;
4487
4488
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4489
		       (uint) (*recinfo-start_recinfo),
4490
		       start_recinfo,
4491
		       share->uniques, &uniquedef,
4492
		       &create_info,
4493
		       HA_CREATE_TMP_TABLE)))
4494
  {
4495
    file->print_error(error,MYF(0));	/* purecov: inspected */
4496
    db_stat=0;
4497
    goto err;
4498
  }
4499
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
4500
  share->db_record_offset= 1;
4501
  return false;
4502
 err:
4503
  return true;
4504
}
4505
4506
4507
void Table::free_tmp_table(THD *thd)
4508
{
4509
  MEM_ROOT own_root= mem_root;
4510
  const char *save_proc_info;
4511
322.2.4 by Mats Kindahl
Post-merge fix to new code using THD:proc_info, which was made private by the pre-merge patch.
4512
  save_proc_info=thd->get_proc_info();
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4513
  thd_proc_info(thd, "removing tmp table");
4514
4515
  if (file)
4516
  {
4517
    if (db_stat)
4518
      file->ha_drop_table(s->table_name.str);
4519
    else
4520
      file->ha_delete_table(s->table_name.str);
4521
    delete file;
4522
  }
4523
4524
  /* free blobs */
4525
  for (Field **ptr= field ; *ptr ; ptr++)
4526
    (*ptr)->free();
4527
  free_io_cache(this);
4528
4529
  if (temp_pool_slot != MY_BIT_NONE)
4530
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4531
4532
  plugin_unlock(0, s->db_plugin);
4533
4534
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4535
  thd_proc_info(thd, save_proc_info);
4536
4537
  return;
4538
}
4539
4540
/**
4541
  If a HEAP table gets full, create a MyISAM table and copy all rows
4542
  to this.
4543
*/
4544
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4545
bool create_myisam_from_heap(THD *thd, Table *table,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4546
                             MI_COLUMNDEF *start_recinfo,
4547
                             MI_COLUMNDEF **recinfo, 
4548
			     int error, bool ignore_last_dupp_key_error)
4549
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
4550
  Table new_table;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4551
  TABLE_SHARE share;
4552
  const char *save_proc_info;
4553
  int write_err;
4554
4555
  if (table->s->db_type() != heap_hton || 
4556
      error != HA_ERR_RECORD_FILE_FULL)
4557
  {
4558
    table->file->print_error(error,MYF(0));
4559
    return(1);
4560
  }
4561
  new_table= *table;
4562
  share= *table->s;
4563
  new_table.s= &share;
4564
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
4565
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4566
                                        new_table.s->db_type())))
4567
    return(1);				// End of memory
4568
322.2.4 by Mats Kindahl
Post-merge fix to new code using THD:proc_info, which was made private by the pre-merge patch.
4569
  save_proc_info=thd->get_proc_info();
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
4570
  thd_proc_info(thd, "converting HEAP to MyISAM");
4571
4572
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4573
					recinfo, thd->lex->select_lex.options | 
4574
					thd->options))
4575
    goto err2;
4576
  if (new_table.open_tmp_table())
4577
    goto err1;
4578
  if (table->file->indexes_are_disabled())
4579
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4580
  table->file->ha_index_or_rnd_end();
4581
  table->file->ha_rnd_init(1);
4582
  if (table->no_rows)
4583
  {
4584
    new_table.file->extra(HA_EXTRA_NO_ROWS);
4585
    new_table.no_rows=1;
4586
  }
4587
4588
#ifdef TO_BE_DONE_LATER_IN_4_1
4589
  /*
4590
    To use start_bulk_insert() (which is new in 4.1) we need to find
4591
    all places where a corresponding end_bulk_insert() should be put.
4592
  */
4593
  table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
4594
  new_table.file->ha_start_bulk_insert(table->file->stats.records);
4595
#else
4596
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4597
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4598
#endif
4599
4600
  /*
4601
    copy all old rows from heap table to MyISAM table
4602
    This is the only code that uses record[1] to read/write but this
4603
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4604
  */
4605
  while (!table->file->rnd_next(new_table.record[1]))
4606
  {
4607
    write_err= new_table.file->ha_write_row(new_table.record[1]);
4608
    if (write_err)
4609
      goto err;
4610
  }
4611
  /* copy row that filled HEAP table */
4612
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
4613
  {
4614
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4615
	!ignore_last_dupp_key_error)
4616
      goto err;
4617
  }
4618
4619
  /* remove heap table and change to use myisam table */
4620
  (void) table->file->ha_rnd_end();
4621
  (void) table->file->close();                  // This deletes the table !
4622
  delete table->file;
4623
  table->file=0;
4624
  plugin_unlock(0, table->s->db_plugin);
4625
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4626
  new_table.s= table->s;                       // Keep old share
4627
  *table= new_table;
4628
  *table->s= share;
4629
  
4630
  table->file->change_table_ptr(table, table->s);
4631
  table->use_all_columns();
4632
  if (save_proc_info)
4633
  {
4634
    const char *new_proc_info=
4635
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4636
      "Copying to tmp table on disk" : save_proc_info);
4637
    thd_proc_info(thd, new_proc_info);
4638
  }
4639
  return(0);
4640
4641
 err:
4642
  table->file->print_error(write_err, MYF(0));
4643
  (void) table->file->ha_rnd_end();
4644
  (void) new_table.file->close();
4645
 err1:
4646
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4647
 err2:
4648
  delete new_table.file;
4649
  thd_proc_info(thd, save_proc_info);
4650
  table->mem_root= new_table.mem_root;
4651
  return(1);
4652
}
4653
354 by Brian Aker
Refactor of Table methods.
4654
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4655
{
4656
  my_bitmap_map *old= bitmap->bitmap;
4657
  bitmap->bitmap= s->all_set.bitmap;
4658
  return old;
4659
}
4660
4661
void Table::restore_column_map(my_bitmap_map *old)
4662
{
4663
  read_set->bitmap= old;
4664
}
4665
355 by Brian Aker
More Table cleanup
4666
uint Table::find_shortest_key(const key_map *usable_keys)
4667
{
365.2.6 by Monty Taylor
Undid some stupid int->int16_t conversions.
4668
  uint32_t min_length= UINT32_MAX;
4669
  uint32_t best= MAX_KEY;
355 by Brian Aker
More Table cleanup
4670
  if (!usable_keys->is_clear_all())
4671
  {
4672
    for (uint nr=0; nr < s->keys ; nr++)
4673
    {
4674
      if (usable_keys->is_set(nr))
4675
      {
4676
        if (key_info[nr].key_length < min_length)
4677
        {
4678
          min_length= key_info[nr].key_length;
4679
          best=nr;
4680
        }
4681
      }
4682
    }
4683
  }
4684
  return best;
4685
}
4686
4687
/*****************************************************************************
4688
  Remove duplicates from tmp table
4689
  This should be recoded to add a unique index to the table and remove
4690
  duplicates
4691
  Table is a locked single thread table
4692
  fields is the number of fields to check (from the end)
4693
*****************************************************************************/
4694
4695
bool Table::compare_record(Field **ptr)
4696
{
4697
  for (; *ptr ; ptr++)
4698
  {
4699
    if ((*ptr)->cmp_offset(s->rec_buff_length))
4700
      return true;
4701
  }
4702
  return false;
4703
}
4704
4705
/* Return false if row hasn't changed */
4706
4707
bool Table::compare_record()
4708
{
4709
  if (s->blob_fields + s->varchar_fields == 0)
4710
    return cmp_record(this, record[1]);
4711
  /* Compare null bits */
4712
  if (memcmp(null_flags,
4713
	     null_flags + s->rec_buff_length,
4714
	     s->null_bytes))
4715
    return true;				// Diff in NULL value
4716
  /* Compare updated fields */
4717
  for (Field **ptr= field ; *ptr ; ptr++)
4718
  {
4719
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
4720
	(*ptr)->cmp_binary_offset(s->rec_buff_length))
4721
      return true;
4722
  }
4723
  return false;
4724
}
4725
4726
4727
4728
354 by Brian Aker
Refactor of Table methods.
4729
4730
/*****************************************************************************
4731
  The different ways to read a record
4732
  Returns -1 if row was not found, 0 if row was found and 1 on errors
4733
*****************************************************************************/
4734
4735
/** Help function when we get some an error from the table handler. */
4736
4737
int Table::report_error(int error)
4738
{
4739
  if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
4740
  {
4741
    status= STATUS_GARBAGE;
4742
    return -1;					// key not found; ok
4743
  }
4744
  /*
4745
    Locking reads can legally return also these errors, do not
4746
    print them to the .err log
4747
  */
4748
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
4749
    sql_print_error(_("Got error %d when reading table '%s'"),
4750
		    error, s->path.str);
4751
  file->print_error(error,MYF(0));
4752
4753
  return 1;
4754
}
4755
1 by brian
clean slate
4756
4757
/*****************************************************************************
4758
** Instansiate templates
4759
*****************************************************************************/
4760
4761
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4762
template class List<String>;
4763
template class List_iterator<String>;
4764
#endif