~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Some general useful functions */
18
18
 
 
19
#include <config.h>
 
20
 
19
21
#include <drizzled/server_includes.h>
20
 
#include <drizzled/drizzled_error_messages.h>
21
 
 
22
 
#include "tmp_table.h"
23
 
#include "sj_tmp_table.h"
 
22
#include <drizzled/error.h>
 
23
#include <drizzled/gettext.h>
 
24
 
 
25
#include <drizzled/tmp_table.h>
 
26
#include <drizzled/sj_tmp_table.h>
 
27
#include <drizzled/nested_join.h>
 
28
#include <drizzled/data_home.h>
 
29
#include <drizzled/sql_parse.h>
 
30
 
 
31
#include <string>
 
32
 
 
33
using namespace std;
24
34
 
25
35
/* INFORMATION_SCHEMA name */
26
36
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
27
37
 
 
38
/* Keyword for parsing virtual column functions */
 
39
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
 
40
 
28
41
/* Functions defined in this file */
29
42
 
30
43
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
31
44
                      myf errortype, int errarg);
32
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
 
                           uchar *head, File file);
 
45
static int open_binary_frm(Session *session, TABLE_SHARE *share,
 
46
                           unsigned char *head, File file);
34
47
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
35
 
                              uint types, char **names);
36
 
static uint find_field(Field **fields, uchar *record, uint start, uint length);
 
48
                              uint32_t types, char **names);
 
49
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length);
37
50
 
38
51
/*************************************************************************/
39
52
 
40
53
/* Get column name from column hash */
41
54
 
42
 
static uchar *get_field_name(Field **buff, size_t *length,
43
 
                             bool not_used __attribute__((unused)))
 
55
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
44
56
{
45
57
  *length= (uint) strlen((*buff)->field_name);
46
 
  return (uchar*) (*buff)->field_name;
 
58
  return (unsigned char*) (*buff)->field_name;
47
59
}
48
60
 
49
61
 
108
120
*/
109
121
 
110
122
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
111
 
                               uint key_length)
 
123
                               uint32_t key_length)
112
124
{
113
125
  MEM_ROOT mem_root;
114
126
  TABLE_SHARE *share;
115
127
  char *key_buff, *path_buff;
116
128
  char path[FN_REFLEN];
117
 
  uint path_length;
 
129
  uint32_t path_length;
118
130
 
119
131
  path_length= build_table_filename(path, sizeof(path) - 1,
120
132
                                    table_list->db,
132
144
 
133
145
    share->path.str= path_buff;
134
146
    share->path.length= path_length;
135
 
    stpcpy(share->path.str, path);
 
147
    my_stpcpy(share->path.str, path);
136
148
    share->normalized_path.str=    share->path.str;
137
149
    share->normalized_path.length= path_length;
138
150
 
168
180
 
169
181
  SYNOPSIS
170
182
    init_tmp_table_share()
171
 
    thd         thread handle
 
183
    session         thread handle
172
184
    share       Share to fill
173
185
    key         Table_cache_key, as generated from create_table_def_key.
174
186
                must start with db name.    
181
193
    don't have to be shared between threads or put into the table def
182
194
    cache, so we can do some things notable simpler and faster
183
195
 
184
 
    If table is not put in thd->temporary_tables (happens only when
 
196
    If table is not put in session->temporary_tables (happens only when
185
197
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
198
    use key_length= 0 as neither table_cache_key or key_length will be used).
187
199
*/
188
200
 
189
 
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
190
 
                          uint key_length, const char *table_name,
 
201
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
 
202
                          uint32_t key_length, const char *table_name,
191
203
                          const char *path)
192
204
{
193
205
 
216
228
    table_map_id is also used for MERGE tables to suppress repeated
217
229
    compatibility checks.
218
230
  */
219
 
  share->table_map_id= (ulong) thd->query_id;
 
231
  share->table_map_id= (ulong) session->query_id;
220
232
 
221
233
  return;
222
234
}
271
283
  
272
284
  SYNOPSIS
273
285
  open_table_def()
274
 
  thd           Thread handler
 
286
  session               Thread handler
275
287
  share         Fill this with table definition
276
288
  db_flags      Bit mask of the following flags: OPEN_VIEW
277
289
 
291
303
   6    Unknown .frm version
292
304
*/
293
305
 
294
 
int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags  __attribute__((unused)))
 
306
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
295
307
{
296
308
  int error, table_type;
297
309
  bool error_given;
298
310
  File file;
299
 
  uchar head[64], *disk_buff;
300
 
  char  path[FN_REFLEN];
 
311
  unsigned char head[64], *disk_buff;
 
312
  string        path("");
 
313
 
301
314
  MEM_ROOT **root_ptr, *old_root;
302
315
 
303
316
  error= 1;
304
317
  error_given= 0;
305
318
  disk_buff= NULL;
306
319
 
307
 
  strxmov(path, share->normalized_path.str, reg_ext, NullS);
308
 
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
320
  path.reserve(FN_REFLEN);
 
321
  path.append(share->normalized_path.str);
 
322
  path.append(reg_ext);
 
323
  if ((file= open(path.c_str(), O_RDONLY)) < 0)
309
324
  {
310
325
    /*
311
326
      We don't try to open 5.0 unencoded name, if
316
331
        
317
332
      - non-encoded db or table name contain "#mysql50#" prefix.
318
333
        This kind of tables must have been opened only by the
319
 
        my_open() above.
 
334
        open() above.
320
335
    */
321
336
    if (strchr(share->table_name.str, '@') ||
322
337
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
326
341
      goto err_not_open;
327
342
 
328
343
    /* Try unencoded 5.0 name */
329
 
    uint length;
330
 
    strxnmov(path, sizeof(path)-1,
331
 
             mysql_data_home, "/", share->db.str, "/",
332
 
             share->table_name.str, reg_ext, NullS);
333
 
    length= unpack_filename(path, path) - reg_ext_length;
 
344
    size_t length;
 
345
    char unpacked_path[FN_REFLEN];
 
346
    path.clear();
 
347
    path.append(mysql_data_home);
 
348
    path.append("/");
 
349
    path.append(share->db.str);
 
350
    path.append("/");
 
351
    path.append(share->table_name.str);
 
352
    path.append(reg_ext);
 
353
    length= unpack_filename(unpacked_path, path.c_str()) - reg_ext_length;
334
354
    /*
335
355
      The following is a safety test and should never fail
336
356
      as the old file name should never be longer than the new one.
342
362
      so no need to check the old file name.
343
363
    */
344
364
    if (length == share->normalized_path.length ||
345
 
        ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
 
365
        ((file= open(unpacked_path, O_RDONLY)) < 0))
346
366
      goto err_not_open;
347
367
 
348
368
    /* Unencoded 5.0 table name found */
349
 
    path[length]= '\0'; // Remove .frm extension
350
 
    stpcpy(share->normalized_path.str, path);
 
369
    unpacked_path[length]= '\0'; // Remove .frm extension
 
370
    my_stpcpy(share->normalized_path.str, unpacked_path);
351
371
    share->normalized_path.length= length;
352
372
  }
353
373
 
355
375
  if (my_read(file, head, 64, MYF(MY_NABP)))
356
376
    goto err;
357
377
 
358
 
  if (head[0] == (uchar) 254 && head[1] == 1)
 
378
  if (head[0] == (unsigned char) 254 && head[1] == 1)
359
379
  {
360
380
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
361
381
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
377
397
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
378
398
    old_root= *root_ptr;
379
399
    *root_ptr= &share->mem_root;
380
 
    error= open_binary_frm(thd, share, head, file);
 
400
    error= open_binary_frm(session, share, head, file);
381
401
    *root_ptr= old_root;
382
402
    error_given= 1;
383
403
  }
387
407
  share->table_category= get_table_category(& share->db, & share->table_name);
388
408
 
389
409
  if (!error)
390
 
    thd->status_var.opened_shares++;
 
410
    session->status_var.opened_shares++;
391
411
 
392
412
err:
393
413
  my_close(file, MYF(MY_WME));
407
427
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
408
428
*/
409
429
 
410
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
 
430
static int open_binary_frm(Session *session, TABLE_SHARE *share, unsigned char *head,
411
431
                           File file)
412
432
{
413
433
  int error, errarg= 0;
414
 
  uint new_frm_ver, field_pack_length, new_field_pack_flag;
415
 
  uint interval_count, interval_parts, read_length, int_length;
416
 
  uint db_create_options, keys, key_parts, n_length;
417
 
  uint key_info_length, com_length, null_bit_pos=0;
418
 
  uint extra_rec_buf_length;
419
 
  uint i,j;
 
434
  uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
 
435
  uint32_t interval_count, interval_parts, read_length, int_length;
 
436
  uint32_t db_create_options, keys, key_parts, n_length;
 
437
  uint32_t key_info_length, com_length, null_bit_pos=0;
 
438
  uint32_t vcol_screen_length;
 
439
  uint32_t extra_rec_buf_length;
 
440
  uint32_t i,j;
420
441
  bool use_hash;
421
 
  uchar forminfo[288];
422
 
  char *keynames, *names, *comment_pos;
423
 
  uchar *record;
424
 
  uchar *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
 
442
  unsigned char forminfo[288];
 
443
  char *keynames, *names, *comment_pos, *vcol_screen_pos;
 
444
  unsigned char *record;
 
445
  unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
425
446
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
447
  handler *handler_file= 0;
427
448
  KEY   *keyinfo;
430
451
  const char **interval_array;
431
452
  enum legacy_db_type legacy_db_type;
432
453
  my_bitmap_map *bitmaps;
433
 
  uchar *buff= 0;
434
 
  uchar *field_extra_info= 0;
 
454
  unsigned char *buff= 0;
 
455
  unsigned char *field_extra_info= 0;
435
456
 
436
457
  new_field_pack_flag= head[27];
437
458
  new_frm_ver= (head[2] - FRM_VER);
441
462
  error= 3;
442
463
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
443
464
    goto err;                                   /* purecov: inspected */
444
 
  VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
 
465
  my_seek(file,pos,MY_SEEK_SET,MYF(0));
445
466
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
446
467
    goto err;
447
468
 
464
485
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
465
486
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
466
487
    share->db_plugin= ha_lock_engine(NULL, 
467
 
                                     ha_checktype(thd, legacy_db_type, 0, 0));
 
488
                                     ha_checktype(session, legacy_db_type, 0, 0));
468
489
  share->db_create_options= db_create_options= uint2korr(head+30);
469
490
  share->db_options_in_use= share->db_create_options;
470
491
  share->mysql_version= uint4korr(head+51);
496
517
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
497
518
    share->blob_ptr_size= portable_sizeof_char_ptr;
498
519
  /* Set temporarily a good value for db_low_byte_first */
499
 
  share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM);
 
520
  share->db_low_byte_first= true;
500
521
  error=4;
501
522
  share->max_rows= uint4korr(head+18);
502
523
  share->min_rows= uint4korr(head+22);
503
524
 
504
525
  /* Read keyinformation */
505
526
  key_info_length= (uint) uint2korr(head+28);
506
 
  VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
507
 
  if (read_string(file,(uchar**) &disk_buff,key_info_length))
 
527
  my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
 
528
  if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
508
529
    goto err;                                   /* purecov: inspected */
509
530
  if (disk_buff[0] & 0x80)
510
531
  {
525
546
    goto err;                                   /* purecov: inspected */
526
547
  memset(keyinfo, 0, n_length);
527
548
  share->key_info= keyinfo;
528
 
  key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
 
549
  key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
529
550
  strpos=disk_buff+6;
530
551
 
531
552
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
575
596
    }
576
597
  }
577
598
  keynames=(char*) key_part;
578
 
  strpos+= (stpcpy(keynames, (char *) strpos) - keynames)+1;
 
599
  strpos+= (my_stpcpy(keynames, (char *) strpos) - keynames)+1;
579
600
 
580
601
  //reading index comments
581
602
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
592
613
  }
593
614
 
594
615
  share->reclength = uint2korr((head+16));
 
616
  share->stored_rec_length= share->reclength;
595
617
 
596
618
  record_offset= (ulong) (uint2korr(head+6)+
597
619
                          ((uint2korr(head+14) == 0xffff ?
600
622
  if ((n_length= uint4korr(head+55)))
601
623
  {
602
624
    /* Read extra data segment */
603
 
    uchar *next_chunk, *buff_end;
604
 
    if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
 
625
    unsigned char *next_chunk, *buff_end;
 
626
    if (!(next_chunk= buff= (unsigned char*) my_malloc(n_length, MYF(MY_WME))))
605
627
      goto err;
606
628
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
607
629
    {
619
641
    buff_end= buff + n_length;
620
642
    if (next_chunk + 2 < buff_end)
621
643
    {
622
 
      uint str_db_type_length= uint2korr(next_chunk);
 
644
      uint32_t str_db_type_length= uint2korr(next_chunk);
623
645
      LEX_STRING name;
624
646
      name.str= (char*) next_chunk + 2;
625
647
      name.length= str_db_type_length;
626
648
 
627
 
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
 
649
      plugin_ref tmp_plugin= ha_resolve_by_name(session, &name);
628
650
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
629
651
      {
630
652
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
633
655
                plugin_data(tmp_plugin, handlerton *)))
634
656
        {
635
657
          /* bad file, legacy_db_type did not match the name */
636
 
          my_free(buff, MYF(0));
 
658
          free(buff);
637
659
          goto err;
638
660
        }
639
661
        /*
649
671
        /* purecov: begin inspected */
650
672
        error= 8;
651
673
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
652
 
        my_free(buff, MYF(0));
 
674
        free(buff);
653
675
        goto err;
654
676
        /* purecov: end */
655
677
      }
660
682
      /* New auto_partitioned indicator introduced in 5.1.11 */
661
683
      next_chunk++;
662
684
    }
663
 
    if (forminfo[46] == (uchar)255)
 
685
    if (forminfo[46] == (unsigned char)255)
664
686
    {
665
687
      //reading long table comment
666
688
      if (next_chunk + 2 > buff_end)
667
689
      {
668
 
          my_free(buff, MYF(0));
 
690
          free(buff);
669
691
          goto err;
670
692
      }
671
693
      share->comment.length = uint2korr(next_chunk);
672
694
      if (! (share->comment.str= strmake_root(&share->mem_root,
673
695
                               (char*)next_chunk + 2, share->comment.length)))
674
696
      {
675
 
          my_free(buff, MYF(0));
 
697
          free(buff);
676
698
          goto err;
677
699
      }
678
700
      next_chunk+= 2 + share->comment.length;
696
718
      }
697
719
      else
698
720
      {
699
 
        const uint format_section_header_size= 8;
700
 
        uint format_section_len= uint2korr(next_chunk+0);
 
721
        const uint32_t format_section_header_size= 8;
 
722
        uint32_t format_section_len= uint2korr(next_chunk+0);
701
723
 
702
724
        field_extra_info= next_chunk + format_section_header_size + 1;
703
725
        next_chunk+= format_section_len;
715
737
  extra_rec_buf_length= uint2korr(head+59);
716
738
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
717
739
  share->rec_buff_length= rec_buff_length;
718
 
  if (!(record= (uchar *) alloc_root(&share->mem_root,
 
740
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
719
741
                                     rec_buff_length)))
720
742
    goto err;                                   /* purecov: inspected */
721
743
  share->default_values= record;
722
744
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
723
745
    goto err;                                   /* purecov: inspected */
724
746
 
725
 
  VOID(my_seek(file,pos+288,MY_SEEK_SET,MYF(0)));
 
747
  my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
726
748
 
727
749
  share->fields= uint2korr(forminfo+258);
728
750
  pos= uint2korr(forminfo+260);                 /* Length of all screens */
732
754
  int_length= uint2korr(forminfo+274);
733
755
  share->null_fields= uint2korr(forminfo+282);
734
756
  com_length= uint2korr(forminfo+284);
735
 
  if (forminfo[46] != (uchar)255)
 
757
  vcol_screen_length= uint2korr(forminfo+286);
 
758
  share->vfields= 0;
 
759
  share->stored_fields= share->fields;
 
760
  if (forminfo[46] != (unsigned char)255)
736
761
  {
737
762
    share->comment.length=  (int) (forminfo[46]);
738
763
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
746
771
                           interval_count*sizeof(TYPELIB)+
747
772
                           (share->fields+interval_parts+
748
773
                            keys+3)*sizeof(char *)+
749
 
                           (n_length+int_length+com_length)))))
 
774
                           (n_length+int_length+com_length+
 
775
                               vcol_screen_length)))))
750
776
    goto err;                                   /* purecov: inspected */
751
777
 
752
778
  share->field= field_ptr;
753
779
  read_length=(uint) (share->fields * field_pack_length +
754
 
                      pos+ (uint) (n_length+int_length+com_length));
755
 
  if (read_string(file,(uchar**) &disk_buff,read_length))
 
780
                      pos+ (uint) (n_length+int_length+com_length+
 
781
                                   vcol_screen_length));
 
782
  if (read_string(file,(unsigned char**) &disk_buff,read_length))
756
783
    goto err;                                   /* purecov: inspected */
757
784
  strpos= disk_buff+pos;
758
785
 
764
791
  memcpy(names, strpos+(share->fields*field_pack_length),
765
792
         (uint) (n_length+int_length));
766
793
  comment_pos= names+(n_length+int_length);
767
 
  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
 
794
  memcpy(comment_pos, disk_buff+read_length-com_length-vcol_screen_length, 
 
795
         com_length);
 
796
  vcol_screen_pos= names+(n_length+int_length+com_length);
 
797
  memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, 
 
798
         vcol_screen_length);
768
799
 
769
800
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
770
801
  if (share->fieldnames.count != share->fields)
779
810
         interval < share->intervals + interval_count;
780
811
         interval++)
781
812
    {
782
 
      uint count= (uint) (interval->count + 1) * sizeof(uint);
783
 
      if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
 
813
      uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
 
814
      if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
784
815
                                                        count)))
785
816
        goto err;
786
817
      for (count= 0; count < interval->count; count++)
796
827
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
797
828
 
798
829
 /* Allocate handler */
799
 
  if (!(handler_file= get_new_handler(share, thd->mem_root,
 
830
  if (!(handler_file= get_new_handler(share, session->mem_root,
800
831
                                      share->db_type())))
801
832
    goto err;
802
833
 
803
834
  record= share->default_values-1;              /* Fieldstart = 1 */
804
835
  if (share->null_field_first)
805
836
  {
806
 
    null_flags= null_pos= (uchar*) record+1;
 
837
    null_flags= null_pos= (unsigned char*) record+1;
807
838
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
808
839
    /*
809
840
      null_bytes below is only correct under the condition that
822
853
 
823
854
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
824
855
  {
825
 
    uint pack_flag, interval_nr, unireg_type, recpos, field_length;
 
856
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
 
857
    uint32_t vcol_info_length=0;
826
858
    enum_field_types field_type;
827
859
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
860
    const CHARSET_INFO *charset= NULL;
829
861
    LEX_STRING comment;
 
862
    virtual_column_info *vcol_info= NULL;
 
863
    bool fld_is_stored= true;
830
864
 
831
865
    if (field_extra_info)
832
866
    {
842
876
      pack_flag=    uint2korr(strpos+8);
843
877
      unireg_type=  (uint) strpos[10];
844
878
      interval_nr=  (uint) strpos[12];
845
 
      uint comment_length=uint2korr(strpos+15);
 
879
      uint32_t comment_length=uint2korr(strpos+15);
846
880
      field_type=(enum_field_types) (uint) strpos[13];
847
881
 
848
882
      {
855
889
          goto err;
856
890
        }
857
891
      }
 
892
      if (field_type == DRIZZLE_TYPE_VIRTUAL)
 
893
      {
 
894
        assert(interval_nr); // Expect non-null expression
 
895
        /* 
 
896
          The interval_id byte in the .frm file stores the length of the
 
897
          expression statement for a virtual column.
 
898
        */
 
899
        vcol_info_length= interval_nr;
 
900
        interval_nr= 0;
 
901
      }
858
902
      if (!comment_length)
859
903
      {
860
904
        comment.str= (char*) "";
866
910
        comment.length= comment_length;
867
911
        comment_pos+=   comment_length;
868
912
      }
 
913
      if (vcol_info_length)
 
914
      {
 
915
        /*
 
916
          Get virtual column data stored in the .frm file as follows:
 
917
          byte 1      = 1 (always 1 to allow for future extensions)
 
918
          byte 2      = sql_type
 
919
          byte 3      = flags (as of now, 0 - no flags, 1 - field is physically stored)
 
920
          byte 4-...  = virtual column expression (text data)
 
921
        */
 
922
        vcol_info= new virtual_column_info();
 
923
        if ((uint)vcol_screen_pos[0] != 1)
 
924
        {
 
925
          error= 4;
 
926
          goto err;
 
927
        }
 
928
        field_type= (enum_field_types) (unsigned char) vcol_screen_pos[1];
 
929
        fld_is_stored= (bool) (uint) vcol_screen_pos[2];
 
930
        vcol_info->expr_str.str= (char *)memdup_root(&share->mem_root,
 
931
                                                     vcol_screen_pos+
 
932
                                                       (uint)FRM_VCOL_HEADER_SIZE,
 
933
                                                     vcol_info_length-
 
934
                                                       (uint)FRM_VCOL_HEADER_SIZE);
 
935
        vcol_info->expr_str.length= vcol_info_length-(uint)FRM_VCOL_HEADER_SIZE;
 
936
        vcol_screen_pos+= vcol_info_length;
 
937
        share->vfields++;
 
938
      }
869
939
    }
870
940
    else
871
941
    {
929
999
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
930
1000
    reg_field->field_index= i;
931
1001
    reg_field->comment=comment;
 
1002
    reg_field->vcol_info= vcol_info;
 
1003
    reg_field->is_stored= fld_is_stored;
932
1004
    if (!(reg_field->flags & NOT_NULL_FLAG))
933
1005
    {
934
1006
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
944
1016
 
945
1017
    if (use_hash)
946
1018
      (void) my_hash_insert(&share->name_hash,
947
 
                            (uchar*) field_ptr); // never fail
 
1019
                            (unsigned char*) field_ptr); // never fail
 
1020
    if (!reg_field->is_stored)
 
1021
    {
 
1022
      share->stored_fields--;
 
1023
      if (share->stored_rec_length>=recpos)
 
1024
        share->stored_rec_length= recpos-1;
 
1025
    }
948
1026
  }
949
1027
  *field_ptr=0;                                 // End marker
 
1028
  /* Sanity checks: */
 
1029
  assert(share->fields>=share->stored_fields);
 
1030
  assert(share->reclength>=share->stored_rec_length);
950
1031
 
951
1032
  /* Fix key->name and key_part->field */
952
1033
  if (key_parts)
953
1034
  {
954
 
    uint primary_key=(uint) (find_type((char*) primary_key_name,
 
1035
    uint32_t primary_key=(uint) (find_type((char*) primary_key_name,
955
1036
                                       &share->keynames, 3) - 1);
956
1037
    int64_t ha_option= handler_file->ha_table_flags();
957
1038
    keyinfo= share->key_info;
958
1039
    key_part= keyinfo->key_part;
959
1040
 
960
 
    for (uint key=0 ; key < share->keys ; key++,keyinfo++)
 
1041
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
961
1042
    {
962
 
      uint usable_parts= 0;
 
1043
      uint32_t usable_parts= 0;
963
1044
      keyinfo->name=(char*) share->keynames.type_names[key];
964
1045
 
965
1046
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
971
1052
        primary_key=key;
972
1053
        for (i=0 ; i < keyinfo->key_parts ;i++)
973
1054
        {
974
 
          uint fieldnr= key_part[i].fieldnr;
 
1055
          uint32_t fieldnr= key_part[i].fieldnr;
975
1056
          if (!fieldnr ||
976
1057
              share->field[fieldnr-1]->null_ptr ||
977
1058
              share->field[fieldnr-1]->key_length() !=
1000
1081
        key_part->type= field->key_type();
1001
1082
        if (field->null_ptr)
1002
1083
        {
1003
 
          key_part->null_offset=(uint) ((uchar*) field->null_ptr -
 
1084
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1004
1085
                                        share->default_values);
1005
1086
          key_part->null_bit= field->null_bit;
1006
1087
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1097
1178
  }
1098
1179
  else
1099
1180
    share->primary_key= MAX_KEY;
1100
 
  x_free((uchar*) disk_buff);
1101
 
  disk_buff=0;
 
1181
  if (disk_buff)
 
1182
    free(disk_buff);
 
1183
  disk_buff= NULL;
1102
1184
  if (new_field_pack_flag <= 1)
1103
1185
  {
1104
1186
    /* Old file format with default as not null */
1105
 
    uint null_length= (share->null_fields+7)/8;
1106
 
    memset(share->default_values + (null_flags - (uchar*) record), 
 
1187
    uint32_t null_length= (share->null_fields+7)/8;
 
1188
    memset(share->default_values + (null_flags - (unsigned char*) record), 
1107
1189
          null_length, 255);
1108
1190
  }
1109
1191
 
1127
1209
  if (share->blob_fields)
1128
1210
  {
1129
1211
    Field **ptr;
1130
 
    uint k, *save;
 
1212
    uint32_t k, *save;
1131
1213
 
1132
1214
    /* Store offsets to blob fields to find them fast */
1133
1215
    if (!(share->blob_field= save=
1145
1227
    the correct null_bytes can now be set, since bitfields have been taken
1146
1228
    into account
1147
1229
  */
1148
 
  share->null_bytes= (null_pos - (uchar*) null_flags +
 
1230
  share->null_bytes= (null_pos - (unsigned char*) null_flags +
1149
1231
                      (null_bit_pos + 7) / 8);
1150
1232
  share->last_null_bit_pos= null_bit_pos;
1151
1233
 
1160
1242
 
1161
1243
  delete handler_file;
1162
1244
  if (buff)
1163
 
    my_free(buff, MYF(0));
 
1245
    free(buff);
1164
1246
  return (0);
1165
1247
 
1166
1248
 err:
1167
1249
  if (buff)
1168
 
    my_free(buff, MYF(0));
 
1250
    free(buff);
1169
1251
  share->error= error;
1170
1252
  share->open_errno= my_errno;
1171
1253
  share->errarg= errarg;
1172
 
  x_free((uchar*) disk_buff);
 
1254
  if (disk_buff)
 
1255
    free(disk_buff);
1173
1256
  delete handler_file;
1174
1257
  hash_free(&share->name_hash);
1175
1258
 
1179
1262
 
1180
1263
 
1181
1264
/*
 
1265
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
 
1266
  This routine is used for error handling purposes.
 
1267
 
 
1268
  SYNOPSIS
 
1269
    clear_field_flag()
 
1270
    table                Table object for which virtual columns are set-up
 
1271
 
 
1272
  RETURN VALUE
 
1273
    NONE
 
1274
*/
 
1275
static void clear_field_flag(Table *table)
 
1276
{
 
1277
  Field **ptr;
 
1278
 
 
1279
  for (ptr= table->field; *ptr; ptr++)
 
1280
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
1281
}
 
1282
 
 
1283
/*
 
1284
  The function uses the feature in fix_fields where the flag 
 
1285
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
 
1286
  This field must always be reset before returning from the function
 
1287
  since it is used for other purposes as well.
 
1288
 
 
1289
  SYNOPSIS
 
1290
    fix_fields_vcol_func()
 
1291
    session                  The thread object
 
1292
    func_item            The item tree reference of the virtual columnfunction
 
1293
    table                The table object
 
1294
    field_name           The name of the processed field
 
1295
 
 
1296
  RETURN VALUE
 
1297
    true                 An error occurred, something was wrong with the
 
1298
                         function.
 
1299
    false                Ok, a partition field array was created
 
1300
*/
 
1301
 
 
1302
bool fix_fields_vcol_func(Session *session,
 
1303
                          Item* func_expr,
 
1304
                          Table *table,
 
1305
                          const char *field_name)
 
1306
{
 
1307
  uint dir_length, home_dir_length;
 
1308
  bool result= true;
 
1309
  TableList tables;
 
1310
  TableList *save_table_list, *save_first_table, *save_last_table;
 
1311
  int error;
 
1312
  Name_resolution_context *context;
 
1313
  const char *save_where;
 
1314
  char* db_name;
 
1315
  char db_name_string[FN_REFLEN];
 
1316
  bool save_use_only_table_context;
 
1317
  Field **ptr, *field;
 
1318
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
1319
  assert(func_expr);
 
1320
 
 
1321
  /*
 
1322
    Set-up the TABLE_LIST object to be a list with a single table
 
1323
    Set the object to zero to create NULL pointers and set alias
 
1324
    and real name to table name and get database name from file name.
 
1325
  */
 
1326
 
 
1327
  bzero((void*)&tables, sizeof(TableList));
 
1328
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
 
1329
  tables.table= table;
 
1330
  tables.next_local= NULL;
 
1331
  tables.next_name_resolution_table= NULL;
 
1332
  memcpy(db_name_string,
 
1333
         table->s->normalized_path.str,
 
1334
         table->s->normalized_path.length);
 
1335
  dir_length= dirname_length(db_name_string);
 
1336
  db_name_string[dir_length - 1]= 0;
 
1337
  home_dir_length= dirname_length(db_name_string);
 
1338
  db_name= &db_name_string[home_dir_length];
 
1339
  tables.db= db_name;
 
1340
 
 
1341
  session->mark_used_columns= MARK_COLUMNS_NONE;
 
1342
 
 
1343
  context= session->lex->current_context();
 
1344
  table->map= 1; //To ensure correct calculation of const item
 
1345
  table->get_fields_in_item_tree= true;
 
1346
  save_table_list= context->table_list;
 
1347
  save_first_table= context->first_name_resolution_table;
 
1348
  save_last_table= context->last_name_resolution_table;
 
1349
  context->table_list= &tables;
 
1350
  context->first_name_resolution_table= &tables;
 
1351
  context->last_name_resolution_table= NULL;
 
1352
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
 
1353
  save_where= session->where;
 
1354
  session->where= "virtual column function";
 
1355
 
 
1356
  /* Save the context before fixing the fields*/
 
1357
  save_use_only_table_context= session->lex->use_only_table_context;
 
1358
  session->lex->use_only_table_context= true;
 
1359
  /* Fix fields referenced to by the virtual column function */
 
1360
  error= func_expr->fix_fields(session, (Item**)0);
 
1361
  /* Restore the original context*/
 
1362
  session->lex->use_only_table_context= save_use_only_table_context;
 
1363
  context->table_list= save_table_list;
 
1364
  context->first_name_resolution_table= save_first_table;
 
1365
  context->last_name_resolution_table= save_last_table;
 
1366
 
 
1367
  if (unlikely(error))
 
1368
  {
 
1369
    clear_field_flag(table);
 
1370
    goto end;
 
1371
  }
 
1372
  session->where= save_where;
 
1373
  /* 
 
1374
    Walk through the Item tree checking if all items are valid 
 
1375
   to be part of the virtual column
 
1376
 */
 
1377
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
1378
  if (error)
 
1379
  {
 
1380
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
1381
    clear_field_flag(table);
 
1382
    goto end;
 
1383
  }
 
1384
  if (unlikely(func_expr->const_item()))
 
1385
  {
 
1386
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
1387
    clear_field_flag(table);
 
1388
    goto end;
 
1389
  }
 
1390
  /* Ensure that this virtual column is not based on another virtual field. */
 
1391
  ptr= table->field;
 
1392
  while ((field= *(ptr++))) 
 
1393
  {
 
1394
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
1395
        (field->vcol_info))
 
1396
    {
 
1397
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
1398
      clear_field_flag(table);
 
1399
      goto end;
 
1400
    }
 
1401
  }
 
1402
  /*
 
1403
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
 
1404
    when calling fix_fields.
 
1405
  */
 
1406
  clear_field_flag(table);
 
1407
  result= false;
 
1408
 
 
1409
end:
 
1410
  table->get_fields_in_item_tree= false;
 
1411
  session->mark_used_columns= save_mark_used_columns;
 
1412
  table->map= 0; //Restore old value
 
1413
  return(result);
 
1414
}
 
1415
 
 
1416
/*
 
1417
  Unpack the definition of a virtual column
 
1418
 
 
1419
  SYNOPSIS
 
1420
    unpack_vcol_info_from_frm()
 
1421
    session                  Thread handler
 
1422
    table                Table with the checked field
 
1423
    field                Pointer to Field object
 
1424
    open_mode            Open table mode needed to determine
 
1425
                         which errors need to be generated in a failure
 
1426
    error_reported       updated flag for the caller that no other error
 
1427
                         messages are to be generated.
 
1428
 
 
1429
  RETURN VALUES
 
1430
    true            Failure
 
1431
    false           Success
 
1432
*/
 
1433
bool unpack_vcol_info_from_frm(Session *session,
 
1434
                               Table *table,
 
1435
                               Field *field,
 
1436
                               LEX_STRING *vcol_expr,
 
1437
                               open_table_mode open_mode,
 
1438
                               bool *error_reported)
 
1439
{
 
1440
  assert(vcol_expr);
 
1441
 
 
1442
  /* 
 
1443
    Step 1: Construct a statement for the parser.
 
1444
    The parsed string needs to take the following format:
 
1445
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
 
1446
  */
 
1447
  char *vcol_expr_str;
 
1448
  int str_len= 0;
 
1449
  
 
1450
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
 
1451
                                          vcol_expr->length + 
 
1452
                                            parse_vcol_keyword.length + 3)))
 
1453
  {
 
1454
    return(true);
 
1455
  }
 
1456
  memcpy(vcol_expr_str,
 
1457
         (char*) parse_vcol_keyword.str,
 
1458
         parse_vcol_keyword.length);
 
1459
  str_len= parse_vcol_keyword.length;
 
1460
  memcpy(vcol_expr_str + str_len, "(", 1);
 
1461
  str_len++;
 
1462
  memcpy(vcol_expr_str + str_len, 
 
1463
         (char*) vcol_expr->str, 
 
1464
         vcol_expr->length);
 
1465
  str_len+= vcol_expr->length;
 
1466
  memcpy(vcol_expr_str + str_len, ")", 1);
 
1467
  str_len++;
 
1468
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
1469
  str_len++;
 
1470
  Lex_input_stream lip(session, vcol_expr_str, str_len);
 
1471
 
 
1472
  /* 
 
1473
    Step 2: Setup session for parsing.
 
1474
    1) make Item objects be created in the memory allocated for the Table
 
1475
       object (not TABLE_SHARE)
 
1476
    2) ensure that created Item's are not put on to session->free_list 
 
1477
       (which is associated with the parsed statement and hence cleared after 
 
1478
       the parsing)
 
1479
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR" 
 
1480
       to be parsed as a SQL command.
 
1481
  */
 
1482
  MEM_ROOT **root_ptr, *old_root;
 
1483
  Item *backup_free_list= session->free_list;
 
1484
  root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
 
1485
  old_root= *root_ptr;
 
1486
  *root_ptr= &table->mem_root;
 
1487
  session->free_list= NULL;
 
1488
  session->lex->parse_vcol_expr= true;
 
1489
 
 
1490
  /* 
 
1491
    Step 3: Use the parser to build an Item object from.
 
1492
  */
 
1493
  if (parse_sql(session, &lip))
 
1494
  {
 
1495
    goto parse_err;
 
1496
  }
 
1497
  /* From now on use vcol_info generated by the parser. */
 
1498
  field->vcol_info= session->lex->vcol_info;
 
1499
 
 
1500
  /* Validate the Item tree. */
 
1501
  if (fix_fields_vcol_func(session,
 
1502
                           field->vcol_info->expr_item,
 
1503
                           table,
 
1504
                           field->field_name))
 
1505
  {
 
1506
    if (open_mode == OTM_CREATE)
 
1507
    {
 
1508
      /*
 
1509
        During CREATE/ALTER TABLE it is ok to receive errors here.
 
1510
        It is not ok if it happens during the opening of an frm
 
1511
        file as part of a normal query.
 
1512
      */
 
1513
      *error_reported= true;
 
1514
    }
 
1515
    field->vcol_info= NULL;
 
1516
    goto parse_err;
 
1517
  }
 
1518
  field->vcol_info->item_free_list= session->free_list;
 
1519
  session->free_list= backup_free_list;
 
1520
  *root_ptr= old_root;
 
1521
 
 
1522
  return(false);
 
1523
 
 
1524
parse_err:
 
1525
  session->lex->parse_vcol_expr= false;
 
1526
  session->free_items();
 
1527
  *root_ptr= old_root;
 
1528
  session->free_list= backup_free_list;
 
1529
  return(true);
 
1530
}
 
1531
 
 
1532
 
 
1533
/*
1182
1534
  Open a table based on a TABLE_SHARE
1183
1535
 
1184
1536
  SYNOPSIS
1185
1537
    open_table_from_share()
1186
 
    thd                 Thread handler
 
1538
    session                     Thread handler
1187
1539
    share               Table definition
1188
1540
    alias               Alias for table
1189
1541
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1206
1558
   7    Table definition has changed in engine
1207
1559
*/
1208
1560
 
1209
 
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1210
 
                          uint db_stat, uint prgflag, uint ha_open_flags,
 
1561
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
 
1562
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1211
1563
                          Table *outparam, open_table_mode open_mode)
1212
1564
{
1213
1565
  int error;
1214
 
  uint records, i, bitmap_size;
 
1566
  uint32_t records, i, bitmap_size;
1215
1567
  bool error_reported= false;
1216
 
  uchar *record, *bitmaps;
1217
 
  Field **field_ptr;
 
1568
  unsigned char *record, *bitmaps;
 
1569
  Field **field_ptr, **vfield_ptr;
1218
1570
 
1219
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
1220
 
  assert(thd->lex->is_lex_started);
 
1571
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1572
  assert(session->lex->is_lex_started);
1221
1573
 
1222
1574
  error= 1;
1223
1575
  memset(outparam, 0, sizeof(*outparam));
1224
 
  outparam->in_use= thd;
 
1576
  outparam->in_use= session;
1225
1577
  outparam->s= share;
1226
1578
  outparam->db_stat= db_stat;
1227
1579
  outparam->write_row_record= NULL;
1256
1608
  if (prgflag & (READ_ALL+EXTRA_RECORD))
1257
1609
    records++;
1258
1610
 
1259
 
  if (!(record= (uchar*) alloc_root(&outparam->mem_root,
 
1611
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1260
1612
                                   share->rec_buff_length * records)))
1261
1613
    goto err;                                   /* purecov: inspected */
1262
1614
 
1296
1648
 
1297
1649
  outparam->field= field_ptr;
1298
1650
 
1299
 
  record= (uchar*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
1651
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1300
1652
  if (share->null_field_first)
1301
 
    outparam->null_flags= (uchar*) record+1;
 
1653
    outparam->null_flags= (unsigned char*) record+1;
1302
1654
  else
1303
 
    outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
 
1655
    outparam->null_flags= (unsigned char*) (record+ 1+ share->reclength -
1304
1656
                                    share->null_bytes);
1305
1657
 
1306
1658
  /* Setup copy of fields from share, but use the right alias and record */
1323
1675
  {
1324
1676
    KEY *key_info, *key_info_end;
1325
1677
    KEY_PART_INFO *key_part;
1326
 
    uint n_length;
 
1678
    uint32_t n_length;
1327
1679
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1328
1680
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1329
1681
      goto err;
1330
1682
    outparam->key_info= key_info;
1331
 
    key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
 
1683
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1332
1684
    
1333
1685
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1334
1686
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1364
1716
    }
1365
1717
  }
1366
1718
 
 
1719
  /*
 
1720
    Process virtual columns, if any.
 
1721
  */
 
1722
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1723
                                              (uint) ((share->vfields+1)*
 
1724
                                                      sizeof(Field*)))))
 
1725
    goto err;
 
1726
 
 
1727
  outparam->vfield= vfield_ptr;
 
1728
  
 
1729
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
1730
  {
 
1731
    if ((*field_ptr)->vcol_info)
 
1732
    {
 
1733
      if (unpack_vcol_info_from_frm(session,
 
1734
                                    outparam,
 
1735
                                    *field_ptr,
 
1736
                                    &(*field_ptr)->vcol_info->expr_str,
 
1737
                                    open_mode,
 
1738
                                    &error_reported))
 
1739
      {
 
1740
        error= 4; // in case no error is reported
 
1741
        goto err;
 
1742
      }
 
1743
      *(vfield_ptr++)= *field_ptr;
 
1744
    }
 
1745
  }
 
1746
  *vfield_ptr= NULL;                              // End marker
 
1747
  /* Check virtual columns against table's storage engine. */
 
1748
  if ((share->vfields && outparam->file) && 
 
1749
        (not outparam->file->check_if_supported_virtual_columns()))
 
1750
  {
 
1751
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
1752
             MYF(0), 
 
1753
             "Specified storage engine");
 
1754
    error_reported= true;
 
1755
    goto err;
 
1756
  }
 
1757
 
1367
1758
  /* Allocate bitmaps */
1368
1759
 
1369
1760
  bitmap_size= share->column_bitmap_size;
1370
 
  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
 
1761
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1371
1762
    goto err;
1372
1763
  bitmap_init(&outparam->def_read_set,
1373
1764
              (my_bitmap_map*) bitmaps, share->fields, false);
1429
1820
  memset(bitmaps, 0, bitmap_size*3);
1430
1821
#endif
1431
1822
 
1432
 
  outparam->no_replicate= outparam->file &&
1433
 
                          test(outparam->file->ha_table_flags() &
1434
 
                               HA_HAS_OWN_BINLOGGING);
1435
 
  thd->status_var.opened_tables++;
 
1823
  outparam->no_replicate= outparam->file;
 
1824
  session->status_var.opened_tables++;
1436
1825
 
1437
1826
  return (0);
1438
1827
 
1443
1832
  outparam->file= 0;                            // For easier error checking
1444
1833
  outparam->db_stat=0;
1445
1834
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1446
 
  my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
 
1835
  free((char*) outparam->alias);
1447
1836
  return (error);
1448
1837
}
1449
1838
 
1463
1852
 
1464
1853
  if (table->db_stat)
1465
1854
    error=table->file->close();
1466
 
  my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
 
1855
  free((char*) table->alias);
1467
1856
  table->alias= 0;
1468
1857
  if (table->field)
1469
1858
  {
1489
1878
 
1490
1879
void free_blobs(register Table *table)
1491
1880
{
1492
 
  uint *ptr, *end;
 
1881
  uint32_t *ptr, *end;
1493
1882
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1494
1883
       ptr != end ;
1495
1884
       ptr++)
1498
1887
 
1499
1888
 
1500
1889
        /* Find where a form starts */
1501
 
        /* if formname is NullS then only formnames is read */
 
1890
        /* if formname is NULL then only formnames is read */
1502
1891
 
1503
 
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
 
1892
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
1504
1893
{
1505
 
  uint a_length,names,length;
1506
 
  uchar *pos,*buf;
 
1894
  uint32_t a_length,names,length;
 
1895
  unsigned char *pos,*buf;
1507
1896
  ulong ret_value=0;
1508
1897
 
1509
1898
  names=uint2korr(head+8);
1517
1906
  if (names)
1518
1907
  {
1519
1908
    length=uint2korr(head+4);
1520
 
    VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0)));
1521
 
    if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
 
1909
    my_seek(file,64L,MY_SEEK_SET,MYF(0));
 
1910
    if (!(buf= (unsigned char*) my_malloc((size_t) length+a_length+names*4,
1522
1911
                                  MYF(MY_WME))) ||
1523
1912
        my_read(file, buf+a_length, (size_t) (length+names*4),
1524
1913
                MYF(MY_NABP)))
1525
1914
    {                                           /* purecov: inspected */
1526
 
      x_free((uchar*) buf);                     /* purecov: inspected */
 
1915
      if (buf)
 
1916
        free(buf);
1527
1917
      return(0L);                               /* purecov: inspected */
1528
1918
    }
1529
1919
    pos= buf+a_length+length;
1532
1922
  if (! save_names)
1533
1923
  {
1534
1924
    if (names)
1535
 
      my_free((uchar*) buf,MYF(0));
 
1925
      free((unsigned char*) buf);
1536
1926
  }
1537
1927
  else if (!names)
1538
1928
    memset(save_names, 0, sizeof(save_names));
1553
1943
    We add an \0 at end of the read string to make reading of C strings easier
1554
1944
*/
1555
1945
 
1556
 
int read_string(File file, uchar**to, size_t length)
 
1946
int read_string(File file, unsigned char**to, size_t length)
1557
1947
{
1558
1948
 
1559
 
  x_free(*to);
1560
 
  if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
 
1949
  if (*to)
 
1950
    free(*to);
 
1951
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
1561
1952
      my_read(file, *to, length,MYF(MY_NABP)))
1562
1953
  {
1563
 
    x_free(*to);                              /* purecov: inspected */
1564
 
    *to= 0;                                   /* purecov: inspected */
 
1954
    if (*to)
 
1955
      free(*to);
 
1956
    *to= NULL;
1565
1957
    return(1);                           /* purecov: inspected */
1566
1958
  }
1567
1959
  *((char*) *to+length)= '\0';
1571
1963
 
1572
1964
        /* Add a new form to a form file */
1573
1965
 
1574
 
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
 
1966
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1575
1967
                     const char *newname)
1576
1968
{
1577
 
  uint i,bufflength,maxlength,n_length,length,names;
 
1969
  uint32_t i,bufflength,maxlength,n_length,length,names;
1578
1970
  ulong endpos,newpos;
1579
 
  uchar buff[IO_SIZE];
1580
 
  uchar *pos;
 
1971
  unsigned char buff[IO_SIZE];
 
1972
  unsigned char *pos;
1581
1973
 
1582
1974
  length=(uint) strlen(newname)+1;
1583
1975
  n_length=uint2korr(fileinfo+4);
1594
1986
 
1595
1987
    while (endpos > maxlength)
1596
1988
    {
1597
 
      VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
 
1989
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
1598
1990
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1599
1991
        return(0L);
1600
 
      VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1601
 
                   MYF(0)));
 
1992
      my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
 
1993
                   MYF(0));
1602
1994
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1603
1995
        return(0);
1604
1996
      endpos-=bufflength; bufflength=IO_SIZE;
1605
1997
    }
1606
1998
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1607
 
    VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
 
1999
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
1608
2000
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1609
2001
        return(0L);
1610
2002
    maxlength+=IO_SIZE;                         /* Fix old ref */
1611
2003
    int2store(fileinfo+6,maxlength);
1612
 
    for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
 
2004
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1613
2005
         pos+=4)
1614
2006
    {
1615
2007
      endpos=uint4korr(pos)+IO_SIZE;
1620
2012
  if (n_length == 1 )
1621
2013
  {                                             /* First name */
1622
2014
    length++;
1623
 
    VOID(strxmov((char*) buff,"/",newname,"/",NullS));
 
2015
    strxmov((char*) buff,"/",newname,"/",NULL);
1624
2016
  }
1625
2017
  else
1626
 
    VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1627
 
  VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
 
2018
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
 
2019
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
1628
2020
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1629
 
      (names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
 
2021
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1630
2022
                         names*4, MYF(MY_NABP+MY_WME))) ||
1631
2023
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1632
2024
    return(0L); /* purecov: inspected */
1633
2025
 
1634
2026
  int2store(fileinfo+8,names+1);
1635
2027
  int2store(fileinfo+4,n_length+length);
1636
 
  (void)ftruncate(file, newpos);/* Append file with '\0' */
 
2028
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1637
2029
  return(newpos);
1638
2030
} /* make_new_entry */
1639
2031
 
1653
2045
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1654
2046
    else
1655
2047
    {
1656
 
      strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
2048
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1657
2049
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1658
2050
               errortype, buff, db_errno);
1659
2051
    }
1665
2057
    
1666
2058
    if (share->db_type() != NULL)
1667
2059
    {
1668
 
      if ((file= get_new_handler(share, current_thd->mem_root,
 
2060
      if ((file= get_new_handler(share, current_session->mem_root,
1669
2061
                                 share->db_type())))
1670
2062
      {
1671
2063
        if (!(datext= *file->bas_ext()))
1674
2066
    }
1675
2067
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1676
2068
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1677
 
    strxmov(buff, share->normalized_path.str, datext, NullS);
 
2069
    strxmov(buff, share->normalized_path.str, datext, NULL);
1678
2070
    my_error(err_no,errortype, buff, db_errno);
1679
2071
    delete file;
1680
2072
    break;
1694
2086
    break;
1695
2087
  }
1696
2088
  case 6:
1697
 
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
2089
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1698
2090
    my_printf_error(ER_NOT_FORM_FILE,
1699
2091
                    _("Table '%-.64s' was created with a different version "
1700
2092
                    "of MySQL and cannot be read"), 
1704
2096
    break;
1705
2097
  default:                              /* Better wrong error than none */
1706
2098
  case 4:
1707
 
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
2099
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1708
2100
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1709
2101
    break;
1710
2102
  }
1719
2111
        */
1720
2112
 
1721
2113
static void
1722
 
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
 
2114
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
1723
2115
                  char **names)
1724
2116
{
1725
2117
  char *type_name, *ptr;
1733
2125
 
1734
2126
    if ((chr= *ptr))                    /* Test if empty type */
1735
2127
    {
1736
 
      while ((type_name=strchr(ptr+1,chr)) != NullS)
 
2128
      while ((type_name=strchr(ptr+1,chr)) != NULL)
1737
2129
      {
1738
2130
        *((*array)++) = ptr+1;
1739
2131
        *type_name= '\0';               /* End string */
1745
2137
      ptr++;
1746
2138
    point_to_type->count= (uint) (*array - point_to_type->type_names);
1747
2139
    point_to_type++;
1748
 
    *((*array)++)= NullS;               /* End of type */
 
2140
    *((*array)++)= NULL;                /* End of type */
1749
2141
  }
1750
2142
  *names=ptr;                           /* Update end */
1751
2143
  return;
1759
2151
    return 0;
1760
2152
  result->count=strings.elements;
1761
2153
  result->name="";
1762
 
  uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
2154
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1763
2155
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1764
2156
    return 0;
1765
2157
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1766
2158
  List_iterator<String> it(strings);
1767
2159
  String *tmp;
1768
 
  for (uint i=0; (tmp=it++) ; i++)
 
2160
  for (uint32_t i=0; (tmp=it++) ; i++)
1769
2161
  {
1770
2162
    result->type_names[i]= tmp->ptr();
1771
2163
    result->type_lengths[i]= tmp->length();
1789
2181
   #  field number +1
1790
2182
*/
1791
2183
 
1792
 
static uint find_field(Field **fields, uchar *record, uint start, uint length)
 
2184
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length)
1793
2185
{
1794
2186
  Field **field;
1795
 
  uint i, pos;
 
2187
  uint32_t i, pos;
1796
2188
 
1797
2189
  pos= 0;
1798
2190
  for (field= fields, i=1 ; *field ; i++,field++)
1846
2238
    May fail with some multibyte charsets though.
1847
2239
*/
1848
2240
 
1849
 
void append_unescaped(String *res, const char *pos, uint length)
 
2241
void append_unescaped(String *res, const char *pos, uint32_t length)
1850
2242
{
1851
2243
  const char *end= pos+length;
1852
2244
  res->append('\'');
1854
2246
  for (; pos != end ; pos++)
1855
2247
  {
1856
2248
#if defined(USE_MB)
1857
 
    uint mblen;
 
2249
    uint32_t mblen;
1858
2250
    if (use_mb(default_charset_info) &&
1859
2251
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1860
2252
    {
1896
2288
 
1897
2289
        /* Create a .frm file */
1898
2290
 
1899
 
File create_frm(THD *thd, const char *name, const char *db,
1900
 
                const char *table, uint reclength, uchar *fileinfo,
1901
 
                HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
 
2291
File create_frm(Session *session, const char *name, const char *db,
 
2292
                const char *table, uint32_t reclength, unsigned char *fileinfo,
 
2293
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
1902
2294
{
1903
2295
  register File file;
1904
2296
  ulong length;
1905
 
  uchar fill[IO_SIZE];
 
2297
  unsigned char fill[IO_SIZE];
1906
2298
  int create_flags= O_RDWR | O_TRUNC;
1907
2299
  ulong key_comment_total_bytes= 0;
1908
 
  uint i;
 
2300
  uint32_t i;
1909
2301
 
1910
2302
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1911
 
    create_flags|= O_EXCL | O_NOFOLLOW;
 
2303
    create_flags|= O_EXCL;
1912
2304
 
1913
2305
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
1914
2306
  if (create_info->max_rows > UINT32_MAX)
1918
2310
 
1919
2311
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
1920
2312
  {
1921
 
    uint key_length, tmp_key_length;
1922
 
    uint tmp;
 
2313
    uint32_t key_length, tmp_key_length;
 
2314
    uint32_t tmp;
1923
2315
    memset(fileinfo, 0, 64);
1924
2316
    /* header */
1925
 
    fileinfo[0]=(uchar) 254;
 
2317
    fileinfo[0]=(unsigned char) 254;
1926
2318
    fileinfo[1]= 1;
1927
2319
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
1928
2320
 
1929
 
    fileinfo[3]= (uchar) ha_legacy_type(
1930
 
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
 
2321
    fileinfo[3]= (unsigned char) ha_legacy_type(
 
2322
          ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
1931
2323
    fileinfo[4]=1;
1932
2324
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
1933
2325
    for (i= 0; i < keys; i++)
1970
2362
    int4store(fileinfo+34,create_info->avg_row_length);
1971
2363
    fileinfo[38]= (create_info->default_table_charset ?
1972
2364
                   create_info->default_table_charset->number : 0);
1973
 
    fileinfo[39]= (uchar) ((uint) create_info->transactional |
1974
 
                           ((uint) create_info->page_checksum << 2));
1975
 
    fileinfo[40]= (uchar) create_info->row_type;
1976
 
    /* Next few bytes where for RAID support */
 
2365
    fileinfo[39]= (unsigned char) create_info->page_checksum;
 
2366
    fileinfo[40]= (unsigned char) create_info->row_type;
 
2367
    /* Next few bytes were for RAID support */
1977
2368
    fileinfo[41]= 0;
1978
2369
    fileinfo[42]= 0;
1979
2370
    int4store(fileinfo+43,create_info->block_size);
1995
2386
    {
1996
2387
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
1997
2388
      {
1998
 
        VOID(my_close(file,MYF(0)));
1999
 
        VOID(my_delete(name,MYF(0)));
 
2389
        my_close(file,MYF(0));
 
2390
        my_delete(name,MYF(0));
2000
2391
        return(-1);
2001
2392
      }
2002
2393
    }
2019
2410
    a tmp_set bitmap to be used by things like filesort.
2020
2411
*/
2021
2412
 
2022
 
void Table::setup_tmp_table_column_bitmaps(uchar *bitmaps)
 
2413
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
2023
2414
{
2024
 
  uint field_count= s->fields;
 
2415
  uint32_t field_count= s->fields;
2025
2416
 
2026
2417
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
2027
2418
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
2054
2445
rename_file_ext(const char * from,const char * to,const char * ext)
2055
2446
{
2056
2447
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
2057
 
  VOID(strxmov(from_b,from,ext,NullS));
2058
 
  VOID(strxmov(to_b,to,ext,NullS));
 
2448
  strxmov(from_b,from,ext,NULL);
 
2449
  strxmov(to_b,to,ext,NULL);
2059
2450
  return (my_rename(from_b,to_b,MYF(MY_WME)));
2060
2451
}
2061
2452
 
2078
2469
{
2079
2470
  char buff[MAX_FIELD_WIDTH], *to;
2080
2471
  String str(buff,sizeof(buff),&my_charset_bin);
2081
 
  uint length;
 
2472
  uint32_t length;
2082
2473
 
2083
2474
  field->val_str(&str);
2084
2475
  if (!(length= str.length()))
2102
2493
    field       Field for retrieving of string
2103
2494
 
2104
2495
  RETURN VALUES
2105
 
    NullS  string is empty
 
2496
    NULL  string is empty
2106
2497
    #      pointer to NULL-terminated string value of field
2107
2498
*/
2108
2499
 
2110
2501
{
2111
2502
  char buff[MAX_FIELD_WIDTH], *to;
2112
2503
  String str(buff,sizeof(buff),&my_charset_bin);
2113
 
  uint length;
 
2504
  uint32_t length;
2114
2505
 
2115
2506
  field->val_str(&str);
2116
2507
  length= str.length();
2117
2508
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2118
 
    return NullS;
 
2509
    return NULL;
2119
2510
  memcpy(to,str.ptr(),(uint) length);
2120
2511
  to[length]=0;
2121
2512
  return to;
2126
2517
    given a buffer with a key value, and a map of keyparts
2127
2518
    that are present in this value, returns the length of the value
2128
2519
*/
2129
 
uint calculate_key_len(Table *table, uint key,
2130
 
                       const uchar *buf __attribute__((unused)),
 
2520
uint32_t calculate_key_len(Table *table, uint32_t key,
 
2521
                       const unsigned char *,
2131
2522
                       key_part_map keypart_map)
2132
2523
{
2133
2524
  /* works only with key prefixes */
2136
2527
  KEY *key_info= table->s->key_info+key;
2137
2528
  KEY_PART_INFO *key_part= key_info->key_part;
2138
2529
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
2139
 
  uint length= 0;
 
2530
  uint32_t length= 0;
2140
2531
 
2141
2532
  while (key_part < end_key_part && keypart_map)
2142
2533
  {
2165
2556
bool check_db_name(LEX_STRING *org_name)
2166
2557
{
2167
2558
  char *name= org_name->str;
2168
 
  uint name_length= org_name->length;
 
2559
  uint32_t name_length= org_name->length;
2169
2560
 
2170
2561
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
2171
2562
    return 1;
2184
2575
*/
2185
2576
 
2186
2577
 
2187
 
bool check_table_name(const char *name, uint length)
 
2578
bool check_table_name(const char *name, uint32_t length)
2188
2579
{
2189
2580
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
2190
2581
    return 1;
2202
2593
*/
2203
2594
bool check_column_name(const char *name)
2204
2595
{
2205
 
  uint name_length= 0;  // name length in symbols
 
2596
  uint32_t name_length= 0;  // name length in symbols
2206
2597
  bool last_char_is_space= true;
2207
2598
  
2208
2599
  while (*name)
2258
2649
*/
2259
2650
 
2260
2651
bool
2261
 
Table::table_check_intact(const uint table_f_count,
 
2652
Table::table_check_intact(const uint32_t table_f_count,
2262
2653
                          const TABLE_FIELD_W_TYPE *table_def)
2263
2654
{
2264
 
  uint i;
 
2655
  uint32_t i;
2265
2656
  bool error= false;
2266
2657
  bool fields_diff_count;
2267
2658
 
2386
2777
  DESCRIPTION
2387
2778
    Create Item_field object for each column in the table and
2388
2779
    initialize it with the corresponding Field. New items are
2389
 
    created in the current THD memory root.
 
2780
    created in the current Session memory root.
2390
2781
 
2391
2782
  RETURN VALUE
2392
2783
    0                    success
2499
2890
  if (table)
2500
2891
  {
2501
2892
    if (!table->insert_values &&
2502
 
        !(table->insert_values= (uchar *)alloc_root(mem_root,
 
2893
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
2503
2894
                                                   table->s->rec_buff_length)))
2504
2895
      return true;
2505
2896
  }
2695
3086
    or Table::restore_column_maps_after_mark_index()
2696
3087
*/
2697
3088
 
2698
 
void Table::mark_columns_used_by_index(uint index)
 
3089
void Table::mark_columns_used_by_index(uint32_t index)
2699
3090
{
2700
3091
  MY_BITMAP *bitmap= &tmp_set;
2701
3092
 
2733
3124
  mark columns used by key, but don't reset other fields
2734
3125
*/
2735
3126
 
2736
 
void Table::mark_columns_used_by_index_no_reset(uint index,
 
3127
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2737
3128
                                                   MY_BITMAP *bitmap)
2738
3129
{
2739
3130
  KEY_PART_INFO *key_part= key_info[index].key_part;
2740
3131
  KEY_PART_INFO *key_part_end= (key_part +
2741
3132
                                key_info[index].key_parts);
2742
3133
  for (;key_part != key_part_end; key_part++)
 
3134
  {
2743
3135
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3136
    if (key_part->field->vcol_info &&
 
3137
        key_part->field->vcol_info->expr_item)
 
3138
      key_part->field->vcol_info->
 
3139
               expr_item->walk(&Item::register_field_in_bitmap, 
 
3140
                               1, (unsigned char *) bitmap);
 
3141
  }
2744
3142
}
2745
3143
 
2746
3144
 
2866
3264
      file->column_bitmaps_signal();
2867
3265
    }
2868
3266
  }
 
3267
  /* Mark all virtual columns as writable */
 
3268
  mark_virtual_columns();
2869
3269
  return;
2870
3270
}
2871
3271
 
2881
3281
{
2882
3282
  if (found_next_number_field)
2883
3283
    mark_auto_increment_column();
2884
 
}
 
3284
  /* Mark all virtual columns as writable */
 
3285
  mark_virtual_columns();
 
3286
}
 
3287
 
 
3288
/* 
 
3289
  @brief Update the write and read table bitmap to allow
 
3290
         using procedure save_in_field for all virtual columns
 
3291
         in the table.
 
3292
 
 
3293
  @return       void
 
3294
 
 
3295
  @detail
 
3296
    Each virtual field is set in the write column map.
 
3297
    All fields that the virtual columns are based on are set in the
 
3298
    read bitmap.
 
3299
*/
 
3300
 
 
3301
void Table::mark_virtual_columns(void)
 
3302
{
 
3303
  Field **vfield_ptr, *tmp_vfield;
 
3304
  bool bitmap_updated= false;
 
3305
 
 
3306
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3307
  {
 
3308
    tmp_vfield= *vfield_ptr;
 
3309
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3310
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map, 
 
3311
                                           1, (unsigned char *) 0);
 
3312
    bitmap_set_bit(read_set, tmp_vfield->field_index);
 
3313
    bitmap_set_bit(write_set, tmp_vfield->field_index);
 
3314
    bitmap_updated= true;
 
3315
  }
 
3316
  if (bitmap_updated)
 
3317
    file->column_bitmaps_signal();
 
3318
}
 
3319
 
2885
3320
 
2886
3321
/*
2887
3322
  Cleanup this table for re-execution.
2890
3325
    TableList::reinit_before_use()
2891
3326
*/
2892
3327
 
2893
 
void TableList::reinit_before_use(THD *thd)
 
3328
void TableList::reinit_before_use(Session *session)
2894
3329
{
2895
3330
  /*
2896
3331
    Reset old pointers to TABLEs: they are not valid since the tables
2906
3341
  {
2907
3342
    embedded= parent_embedding;
2908
3343
    if (embedded->prep_on_expr)
2909
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
3344
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
2910
3345
    parent_embedding= embedded->embedding;
2911
3346
  }
2912
3347
  while (parent_embedding &&
3011
3446
    /* iterate over the hints list */
3012
3447
    while ((hint= iter++))
3013
3448
    {
3014
 
      uint pos;
 
3449
      uint32_t pos;
3015
3450
 
3016
3451
      /* process empty USE INDEX () */
3017
3452
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
3101
3536
}
3102
3537
 
3103
3538
 
3104
 
size_t Table::max_row_length(const uchar *data)
 
3539
size_t Table::max_row_length(const unsigned char *data)
3105
3540
{
3106
3541
  size_t length= getRecordLength() + 2 * sizeFields();
3107
 
  uint *const beg= getBlobField();
3108
 
  uint *const end= beg + sizeBlobFields();
 
3542
  uint32_t *const beg= getBlobField();
 
3543
  uint32_t *const end= beg + sizeBlobFields();
3109
3544
 
3110
 
  for (uint *ptr= beg ; ptr != end ; ++ptr)
 
3545
  for (uint32_t *ptr= beg ; ptr != end ; ++ptr)
3111
3546
  {
3112
3547
    Field_blob* const blob= (Field_blob*) field[*ptr];
3113
 
    length+= blob->get_length((const uchar*)
 
3548
    length+= blob->get_length((const unsigned char*)
3114
3549
                              (data + blob->offset(record[0]))) +
3115
3550
      HA_KEY_BLOB_LENGTH;
3116
3551
  }
3129
3564
  true       table
3130
3565
*/
3131
3566
 
3132
 
bool mysql_frm_type(THD *thd __attribute__((unused)),
3133
 
                    char *path, enum legacy_db_type *dbt)
 
3567
bool mysql_frm_type(Session *, char *path, enum legacy_db_type *dbt)
3134
3568
{
3135
3569
  File file;
3136
 
  uchar header[10];     /* This should be optimized */
 
3570
  unsigned char header[10];     /* This should be optimized */
3137
3571
  int error;
3138
3572
 
3139
3573
  *dbt= DB_TYPE_UNKNOWN;
3140
3574
 
3141
 
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
3575
  if ((file= open(path, O_RDONLY)) < 0)
3142
3576
    return false;
3143
 
  error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
 
3577
  error= my_read(file, (unsigned char*) header, sizeof(header), MYF(MY_NABP));
3144
3578
  my_close(file, MYF(MY_WME));
3145
3579
 
3146
3580
  if (error)
3151
3585
    if the following test is true (arg #3). This should not have effect
3152
3586
    on return value from this function (default FRMTYPE_TABLE)
3153
3587
   */  
3154
 
  if (header[0] != (uchar) 254 || header[1] != 1 ||
 
3588
  if (header[0] != (unsigned char) 254 || header[1] != 1 ||
3155
3589
      (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
3156
3590
       (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
3157
3591
    return true;
3166
3600
 
3167
3601
 
3168
3602
/* Prototypes */
3169
 
void free_tmp_table(THD *thd, Table *entry);
 
3603
void free_tmp_table(Session *session, Table *entry);
3170
3604
 
3171
3605
/**
3172
3606
  Create field for temporary table from given field.
3173
3607
 
3174
 
  @param thd           Thread handler
 
3608
  @param session               Thread handler
3175
3609
  @param org_field    field from which new field will be created
3176
3610
  @param name         New field name
3177
3611
  @param table         Temporary table
3190
3624
    new_created field
3191
3625
*/
3192
3626
 
3193
 
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
 
3627
Field *create_tmp_field_from_field(Session *session, Field *org_field,
3194
3628
                                   const char *name, Table *table,
3195
 
                                   Item_field *item, uint convert_blob_length)
 
3629
                                   Item_field *item, uint32_t convert_blob_length)
3196
3630
{
3197
3631
  Field *new_field;
3198
3632
 
3207
3641
                                   org_field->field_name, table->s,
3208
3642
                                   org_field->charset());
3209
3643
  else
3210
 
    new_field= org_field->new_field(thd->mem_root, table,
 
3644
    new_field= org_field->new_field(session->mem_root, table,
3211
3645
                                    table == org_field->table);
3212
3646
  if (new_field)
3213
3647
  {
3231
3665
/**
3232
3666
  Create field for temporary table using type of given item.
3233
3667
 
3234
 
  @param thd                   Thread handler
 
3668
  @param session                   Thread handler
3235
3669
  @param item                  Item to create a field for
3236
3670
  @param table                 Temporary table
3237
3671
  @param copy_func             If set and item is a function, store copy of
3252
3686
    new_created field
3253
3687
*/
3254
3688
 
3255
 
static Field *create_tmp_field_from_item(THD *thd __attribute__((unused)),
 
3689
static Field *create_tmp_field_from_item(Session *,
3256
3690
                                         Item *item, Table *table,
3257
3691
                                         Item ***copy_func, bool modify_item,
3258
 
                                         uint convert_blob_length)
 
3692
                                         uint32_t convert_blob_length)
3259
3693
{
3260
3694
  bool maybe_null= item->maybe_null;
3261
3695
  Field *new_field;
3321
3755
    {
3322
3756
      signed int overflow;
3323
3757
 
3324
 
      dec= min(dec, (uint8_t)DECIMAL_MAX_SCALE);
 
3758
      dec= cmin(dec, (uint8_t)DECIMAL_MAX_SCALE);
3325
3759
 
3326
3760
      /*
3327
3761
        If the value still overflows the field with the corrected dec,
3334
3768
                                               item->unsigned_flag) - len;
3335
3769
 
3336
3770
      if (overflow > 0)
3337
 
        dec= max(0, dec - overflow);            // too long, discard fract
 
3771
        dec= cmax(0, dec - overflow);            // too long, discard fract
3338
3772
      else
3339
3773
        len -= item->decimals - dec;            // corrected value fits
3340
3774
    }
3366
3800
/**
3367
3801
  Create field for information schema table.
3368
3802
 
3369
 
  @param thd            Thread handler
 
3803
  @param session                Thread handler
3370
3804
  @param table          Temporary table
3371
3805
  @param item           Item to create a field for
3372
3806
 
3376
3810
    new_created field
3377
3811
*/
3378
3812
 
3379
 
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
3380
 
                                   Item *item, Table *table)
 
3813
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
3381
3814
{
3382
3815
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3383
3816
  {
3400
3833
/**
3401
3834
  Create field for temporary table.
3402
3835
 
3403
 
  @param thd            Thread handler
 
3836
  @param session                Thread handler
3404
3837
  @param table          Temporary table
3405
3838
  @param item           Item to create a field for
3406
3839
  @param type           Type of item (normally item->type)
3426
3859
    new_created field
3427
3860
*/
3428
3861
 
3429
 
Field *create_tmp_field(THD *thd, Table *table,Item *item, Item::Type type,
3430
 
                        Item ***copy_func, Field **from_field,
3431
 
                        Field **default_field,
3432
 
                        bool group, bool modify_item,
3433
 
                        bool table_cant_handle_bit_fields __attribute__((unused)),
3434
 
                        bool make_copy_field,
3435
 
                        uint convert_blob_length)
 
3862
Field *create_tmp_field(Session *session, Table *table,Item *item,
 
3863
                        Item::Type type, Item ***copy_func, Field **from_field,
 
3864
                        Field **default_field, bool group, bool modify_item,
 
3865
                        bool, bool make_copy_field,
 
3866
                        uint32_t convert_blob_length)
3436
3867
{
3437
3868
  Field *result;
3438
3869
  Item::Type orig_type= type;
3468
3899
    */
3469
3900
    if (field->maybe_null && !field->field->maybe_null())
3470
3901
    {
3471
 
      result= create_tmp_field_from_item(thd, item, table, NULL,
 
3902
      result= create_tmp_field_from_item(session, item, table, NULL,
3472
3903
                                         modify_item, convert_blob_length);
3473
3904
      *from_field= field->field;
3474
3905
      if (result && modify_item)
3475
3906
        field->result_field= result;
3476
3907
    } 
3477
3908
    else
3478
 
      result= create_tmp_field_from_field(thd, (*from_field= field->field),
 
3909
      result= create_tmp_field_from_field(session, (*from_field= field->field),
3479
3910
                                          orig_item ? orig_item->name :
3480
3911
                                          item->name,
3481
3912
                                          table,
3509
3940
      assert(((Item_result_field*)item)->result_field);
3510
3941
      *from_field= ((Item_result_field*)item)->result_field;
3511
3942
    }
3512
 
    return create_tmp_field_from_item(thd, item, table,
 
3943
    return create_tmp_field_from_item(session, item, table,
3513
3944
                                      (make_copy_field ? 0 : copy_func),
3514
3945
                                       modify_item, convert_blob_length);
3515
3946
  case Item::TYPE_HOLDER:  
3532
3963
  corresponding Item_field items, pointing at the fields in the
3533
3964
  temporary table, unless this was prohibited by true
3534
3965
  value of argument save_sum_fields. The Item_field objects
3535
 
  are created in THD memory root.
 
3966
  are created in Session memory root.
3536
3967
 
3537
 
  @param thd                  thread handle
 
3968
  @param session                  thread handle
3538
3969
  @param param                a description used as input to create the table
3539
3970
  @param fields               list of items that will be used to define
3540
3971
                              column types of the table (also see NOTES)
3550
3981
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3551
3982
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3552
3983
#define RATIO_TO_PACK_ROWS             2
3553
 
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
3554
3984
 
3555
3985
Table *
3556
 
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
 
3986
create_tmp_table(Session *session,TMP_TABLE_PARAM *param,List<Item> &fields,
3557
3987
                 order_st *group, bool distinct, bool save_sum_fields,
3558
3988
                 uint64_t select_options, ha_rows rows_limit,
3559
3989
                 char *table_alias)
3562
3992
  Table *table;
3563
3993
  TABLE_SHARE *share;
3564
3994
  uint  i,field_count,null_count,null_pack_length;
3565
 
  uint  copy_func_count= param->func_count;
3566
 
  uint  hidden_null_count, hidden_null_pack_length, hidden_field_count;
3567
 
  uint  blob_count,group_null_items, string_count;
3568
 
  uint  temp_pool_slot=MY_BIT_NONE;
3569
 
  uint fieldnr= 0;
 
3995
  uint32_t  copy_func_count= param->func_count;
 
3996
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
 
3997
  uint32_t  blob_count,group_null_items, string_count;
 
3998
  uint32_t  temp_pool_slot=MY_BIT_NONE;
 
3999
  uint32_t fieldnr= 0;
3570
4000
  ulong reclength, string_total_length;
3571
4001
  bool  using_unique_constraint= 0;
3572
4002
  bool  use_packed_rows= 0;
3573
4003
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
3574
4004
  char  *tmpname,path[FN_REFLEN];
3575
 
  uchar *pos, *group_buff, *bitmaps;
3576
 
  uchar *null_flags;
 
4005
  unsigned char *pos, *group_buff, *bitmaps;
 
4006
  unsigned char *null_flags;
3577
4007
  Field **reg_field, **from_field, **default_field;
3578
 
  uint *blob_field;
 
4008
  uint32_t *blob_field;
3579
4009
  Copy_field *copy=0;
3580
4010
  KEY *keyinfo;
3581
4011
  KEY_PART_INFO *key_part_info;
3582
4012
  Item **copy_func;
3583
4013
  MI_COLUMNDEF *recinfo;
3584
 
  uint total_uneven_bit_length= 0;
 
4014
  uint32_t total_uneven_bit_length= 0;
3585
4015
  bool force_copy_fields= param->force_copy_fields;
3586
4016
 
3587
 
  status_var_increment(thd->status_var.created_tmp_tables);
 
4017
  status_var_increment(session->status_var.created_tmp_tables);
3588
4018
 
3589
4019
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3590
4020
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
3595
4025
  else
3596
4026
  {
3597
4027
    /* if we run out of slots or we are not using tempool */
3598
 
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
3599
 
            thd->thread_id, thd->tmp_table++);
 
4028
    sprintf(path,"%s%lx_%"PRIx64"_%x", tmp_file_prefix,current_pid,
 
4029
            session->thread_id, session->tmp_table++);
3600
4030
  }
3601
4031
 
3602
4032
  /*
3660
4090
                        &group_buff, (group && ! using_unique_constraint ?
3661
4091
                                      param->group_length : 0),
3662
4092
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3663
 
                        NullS))
 
4093
                        NULL))
3664
4094
  {
3665
4095
    if (temp_pool_slot != MY_BIT_NONE)
3666
4096
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3667
4097
    return(NULL);                               /* purecov: inspected */
3668
4098
  }
3669
 
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
3670
 
  if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
 
4099
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in Session mem_root */
 
4100
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
3671
4101
  {
3672
4102
    if (temp_pool_slot != MY_BIT_NONE)
3673
4103
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3675
4105
    return(NULL);                               /* purecov: inspected */
3676
4106
  }
3677
4107
  param->items_to_copy= copy_func;
3678
 
  stpcpy(tmpname,path);
 
4108
  my_stpcpy(tmpname,path);
3679
4109
  /* make table according to fields */
3680
4110
 
3681
4111
  memset(table, 0, sizeof(*table));
3684
4114
  memset(from_field, 0, sizeof(Field*)*field_count);
3685
4115
 
3686
4116
  table->mem_root= own_root;
3687
 
  mem_root_save= thd->mem_root;
3688
 
  thd->mem_root= &table->mem_root;
 
4117
  mem_root_save= session->mem_root;
 
4118
  session->mem_root= &table->mem_root;
3689
4119
 
3690
4120
  table->field=reg_field;
3691
4121
  table->alias= table_alias;
3694
4124
  table->map=1;
3695
4125
  table->temp_pool_slot = temp_pool_slot;
3696
4126
  table->copy_blobs= 1;
3697
 
  table->in_use= thd;
 
4127
  table->in_use= session;
3698
4128
  table->quick_keys.init();
3699
4129
  table->covering_keys.init();
3700
4130
  table->keys_in_use_for_query.init();
3701
4131
 
3702
4132
  table->setShare(share);
3703
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
 
4133
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
3704
4134
  share->blob_field= blob_field;
3705
4135
  share->blob_ptr_size= portable_sizeof_char_ptr;
3706
4136
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3752
4182
        if (!arg->const_item())
3753
4183
        {
3754
4184
          Field *new_field=
3755
 
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
 
4185
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
3756
4186
                             tmp_from_field, &default_field[fieldnr],
3757
4187
                             group != 0,not_all_columns,
3758
4188
                             distinct, 0,
3772
4202
            string_count++;
3773
4203
            string_total_length+= new_field->pack_length();
3774
4204
          }
3775
 
          thd->mem_root= mem_root_save;
3776
 
          thd->change_item_tree(argp, new Item_field(new_field));
3777
 
          thd->mem_root= &table->mem_root;
 
4205
          session->mem_root= mem_root_save;
 
4206
          session->change_item_tree(argp, new Item_field(new_field));
 
4207
          session->mem_root= &table->mem_root;
3778
4208
          if (!(new_field->flags & NOT_NULL_FLAG))
3779
4209
          {
3780
4210
            null_count++;
3801
4231
        that in the later case group is set to the row pointer.
3802
4232
      */
3803
4233
      Field *new_field= (param->schema_table) ?
3804
 
        create_tmp_field_for_schema(thd, item, table) :
3805
 
        create_tmp_field(thd, table, item, type, &copy_func,
 
4234
        create_tmp_field_for_schema(session, item, table) :
 
4235
        create_tmp_field(session, table, item, type, &copy_func,
3806
4236
                         tmp_from_field, &default_field[fieldnr],
3807
4237
                         group != 0,
3808
4238
                         !force_copy_fields &&
3820
4250
 
3821
4251
      if (!new_field)
3822
4252
      {
3823
 
        if (thd->is_fatal_error)
 
4253
        if (session->is_fatal_error)
3824
4254
          goto err;                             // Got OOM
3825
4255
        continue;                               // Some kindf of const item
3826
4256
      }
3913
4343
 
3914
4344
  share->reclength= reclength;
3915
4345
  {
3916
 
    uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
 
4346
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
3917
4347
    share->rec_buff_length= alloc_length;
3918
 
    if (!(table->record[0]= (uchar*)
 
4348
    if (!(table->record[0]= (unsigned char*)
3919
4349
                            alloc_root(&table->mem_root, alloc_length*3)))
3920
4350
      goto err;
3921
4351
    table->record[1]= table->record[0]+alloc_length;
3927
4357
  table->setup_tmp_table_column_bitmaps(bitmaps);
3928
4358
 
3929
4359
  recinfo=param->start_recinfo;
3930
 
  null_flags=(uchar*) table->record[0];
 
4360
  null_flags=(unsigned char*) table->record[0];
3931
4361
  pos=table->record[0]+ null_pack_length;
3932
4362
  if (null_pack_length)
3933
4363
  {
3937
4367
    recinfo++;
3938
4368
    memset(null_flags, 255, null_pack_length);  // Set null fields
3939
4369
 
3940
 
    table->null_flags= (uchar*) table->record[0];
 
4370
    table->null_flags= (unsigned char*) table->record[0];
3941
4371
    share->null_fields= null_count+ hidden_null_count;
3942
4372
    share->null_bytes= null_pack_length;
3943
4373
  }
3946
4376
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
3947
4377
  {
3948
4378
    Field *field= *reg_field;
3949
 
    uint length;
 
4379
    uint32_t length;
3950
4380
    memset(recinfo, 0, sizeof(*recinfo));
3951
4381
 
3952
4382
    if (!(field->flags & NOT_NULL_FLAG))
3973
4403
      null_count++;
3974
4404
    }
3975
4405
    else
3976
 
      field->move_field(pos,(uchar*) 0,0);
 
4406
      field->move_field(pos,(unsigned char*) 0,0);
3977
4407
    field->reset();
3978
4408
 
3979
4409
    /*
4028
4458
  param->recinfo=recinfo;
4029
4459
  store_record(table,s->default_values);        // Make empty default record
4030
4460
 
4031
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
 
4461
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
4032
4462
    share->max_rows= ~(ha_rows) 0;
4033
4463
  else
4034
4464
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
4035
 
                                 min(thd->variables.tmp_table_size,
4036
 
                                     thd->variables.max_heap_table_size) :
4037
 
                                 thd->variables.tmp_table_size) /
 
4465
                                 cmin(session->variables.tmp_table_size,
 
4466
                                     session->variables.max_heap_table_size) :
 
4467
                                 session->variables.tmp_table_size) /
4038
4468
                                 share->reclength);
4039
4469
  set_if_bigger(share->max_rows,1);             // For dummy start options
4040
4470
  /*
4078
4508
      if (!using_unique_constraint)
4079
4509
      {
4080
4510
        cur_group->buff=(char*) group_buff;
4081
 
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
 
4511
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
4082
4512
                                                     group_buff +
4083
4513
                                                     test(maybe_null),
4084
4514
                                                     field->null_ptr,
4095
4525
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
4096
4526
          key_part_info->null_bit=field->null_bit;
4097
4527
          key_part_info->null_offset= (uint) (field->null_ptr -
4098
 
                                              (uchar*) table->record[0]);
 
4528
                                              (unsigned char*) table->record[0]);
4099
4529
          cur_group->buff++;                        // Pointer to field data
4100
4530
          group_buff++;                         // Skipp null flag
4101
4531
        }
4155
4585
      key_part_info->field= new Field_varstring(table->record[0],
4156
4586
                                                (uint32_t) key_part_info->length,
4157
4587
                                                0,
4158
 
                                                (uchar*) 0,
 
4588
                                                (unsigned char*) 0,
4159
4589
                                                (uint) 0,
4160
4590
                                                Field::NONE,
4161
 
                                                NullS, 
 
4591
                                                NULL, 
4162
4592
                                                table->s,
4163
4593
                                                &my_charset_bin);
4164
4594
      if (!key_part_info->field)
4202
4632
    }
4203
4633
  }
4204
4634
 
4205
 
  if (thd->is_fatal_error)                              // If end of memory
 
4635
  if (session->is_fatal_error)                          // If end of memory
4206
4636
    goto err;                                    /* purecov: inspected */
4207
4637
  share->db_record_offset= 1;
4208
4638
  if (share->db_type() == myisam_hton)
4214
4644
  if (table->open_tmp_table())
4215
4645
    goto err;
4216
4646
 
4217
 
  thd->mem_root= mem_root_save;
 
4647
  session->mem_root= mem_root_save;
4218
4648
 
4219
4649
  return(table);
4220
4650
 
4221
4651
err:
4222
 
  thd->mem_root= mem_root_save;
4223
 
  table->free_tmp_table(thd);                    /* purecov: inspected */
 
4652
  session->mem_root= mem_root_save;
 
4653
  table->free_tmp_table(session);                    /* purecov: inspected */
4224
4654
  if (temp_pool_slot != MY_BIT_NONE)
4225
4655
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4226
4656
  return(NULL);                         /* purecov: inspected */
4237
4667
    The sole purpose of this Table object is to use the power of Field
4238
4668
    class to read/write data to/from table->record[0]. Then one can store
4239
4669
    the record in any container (RB tree, hash, etc).
4240
 
    The table is created in THD mem_root, so are the table's fields.
 
4670
    The table is created in Session mem_root, so are the table's fields.
4241
4671
    Consequently, if you don't BLOB fields, you don't need to free it.
4242
4672
 
4243
 
  @param thd         connection handle
 
4673
  @param session         connection handle
4244
4674
  @param field_list  list of column definitions
4245
4675
 
4246
4676
  @return
4247
4677
    0 if out of memory, Table object in case of success
4248
4678
*/
4249
4679
 
4250
 
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
 
4680
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4251
4681
{
4252
 
  uint field_count= field_list.elements;
4253
 
  uint blob_count= 0;
 
4682
  uint32_t field_count= field_list.elements;
 
4683
  uint32_t blob_count= 0;
4254
4684
  Field **field;
4255
4685
  Create_field *cdef;                           /* column definition */
4256
 
  uint record_length= 0;
4257
 
  uint null_count= 0;                 /* number of columns which may be null */
4258
 
  uint null_pack_length;              /* NULL representation array length */
4259
 
  uint *blob_field;
4260
 
  uchar *bitmaps;
 
4686
  uint32_t record_length= 0;
 
4687
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
4688
  uint32_t null_pack_length;              /* NULL representation array length */
 
4689
  uint32_t *blob_field;
 
4690
  unsigned char *bitmaps;
4261
4691
  Table *table;
4262
4692
  TABLE_SHARE *share;
4263
4693
 
4264
 
  if (!multi_alloc_root(thd->mem_root,
 
4694
  if (!multi_alloc_root(session->mem_root,
4265
4695
                        &table, sizeof(*table),
4266
4696
                        &share, sizeof(*share),
4267
4697
                        &field, (field_count + 1) * sizeof(Field*),
4268
4698
                        &blob_field, (field_count+1) *sizeof(uint),
4269
4699
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4270
 
                        NullS))
 
4700
                        NULL))
4271
4701
    return 0;
4272
4702
 
4273
4703
  memset(table, 0, sizeof(*table));
4284
4714
  while ((cdef= it++))
4285
4715
  {
4286
4716
    *field= make_field(share, 0, cdef->length,
4287
 
                       (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
4717
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4288
4718
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4289
4719
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4290
4720
                       cdef->unireg_check,
4308
4738
  null_pack_length= (null_count + 7)/8;
4309
4739
  share->reclength= record_length + null_pack_length;
4310
4740
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4311
 
  table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
 
4741
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4312
4742
  if (!table->record[0])
4313
4743
    goto error;
4314
4744
 
4315
4745
  if (null_pack_length)
4316
4746
  {
4317
 
    table->null_flags= (uchar*) table->record[0];
 
4747
    table->null_flags= (unsigned char*) table->record[0];
4318
4748
    share->null_fields= null_count;
4319
4749
    share->null_bytes= null_pack_length;
4320
4750
  }
4321
4751
 
4322
 
  table->in_use= thd;           /* field->reset() may access table->in_use */
 
4752
  table->in_use= session;           /* field->reset() may access table->in_use */
4323
4753
  {
4324
4754
    /* Set up field pointers */
4325
 
    uchar *null_pos= table->record[0];
4326
 
    uchar *field_pos= null_pos + share->null_bytes;
4327
 
    uint null_bit= 1;
 
4755
    unsigned char *null_pos= table->record[0];
 
4756
    unsigned char *field_pos= null_pos + share->null_bytes;
 
4757
    uint32_t null_bit= 1;
4328
4758
 
4329
4759
    for (field= table->field; *field; ++field)
4330
4760
    {
4333
4763
        cur_field->move_field(field_pos);
4334
4764
      else
4335
4765
      {
4336
 
        cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
 
4766
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
4337
4767
        null_bit<<= 1;
4338
4768
        if (null_bit == (1 << 8))
4339
4769
        {
4445
4875
      keydef.keysegs=  keyinfo->key_parts;
4446
4876
      keydef.seg= seg;
4447
4877
    }
4448
 
    for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
 
4878
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4449
4879
    {
4450
4880
      Field *field=keyinfo->key_part[i].field;
4451
4881
      seg->flag=     0;
4468
4898
      if (!(field->flags & NOT_NULL_FLAG))
4469
4899
      {
4470
4900
        seg->null_bit= field->null_bit;
4471
 
        seg->null_pos= (uint) (field->null_ptr - (uchar*) record[0]);
 
4901
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
4472
4902
        /*
4473
4903
          We are using a GROUP BY on something that contains NULL
4474
4904
          In this case we have to tell MyISAM that two NULL should
4505
4935
}
4506
4936
 
4507
4937
 
4508
 
void Table::free_tmp_table(THD *thd)
 
4938
void Table::free_tmp_table(Session *session)
4509
4939
{
4510
4940
  MEM_ROOT own_root= mem_root;
4511
4941
  const char *save_proc_info;
4512
4942
 
4513
 
  save_proc_info=thd->get_proc_info();
4514
 
  thd_proc_info(thd, "removing tmp table");
 
4943
  save_proc_info=session->get_proc_info();
 
4944
  session->set_proc_info("removing tmp table");
4515
4945
 
4516
4946
  if (file)
4517
4947
  {
4533
4963
  plugin_unlock(0, s->db_plugin);
4534
4964
 
4535
4965
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4536
 
  thd_proc_info(thd, save_proc_info);
 
4966
  session->set_proc_info(save_proc_info);
4537
4967
 
4538
4968
  return;
4539
4969
}
4543
4973
  to this.
4544
4974
*/
4545
4975
 
4546
 
bool create_myisam_from_heap(THD *thd, Table *table,
 
4976
bool create_myisam_from_heap(Session *session, Table *table,
4547
4977
                             MI_COLUMNDEF *start_recinfo,
4548
4978
                             MI_COLUMNDEF **recinfo, 
4549
4979
                             int error, bool ignore_last_dupp_key_error)
4562
4992
  new_table= *table;
4563
4993
  share= *table->s;
4564
4994
  new_table.s= &share;
4565
 
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
 
4995
  new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4566
4996
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4567
4997
                                        new_table.s->db_type())))
4568
4998
    return(1);                          // End of memory
4569
4999
 
4570
 
  save_proc_info=thd->get_proc_info();
4571
 
  thd_proc_info(thd, "converting HEAP to MyISAM");
 
5000
  save_proc_info=session->get_proc_info();
 
5001
  session->set_proc_info("converting HEAP to MyISAM");
4572
5002
 
4573
5003
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4574
 
                                        recinfo, thd->lex->select_lex.options | 
4575
 
                                        thd->options))
 
5004
                                        recinfo, session->lex->select_lex.options | 
 
5005
                                        session->options))
4576
5006
    goto err2;
4577
5007
  if (new_table.open_tmp_table())
4578
5008
    goto err1;
4635
5065
    const char *new_proc_info=
4636
5066
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4637
5067
      "Copying to tmp table on disk" : save_proc_info);
4638
 
    thd_proc_info(thd, new_proc_info);
 
5068
    session->set_proc_info(new_proc_info);
4639
5069
  }
4640
5070
  return(0);
4641
5071
 
4647
5077
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4648
5078
 err2:
4649
5079
  delete new_table.file;
4650
 
  thd_proc_info(thd, save_proc_info);
 
5080
  session->set_proc_info(save_proc_info);
4651
5081
  table->mem_root= new_table.mem_root;
4652
5082
  return(1);
4653
5083
}
4664
5094
  read_set->bitmap= old;
4665
5095
}
4666
5096
 
4667
 
uint Table::find_shortest_key(const key_map *usable_keys)
 
5097
uint32_t Table::find_shortest_key(const key_map *usable_keys)
4668
5098
{
4669
5099
  uint32_t min_length= UINT32_MAX;
4670
5100
  uint32_t best= MAX_KEY;
4671
5101
  if (!usable_keys->is_clear_all())
4672
5102
  {
4673
 
    for (uint nr=0; nr < s->keys ; nr++)
 
5103
    for (uint32_t nr=0; nr < s->keys ; nr++)
4674
5104
    {
4675
5105
      if (usable_keys->is_set(nr))
4676
5106
      {
4755
5185
}
4756
5186
 
4757
5187
 
 
5188
/*
 
5189
  Calculate data for each virtual field marked for write in the
 
5190
  corresponding column map.
 
5191
 
 
5192
  SYNOPSIS
 
5193
    update_virtual_fields_marked_for_write()
 
5194
    table                  The Table object
 
5195
    ignore_stored          Indication whether physically stored virtual
 
5196
                           fields do not need updating.
 
5197
                           This value is false when during INSERT and UPDATE
 
5198
                           and true in all other cases.
 
5199
 
 
5200
  RETURN
 
5201
    0  - Success
 
5202
    >0 - Error occurred during the generation/calculation of a virtual field value
 
5203
 
 
5204
*/
 
5205
 
 
5206
int update_virtual_fields_marked_for_write(Table *table,
 
5207
                                           bool ignore_stored)
 
5208
{
 
5209
  Field **vfield_ptr, *vfield;
 
5210
  int error= 0;
 
5211
  if ((not table) or (not table->vfield))
 
5212
    return(0);
 
5213
 
 
5214
  /* Iterate over virtual fields in the table */
 
5215
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
5216
  {
 
5217
    vfield= (*vfield_ptr);
 
5218
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
5219
    /*
 
5220
      Only update those fields that are marked in the write_set bitmap
 
5221
      and not _already_ physically stored in the database.
 
5222
    */
 
5223
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
 
5224
        (not (ignore_stored && vfield->is_stored))
 
5225
       )
 
5226
    {
 
5227
      /* Generate the actual value of the virtual fields */
 
5228
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
5229
    }
 
5230
  }
 
5231
  return(0);
 
5232
}
 
5233
 
 
5234
 
4758
5235
/*****************************************************************************
4759
5236
** Instansiate templates
4760
5237
*****************************************************************************/