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