~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2010-10-09 04:44:38 UTC
  • mto: (1827.1.1 trunk-drizzle)
  • mto: This revision was merged to the branch mainline in revision 1828.
  • Revision ID: brian@tangent.org-20101009044438-inypezfli460whto
First pass on moving show create schema out.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
#include <drizzled/item/null.h>
55
55
#include <drizzled/temporal.h>
56
56
 
57
 
#include "drizzled/table/instance.h"
 
57
#include "drizzled/table_share_instance.h"
58
58
 
59
59
#include "drizzled/table_proto.h"
60
60
 
81
81
 
82
82
  if (db_stat)
83
83
    error= cursor->close();
84
 
  _alias.clear();
 
84
  free((char*) alias);
 
85
  alias= NULL;
85
86
  if (field)
86
87
  {
87
88
    for (Field **ptr=field ; *ptr ; ptr++)
95
96
 
96
97
  if (free_share)
97
98
  {
98
 
    release();
 
99
    if (s->getType() == message::Table::STANDARD)
 
100
    {
 
101
      TableShare::release(s);
 
102
    }
 
103
    else
 
104
    {
 
105
      delete s;
 
106
    }
 
107
 
 
108
    s= NULL;
99
109
  }
 
110
  mem_root.free_root(MYF(0));
100
111
 
101
112
  return error;
102
113
}
103
114
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
115
 
110
116
void Table::resetTable(Session *session,
111
117
                       TableShare *share,
112
118
                       uint32_t db_stat_arg)
113
119
{
114
 
  setShare(share);
 
120
  s= share;
115
121
  field= NULL;
116
122
 
117
123
  cursor= NULL;
136
142
 
137
143
  pos_in_table_list= NULL;
138
144
  group= NULL;
139
 
  _alias.clear();
 
145
  alias= NULL;
140
146
  null_flags= NULL;
141
147
 
142
148
  lock_position= 0;
247
253
  return (nr);
248
254
} /* set_zone */
249
255
 
 
256
        /* Adjust number to next larger disk buffer */
 
257
 
 
258
ulong next_io_size(register ulong pos)
 
259
{
 
260
  register ulong offset;
 
261
  if ((offset= pos & (IO_SIZE-1)))
 
262
    return pos-offset+IO_SIZE;
 
263
  return pos;
 
264
} /* next_io_size */
 
265
 
250
266
 
251
267
/*
252
268
  Store an SQL quoted string.
310
326
}
311
327
 
312
328
 
 
329
/*
 
330
  Set up column usage bitmaps for a temporary table
 
331
 
 
332
  IMPLEMENTATION
 
333
    For temporary tables, we need one bitmap with all columns set and
 
334
    a tmp_set bitmap to be used by things like filesort.
 
335
*/
 
336
 
 
337
void Table::setup_tmp_table_column_bitmaps()
 
338
{
 
339
  uint32_t field_count= s->sizeFields();
 
340
 
 
341
  this->def_read_set.resize(field_count);
 
342
  this->def_write_set.resize(field_count);
 
343
  this->tmp_set.resize(field_count);
 
344
  this->getMutableShare()->all_set.resize(field_count);
 
345
  this->getMutableShare()->all_set.set();
 
346
  this->def_write_set.set();
 
347
  this->def_read_set.set();
 
348
  default_column_bitmaps();
 
349
}
 
350
 
 
351
 
313
352
int rename_file_ext(const char * from,const char * to,const char * ext)
314
353
{
315
354
  string from_s, to_s;
335
374
 
336
375
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
337
376
{
338
 
  if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
 
377
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
339
378
  {
340
379
    return false;
341
380
  }
432
471
{
433
472
 
434
473
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
435
 
      getShare()->hasPrimaryKey())
 
474
      s->hasPrimaryKey())
436
475
  {
437
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
476
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
438
477
  }
439
478
  return;
440
479
}
521
560
    We must set bit in read set as update_auto_increment() is using the
522
561
    store() to check overflow of auto_increment values
523
562
  */
524
 
  setReadSet(found_next_number_field->position());
525
 
  setWriteSet(found_next_number_field->position());
526
 
  if (getShare()->next_number_keypart)
527
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
563
  setReadSet(found_next_number_field->field_index);
 
564
  setWriteSet(found_next_number_field->field_index);
 
565
  if (s->next_number_keypart)
 
566
    mark_columns_used_by_index_no_reset(s->next_number_index);
528
567
}
529
568
 
530
569
 
555
594
    be able to do an delete
556
595
 
557
596
  */
558
 
  if (not getShare()->hasPrimaryKey())
 
597
  if (not s->hasPrimaryKey())
559
598
  {
560
599
    /* fallback to use all columns in the table to identify row */
561
600
    use_all_columns();
562
601
    return;
563
602
  }
564
603
  else
565
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
604
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
566
605
 
567
606
  /* If we the engine wants all predicates we mark all keys */
568
607
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
571
610
    for (reg_field= field ; *reg_field ; reg_field++)
572
611
    {
573
612
      if ((*reg_field)->flags & PART_KEY_FLAG)
574
 
        setReadSet((*reg_field)->position());
 
613
        setReadSet((*reg_field)->field_index);
575
614
    }
576
615
  }
577
616
}
603
642
    the primary key, the hidden primary key or all columns to be
604
643
    able to do an update
605
644
  */
606
 
  if (not getShare()->hasPrimaryKey())
 
645
  if (not s->hasPrimaryKey())
607
646
  {
608
647
    /* fallback to use all columns in the table to identify row */
609
648
    use_all_columns();
610
649
    return;
611
650
  }
612
651
  else
613
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
652
    mark_columns_used_by_index_no_reset(s->getPrimaryKey());
614
653
 
615
654
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
616
655
  {
620
659
    {
621
660
      /* Merge keys is all keys that had a column refered to in the query */
622
661
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
623
 
        setReadSet((*reg_field)->position());
 
662
        setReadSet((*reg_field)->field_index);
624
663
    }
625
664
  }
626
665
 
658
697
  return length;
659
698
}
660
699
 
661
 
void Table::setVariableWidth(void)
662
 
{
663
 
  assert(in_use);
664
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
665
 
  {
666
 
    getMutableShare()->setVariableWidth();
667
 
    return;
668
 
  }
669
 
 
670
 
  assert(0); // Programming error, you can't set this on a plain old Table.
671
 
}
672
 
 
673
700
/****************************************************************************
674
701
 Functions for creating temporary tables.
675
702
****************************************************************************/
707
734
  */
708
735
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
709
736
      (org_field->flags & BLOB_FLAG))
710
 
  {
711
 
    table->setVariableWidth();
712
737
    new_field= new Field_varstring(convert_blob_length,
713
738
                                   org_field->maybe_null(),
714
 
                                   org_field->field_name,
 
739
                                   org_field->field_name, table->getMutableShare(),
715
740
                                   org_field->charset());
716
 
  }
717
741
  else
718
 
  {
719
742
    new_field= org_field->new_field(session->mem_root, table,
720
743
                                    table == org_field->getTable());
721
 
  }
722
744
  if (new_field)
723
745
  {
724
746
    new_field->init(table);
771
793
 
772
794
Table *
773
795
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
774
 
                 Order *group, bool distinct, bool save_sum_fields,
 
796
                 order_st *group, bool distinct, bool save_sum_fields,
775
797
                 uint64_t select_options, ha_rows rows_limit,
776
798
                 const char *table_alias)
777
799
{
778
800
  memory::Root *mem_root_save;
 
801
  Table *table;
779
802
  uint  i,field_count,null_count,null_pack_length;
780
803
  uint32_t  copy_func_count= param->func_count;
781
804
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
805
828
    {
806
829
      group= 0;                                 // Can't use group key
807
830
    }
808
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
831
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
809
832
    {
810
833
      /*
811
834
        marker == 4 means two things:
838
861
    copy_func_count+= param->sum_func_count;
839
862
  }
840
863
 
841
 
  table::Instance *table;
842
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
864
  TableShareInstance *share= session->getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
843
865
 
844
 
  if (not table->getMemRoot()->multi_alloc_root(0,
 
866
  if (not share->getMemRoot()->multi_alloc_root(0,
845
867
                                                &default_field, sizeof(Field*) * (field_count),
846
868
                                                &from_field, sizeof(Field*)*field_count,
847
869
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
862
884
  param->items_to_copy= copy_func;
863
885
  /* make table according to fields */
864
886
 
 
887
  table= share->getTable();
 
888
 
865
889
  memset(default_field, 0, sizeof(Field*) * (field_count));
866
890
  memset(from_field, 0, sizeof(Field*)*field_count);
867
891
 
868
892
  mem_root_save= session->mem_root;
869
893
  session->mem_root= table->getMemRoot();
870
894
 
871
 
  table->getMutableShare()->setFields(field_count+1);
872
 
  table->setFields(table->getMutableShare()->getFields(true));
873
 
  reg_field= table->getMutableShare()->getFields(true);
874
 
  table->setAlias(table_alias);
 
895
  share->setFields(field_count+1);
 
896
  table->setFields(share->getFields(true));
 
897
  reg_field= share->getFields(true);
 
898
  table->alias= table_alias;
875
899
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
876
900
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
877
901
  table->map=1;
882
906
  table->covering_keys.reset();
883
907
  table->keys_in_use_for_query.reset();
884
908
 
885
 
  table->getMutableShare()->blob_field.resize(field_count+1);
886
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
887
 
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
888
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
889
 
  table->getMutableShare()->table_charset= param->table_charset;
890
 
  table->getMutableShare()->keys_for_keyread.reset();
891
 
  table->getMutableShare()->keys_in_use.reset();
 
909
  table->setShare(share);
 
910
  share->blob_field.resize(field_count+1);
 
911
  uint32_t *blob_field= &share->blob_field[0];
 
912
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
913
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
914
  share->table_charset= param->table_charset;
 
915
  share->keys_for_keyread.reset();
 
916
  share->keys_in_use.reset();
892
917
 
893
918
  /* Calculate which type of fields we will store in the temporary table */
894
919
 
965
990
            */
966
991
            (*argp)->maybe_null=1;
967
992
          }
968
 
          new_field->setPosition(fieldnr++);
 
993
          new_field->field_index= fieldnr++;
969
994
        }
970
995
      }
971
996
    }
1012
1037
        group_null_items++;
1013
1038
        new_field->flags|= GROUP_FLAG;
1014
1039
      }
1015
 
      new_field->setPosition(fieldnr++);
 
1040
      new_field->field_index= fieldnr++;
1016
1041
      *(reg_field++)= new_field;
1017
1042
    }
1018
1043
    if (!--hidden_field_count)
1035
1060
  field_count= fieldnr;
1036
1061
  *reg_field= 0;
1037
1062
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->fields= field_count;
 
1063
  share->fields= field_count;
1039
1064
 
1040
1065
  /* If result table is small; use a heap */
1041
1066
  /* future: storage engine selection can be made dynamic? */
1044
1069
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1045
1070
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1046
1071
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1072
    share->storage_engine= myisam_engine;
 
1073
    table->cursor= share->db_type()->getCursor(*share);
1049
1074
    if (group &&
1050
1075
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
1076
         param->group_length > table->cursor->getEngine()->max_key_length()))
1055
1080
  }
1056
1081
  else
1057
1082
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1083
    share->storage_engine= heap_engine;
 
1084
    table->cursor= share->db_type()->getCursor(*share);
1060
1085
  }
1061
1086
  if (! table->cursor)
1062
1087
    goto err;
1065
1090
  if (! using_unique_constraint)
1066
1091
    reclength+= group_null_items;       // null flag is stored separately
1067
1092
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
1093
  share->blob_fields= blob_count;
1069
1094
  if (blob_count == 0)
1070
1095
  {
1071
1096
    /* We need to ensure that first byte is not 0 for the delete link */
1084
1109
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
1085
1110
    use_packed_rows= 1;
1086
1111
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
1112
  share->setRecordLength(reclength);
1088
1113
  {
1089
1114
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1090
 
    table->getMutableShare()->rec_buff_length= alloc_length;
 
1115
    share->rec_buff_length= alloc_length;
1091
1116
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1092
1117
    {
1093
1118
      goto err;
1094
1119
    }
1095
1120
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
1121
    share->resizeDefaultValues(alloc_length);
1097
1122
  }
1098
1123
  copy_func[0]= 0;                              // End marker
1099
1124
  param->func_count= copy_func - param->items_to_copy;
1112
1137
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
1138
 
1114
1139
    table->null_flags= (unsigned char*) table->getInsertRecord();
1115
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1116
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
1140
    share->null_fields= null_count+ hidden_null_count;
 
1141
    share->null_bytes= null_pack_length;
1117
1142
  }
1118
1143
  null_count= (blob_count == 0) ? 1 : 0;
1119
1144
  hidden_field_count=param->hidden_field_count;
1204
1229
  }
1205
1230
  else
1206
1231
  {
1207
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1232
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
1208
1233
                           min(session->variables.tmp_table_size,
1209
1234
                               session->variables.max_heap_table_size) :
1210
1235
                           session->variables.tmp_table_size) /
1211
 
                          table->getMutableShare()->getRecordLength());
 
1236
                          share->getRecordLength());
1212
1237
  }
1213
1238
 
1214
1239
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
1218
1243
  */
1219
1244
  set_if_smaller(max_rows, rows_limit);
1220
1245
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
 
1246
  share->setMaxRows(max_rows);
1222
1247
 
1223
1248
  param->end_write_records= rows_limit;
1224
1249
 
1228
1253
  {
1229
1254
    table->group=group;                         /* Table is grouped by key */
1230
1255
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
1256
    share->keys=1;
 
1257
    share->uniques= test(using_unique_constraint);
1233
1258
    table->key_info=keyinfo;
1234
1259
    keyinfo->key_part=key_part_info;
1235
1260
    keyinfo->flags=HA_NOSAME;
1238
1263
    keyinfo->rec_per_key= 0;
1239
1264
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
1265
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
1266
    order_st *cur_group= group;
1242
1267
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
1268
    {
1244
1269
      Field *field=(*cur_group->item)->get_tmp_table_field();
1300
1325
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
1326
        used for lookups.
1302
1327
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
1328
      share->uniques= 1;
1304
1329
    }
1305
1330
    null_pack_length-=hidden_null_pack_length;
1306
1331
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
1332
                         (share->uniques ? test(null_pack_length) : 0));
1308
1333
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
 
1334
    share->keys= 1;
1310
1335
    if (!(key_part_info= (KeyPartInfo*)
1311
1336
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
1312
1337
      goto err;
1324
1349
      blobs can distinguish NULL from 0. This extra field is not needed
1325
1350
      when we do not use UNIQUE indexes for blobs.
1326
1351
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
1352
    if (null_pack_length && share->uniques)
1328
1353
    {
1329
1354
      key_part_info->null_bit= 0;
1330
1355
      key_part_info->offset=hidden_null_pack_length;
1331
1356
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
1357
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
1334
1358
                                                (uint32_t) key_part_info->length,
1335
1359
                                                0,
1336
1360
                                                (unsigned char*) 0,
1337
1361
                                                (uint32_t) 0,
1338
1362
                                                NULL,
 
1363
                                                table->getMutableShare(),
1339
1364
                                                &my_charset_bin);
1340
1365
      if (!key_part_info->field)
1341
1366
        goto err;
1379
1404
 
1380
1405
  if (session->is_fatal_error)                          // If end of memory
1381
1406
    goto err;
1382
 
  table->getMutableShare()->db_record_offset= 1;
1383
 
  if (table->getShare()->db_type() == myisam_engine)
 
1407
  share->db_record_offset= 1;
 
1408
  if (share->db_type() == myisam_engine)
1384
1409
  {
1385
1410
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
1411
                                       &param->recinfo, select_options))
1403
1428
 
1404
1429
/****************************************************************************/
1405
1430
 
 
1431
/**
 
1432
  Create a reduced Table object with properly set up Field list from a
 
1433
  list of field definitions.
 
1434
 
 
1435
    The created table doesn't have a table Cursor associated with
 
1436
    it, has no keys, no group/distinct, no copy_funcs array.
 
1437
    The sole purpose of this Table object is to use the power of Field
 
1438
    class to read/write data to/from table->getInsertRecord(). Then one can store
 
1439
    the record in any container (RB tree, hash, etc).
 
1440
    The table is created in Session mem_root, so are the table's fields.
 
1441
    Consequently, if you don't BLOB fields, you don't need to free it.
 
1442
 
 
1443
  @param session         connection handle
 
1444
  @param field_list  list of column definitions
 
1445
 
 
1446
  @return
 
1447
    0 if out of memory, Table object in case of success
 
1448
*/
 
1449
 
 
1450
Table *Session::create_virtual_tmp_table(List<CreateField> &field_list)
 
1451
{
 
1452
  uint32_t field_count= field_list.elements;
 
1453
  uint32_t blob_count= 0;
 
1454
  Field **field;
 
1455
  CreateField *cdef;                           /* column definition */
 
1456
  uint32_t record_length= 0;
 
1457
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
1458
  uint32_t null_pack_length;              /* NULL representation array length */
 
1459
  Table *table;
 
1460
 
 
1461
  TableShareInstance *share= getTemporaryShare(message::Table::INTERNAL); // This will not go into the tableshare cache, so no key is used.
 
1462
  table= share->getTable();
 
1463
  share->setFields(field_count + 1);
 
1464
  table->setFields(share->getFields(true));
 
1465
  field= share->getFields(true);
 
1466
  share->blob_field.resize(field_count+1);
 
1467
  share->fields= field_count;
 
1468
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
1469
  table->setup_tmp_table_column_bitmaps();
 
1470
 
 
1471
  table->in_use= this;           /* field->reset() may access table->in_use */
 
1472
 
 
1473
  /* Create all fields and calculate the total length of record */
 
1474
  List_iterator_fast<CreateField> it(field_list);
 
1475
  while ((cdef= it++))
 
1476
  {
 
1477
    *field= share->make_field(NULL,
 
1478
                              cdef->length,
 
1479
                              (cdef->flags & NOT_NULL_FLAG) ? false : true,
 
1480
                              (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
 
1481
                              (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
 
1482
                              cdef->decimals,
 
1483
                              cdef->sql_type,
 
1484
                              cdef->charset,
 
1485
                              cdef->unireg_check,
 
1486
                              cdef->interval,
 
1487
                              cdef->field_name);
 
1488
    if (!*field)
 
1489
      goto error;
 
1490
    (*field)->init(table);
 
1491
    record_length+= (*field)->pack_length();
 
1492
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
1493
      null_count++;
 
1494
 
 
1495
    if ((*field)->flags & BLOB_FLAG)
 
1496
      share->blob_field[blob_count++]= (uint32_t) (field - table->getFields());
 
1497
 
 
1498
    field++;
 
1499
  }
 
1500
  *field= NULL;                             /* mark the end of the list */
 
1501
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
1502
  share->blob_fields= blob_count;
 
1503
 
 
1504
  null_pack_length= (null_count + 7)/8;
 
1505
  share->setRecordLength(record_length + null_pack_length);
 
1506
  share->rec_buff_length= ALIGN_SIZE(share->getRecordLength() + 1);
 
1507
  table->record[0]= (unsigned char*)alloc(share->rec_buff_length);
 
1508
  if (not table->getInsertRecord())
 
1509
    goto error;
 
1510
 
 
1511
  if (null_pack_length)
 
1512
  {
 
1513
    table->null_flags= (unsigned char*) table->getInsertRecord();
 
1514
    share->null_fields= null_count;
 
1515
    share->null_bytes= null_pack_length;
 
1516
  }
 
1517
  {
 
1518
    /* Set up field pointers */
 
1519
    unsigned char *null_pos= table->getInsertRecord();
 
1520
    unsigned char *field_pos= null_pos + share->null_bytes;
 
1521
    uint32_t null_bit= 1;
 
1522
 
 
1523
    for (field= table->getFields(); *field; ++field)
 
1524
    {
 
1525
      Field *cur_field= *field;
 
1526
      if ((cur_field->flags & NOT_NULL_FLAG))
 
1527
        cur_field->move_field(field_pos);
 
1528
      else
 
1529
      {
 
1530
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
1531
        null_bit<<= 1;
 
1532
        if (null_bit == (1 << 8))
 
1533
        {
 
1534
          ++null_pos;
 
1535
          null_bit= 1;
 
1536
        }
 
1537
      }
 
1538
      cur_field->reset();
 
1539
 
 
1540
      field_pos+= cur_field->pack_length();
 
1541
    }
 
1542
  }
 
1543
 
 
1544
  return table;
 
1545
 
 
1546
error:
 
1547
  for (field= table->getFields(); *field; ++field)
 
1548
  {
 
1549
    delete *field;                         /* just invokes field destructor */
 
1550
  }
 
1551
  return 0;
 
1552
}
 
1553
 
 
1554
bool Table::open_tmp_table()
 
1555
{
 
1556
  int error;
 
1557
  
 
1558
  TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getPath());
 
1559
  if ((error=cursor->ha_open(identifier,
 
1560
                             this,
 
1561
                             O_RDWR,
 
1562
                             HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
1563
  {
 
1564
    print_error(error, MYF(0));
 
1565
    db_stat= 0;
 
1566
    return true;
 
1567
  }
 
1568
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
 
1569
  return false;
 
1570
}
 
1571
 
 
1572
 
 
1573
/*
 
1574
  Create MyISAM temporary table
 
1575
 
 
1576
  SYNOPSIS
 
1577
    create_myisam_tmp_table()
 
1578
      keyinfo         Description of the index (there is always one index)
 
1579
      start_recinfo   MyISAM's column descriptions
 
1580
      recinfo INOUT   End of MyISAM's column descriptions
 
1581
      options         Option bits
 
1582
 
 
1583
  DESCRIPTION
 
1584
    Create a MyISAM temporary table according to passed description. The is
 
1585
    assumed to have one unique index or constraint.
 
1586
 
 
1587
    The passed array or MI_COLUMNDEF structures must have this form:
 
1588
 
 
1589
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
1590
         when there are many nullable columns)
 
1591
      2. Table columns
 
1592
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
1593
 
 
1594
    This function may use the free element to create hash column for unique
 
1595
    constraint.
 
1596
 
 
1597
   RETURN
 
1598
     false - OK
 
1599
     true  - Error
 
1600
*/
 
1601
 
 
1602
bool Table::create_myisam_tmp_table(KeyInfo *keyinfo,
 
1603
                                    MI_COLUMNDEF *start_recinfo,
 
1604
                                    MI_COLUMNDEF **recinfo,
 
1605
                                    uint64_t options)
 
1606
{
 
1607
  int error;
 
1608
  MI_KEYDEF keydef;
 
1609
  MI_UNIQUEDEF uniquedef;
 
1610
  TableShare *share= s;
 
1611
 
 
1612
  if (share->sizeKeys())
 
1613
  {                                             // Get keys for ni_create
 
1614
    bool using_unique_constraint= false;
 
1615
    HA_KEYSEG *seg= (HA_KEYSEG*) this->mem_root.alloc_root(sizeof(*seg) * keyinfo->key_parts);
 
1616
    if (not seg)
 
1617
      return true;
 
1618
 
 
1619
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
1620
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
 
1621
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
1622
        share->uniques)
 
1623
    {
 
1624
      /* Can't create a key; Make a unique constraint instead of a key */
 
1625
      share->keys=    0;
 
1626
      share->uniques= 1;
 
1627
      using_unique_constraint= true;
 
1628
      memset(&uniquedef, 0, sizeof(uniquedef));
 
1629
      uniquedef.keysegs=keyinfo->key_parts;
 
1630
      uniquedef.seg=seg;
 
1631
      uniquedef.null_are_equal=1;
 
1632
 
 
1633
      /* Create extra column for hash value */
 
1634
      memset(*recinfo, 0, sizeof(**recinfo));
 
1635
      (*recinfo)->type= FIELD_CHECK;
 
1636
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
1637
      (*recinfo)++;
 
1638
      share->setRecordLength(share->getRecordLength() + MI_UNIQUE_HASH_LENGTH);
 
1639
    }
 
1640
    else
 
1641
    {
 
1642
      /* Create an unique key */
 
1643
      memset(&keydef, 0, sizeof(keydef));
 
1644
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
1645
      keydef.keysegs=  keyinfo->key_parts;
 
1646
      keydef.seg= seg;
 
1647
    }
 
1648
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
1649
    {
 
1650
      Field *key_field=keyinfo->key_part[i].field;
 
1651
      seg->flag=     0;
 
1652
      seg->language= key_field->charset()->number;
 
1653
      seg->length=   keyinfo->key_part[i].length;
 
1654
      seg->start=    keyinfo->key_part[i].offset;
 
1655
      if (key_field->flags & BLOB_FLAG)
 
1656
      {
 
1657
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
1658
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
1659
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
1660
                                  - share->blob_ptr_size);
 
1661
        seg->flag= HA_BLOB_PART;
 
1662
        seg->length= 0;                 // Whole blob in unique constraint
 
1663
      }
 
1664
      else
 
1665
      {
 
1666
        seg->type= keyinfo->key_part[i].type;
 
1667
      }
 
1668
      if (!(key_field->flags & NOT_NULL_FLAG))
 
1669
      {
 
1670
        seg->null_bit= key_field->null_bit;
 
1671
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) getInsertRecord());
 
1672
        /*
 
1673
          We are using a GROUP BY on something that contains NULL
 
1674
          In this case we have to tell MyISAM that two NULL should
 
1675
          on INSERT be regarded at the same value
 
1676
        */
 
1677
        if (! using_unique_constraint)
 
1678
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
1679
      }
 
1680
    }
 
1681
  }
 
1682
  MI_CREATE_INFO create_info;
 
1683
 
 
1684
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
1685
      OPTION_BIG_TABLES)
 
1686
    create_info.data_file_length= ~(uint64_t) 0;
 
1687
 
 
1688
  if ((error= mi_create(share->getTableName(), share->sizeKeys(), &keydef,
 
1689
                        (uint32_t) (*recinfo-start_recinfo),
 
1690
                        start_recinfo,
 
1691
                        share->uniques, &uniquedef,
 
1692
                        &create_info,
 
1693
                        HA_CREATE_TMP_TABLE)))
 
1694
  {
 
1695
    print_error(error, MYF(0));
 
1696
    db_stat= 0;
 
1697
 
 
1698
    return true;
 
1699
  }
 
1700
  in_use->status_var.created_tmp_disk_tables++;
 
1701
  share->db_record_offset= 1;
 
1702
  return false;
 
1703
}
 
1704
 
 
1705
 
 
1706
void Table::free_tmp_table(Session *session)
 
1707
{
 
1708
  memory::Root own_root= mem_root;
 
1709
  const char *save_proc_info;
 
1710
 
 
1711
  save_proc_info= session->get_proc_info();
 
1712
  session->set_proc_info("removing tmp table");
 
1713
 
 
1714
  // Release latches since this can take a long time
 
1715
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
1716
 
 
1717
  if (cursor)
 
1718
  {
 
1719
    if (db_stat)
 
1720
    {
 
1721
      cursor->closeMarkForDelete(s->getTableName());
 
1722
    }
 
1723
 
 
1724
    TableIdentifier identifier(s->getSchemaName(), s->getTableName(), s->getTableName());
 
1725
    s->db_type()->doDropTable(*session, identifier);
 
1726
 
 
1727
    delete cursor;
 
1728
  }
 
1729
 
 
1730
  /* free blobs */
 
1731
  for (Field **ptr= field ; *ptr ; ptr++)
 
1732
  {
 
1733
    (*ptr)->free();
 
1734
  }
 
1735
  free_io_cache();
 
1736
 
 
1737
  own_root.free_root(MYF(0)); /* the table is allocated in its own root */
 
1738
  session->set_proc_info(save_proc_info);
 
1739
}
 
1740
 
1406
1741
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
1742
                               boost::dynamic_bitset<>& write_set_arg)
1408
1743
{
1414
1749
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1415
1750
{
1416
1751
  const boost::dynamic_bitset<> old= in_map;
1417
 
  in_map= getShare()->all_set;
 
1752
  in_map= s->all_set;
1418
1753
  return old;
1419
1754
}
1420
1755
 
1439
1774
  uint32_t best= MAX_KEY;
1440
1775
  if (usable_keys->any())
1441
1776
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
1777
    for (uint32_t nr= 0; nr < s->sizeKeys() ; nr++)
1443
1778
    {
1444
1779
      if (usable_keys->test(nr))
1445
1780
      {
1466
1801
{
1467
1802
  for (; *ptr ; ptr++)
1468
1803
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
1804
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
1805
      return true;
1471
1806
  }
1472
1807
  return false;
1473
1808
}
1474
1809
 
1475
 
/**
1476
 
   True if the table's input and output record buffers are comparable using
1477
 
   compare_records(TABLE*).
1478
 
 */
1479
 
bool Table::records_are_comparable()
1480
 
{
1481
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1482
 
          write_set->is_subset_of(*read_set));
1483
 
}
1484
 
 
1485
 
/**
1486
 
   Compares the input and outbut record buffers of the table to see if a row
1487
 
   has changed. The algorithm iterates over updated columns and if they are
1488
 
   nullable compares NULL bits in the buffer before comparing actual
1489
 
   data. Special care must be taken to compare only the relevant NULL bits and
1490
 
   mask out all others as they may be undefined. The storage engine will not
1491
 
   and should not touch them.
1492
 
 
1493
 
   @param table The table to evaluate.
1494
 
 
1495
 
   @return true if row has changed.
1496
 
   @return false otherwise.
1497
 
*/
1498
 
bool Table::compare_records()
1499
 
{
1500
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1501
 
  {
1502
 
    /*
1503
 
      Storage engine may not have read all columns of the record.  Fields
1504
 
      (including NULL bits) not in the write_set may not have been read and
1505
 
      can therefore not be compared.
1506
 
    */
1507
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1508
 
    {
1509
 
      Field *f= *ptr;
1510
 
      if (write_set->test(f->position()))
1511
 
      {
1512
 
        if (f->real_maybe_null())
1513
 
        {
1514
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1515
 
 
1516
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1517
 
              ((record[1][null_byte_index]) & f->null_bit))
1518
 
            return true;
1519
 
        }
1520
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1521
 
          return true;
1522
 
      }
1523
 
    }
1524
 
    return false;
1525
 
  }
1526
 
 
1527
 
  /*
1528
 
    The storage engine has read all columns, so it's safe to compare all bits
1529
 
    including those not in the write_set. This is cheaper than the
1530
 
    field-by-field comparison done above.
1531
 
  */
1532
 
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1533
 
    // Fixed-size record: do bitwise comparison of the records
1534
 
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1535
 
 
 
1810
/* Return false if row hasn't changed */
 
1811
 
 
1812
bool Table::compare_record()
 
1813
{
 
1814
  if (s->blob_fields + s->varchar_fields == 0)
 
1815
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) s->getRecordLength());
 
1816
  
1536
1817
  /* Compare null bits */
1537
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1818
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
1538
1819
    return true; /* Diff in NULL value */
1539
1820
 
1540
1821
  /* Compare updated fields */
1541
1822
  for (Field **ptr= field ; *ptr ; ptr++)
1542
1823
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
1824
    if (isWriteSet((*ptr)->field_index) &&
 
1825
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
1826
      return true;
1546
1827
  }
1547
1828
  return false;
1553
1834
 */
1554
1835
void Table::storeRecord()
1555
1836
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1837
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) s->getRecordLength());
1557
1838
}
1558
1839
 
1559
1840
/*
1562
1843
 */
1563
1844
void Table::storeRecordAsInsert()
1564
1845
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1846
  assert(insert_values.size() >= s->getRecordLength());
 
1847
  memcpy(&insert_values[0], getInsertRecord(), (size_t) s->getRecordLength());
1567
1848
}
1568
1849
 
1569
1850
/*
1572
1853
 */
1573
1854
void Table::storeRecordAsDefault()
1574
1855
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1856
  memcpy(s->getDefaultValues(), getInsertRecord(), (size_t) s->getRecordLength());
1576
1857
}
1577
1858
 
1578
1859
/*
1581
1862
 */
1582
1863
void Table::restoreRecord()
1583
1864
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1865
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) s->getRecordLength());
1585
1866
}
1586
1867
 
1587
1868
/*
1590
1871
 */
1591
1872
void Table::restoreRecordAsDefault()
1592
1873
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1874
  memcpy(getInsertRecord(), s->getDefaultValues(), (size_t) s->getRecordLength());
1594
1875
}
1595
1876
 
1596
1877
/*
1600
1881
void Table::emptyRecord()
1601
1882
{
1602
1883
  restoreRecordAsDefault();
1603
 
  memset(null_flags, 255, getShare()->null_bytes);
 
1884
  memset(null_flags, 255, s->null_bytes);
1604
1885
}
1605
1886
 
1606
1887
Table::Table() : 
 
1888
  s(NULL),
1607
1889
  field(NULL),
1608
1890
  cursor(NULL),
1609
1891
  next(NULL),
1622
1904
  timestamp_field(NULL),
1623
1905
  pos_in_table_list(NULL),
1624
1906
  group(NULL),
 
1907
  alias(NULL),
1625
1908
  null_flags(NULL),
1626
1909
  lock_position(0),
1627
1910
  lock_data_start(0),
1647
1930
  query_id(0),
1648
1931
  quick_condition_rows(0),
1649
1932
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1650
 
  map(0)
 
1933
  map(0),
 
1934
  is_placeholder_created(0)
1651
1935
{
1652
1936
  record[0]= (unsigned char *) 0;
1653
1937
  record[1]= (unsigned char *) 0;
1688
1972
  */
1689
1973
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1690
1974
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
1691
 
                  error, getShare()->getPath());
 
1975
                  error, s->getPath());
1692
1976
  print_error(error, MYF(0));
1693
1977
 
1694
1978
  return 1;
1711
1995
  tablenr= table_number;
1712
1996
  map= (table_map) 1 << table_number;
1713
1997
  force_index= table_list->force_index;
1714
 
  covering_keys= getShare()->keys_for_keyread;
 
1998
  covering_keys= s->keys_for_keyread;
1715
1999
  merge_keys.reset();
1716
2000
}
1717
2001
 
1731
2015
  return false;
1732
2016
}
1733
2017
 
1734
 
 
1735
 
void Table::filesort_free_buffers(bool full)
1736
 
{
1737
 
  if (sort.record_pointers)
1738
 
  {
1739
 
    free((unsigned char*) sort.record_pointers);
1740
 
    sort.record_pointers=0;
1741
 
  }
1742
 
  if (full)
1743
 
  {
1744
 
    if (sort.sort_keys )
1745
 
    {
1746
 
      if ((unsigned char*) sort.sort_keys)
1747
 
        free((unsigned char*) sort.sort_keys);
1748
 
      sort.sort_keys= 0;
1749
 
    }
1750
 
    if (sort.buffpek)
1751
 
    {
1752
 
      if ((unsigned char*) sort.buffpek)
1753
 
        free((unsigned char*) sort.buffpek);
1754
 
      sort.buffpek= 0;
1755
 
      sort.buffpek_len= 0;
1756
 
    }
1757
 
  }
1758
 
 
1759
 
  if (sort.addon_buf)
1760
 
  {
1761
 
    free((char *) sort.addon_buf);
1762
 
    free((char *) sort.addon_field);
1763
 
    sort.addon_buf=0;
1764
 
    sort.addon_field=0;
1765
 
  }
1766
 
}
1767
 
 
1768
2018
} /* namespace drizzled */