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