~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2010-10-21 08:55:44 UTC
  • mto: (1866.1.1 merge)
  • mto: This revision was merged to the branch mainline in revision 1867.
  • Revision ID: brian@tangent.org-20101021085544-chpce06zm4tdaqdi
This creates a function for seeing which catalog you are in. It also
refactors some of the functions to be in the utility_function collect.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 (getShare()->getType() == message::Table::STANDARD)
 
100
    {
 
101
      TableShare::release(getMutableShare());
 
102
    }
 
103
    else
 
104
    {
 
105
      delete getShare();
 
106
    }
 
107
 
 
108
    setShare(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,
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.
521
537
    We must set bit in read set as update_auto_increment() is using the
522
538
    store() to check overflow of auto_increment values
523
539
  */
524
 
  setReadSet(found_next_number_field->position());
525
 
  setWriteSet(found_next_number_field->position());
 
540
  setReadSet(found_next_number_field->field_index);
 
541
  setWriteSet(found_next_number_field->field_index);
526
542
  if (getShare()->next_number_keypart)
527
543
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
528
544
}
571
587
    for (reg_field= field ; *reg_field ; reg_field++)
572
588
    {
573
589
      if ((*reg_field)->flags & PART_KEY_FLAG)
574
 
        setReadSet((*reg_field)->position());
 
590
        setReadSet((*reg_field)->field_index);
575
591
    }
576
592
  }
577
593
}
620
636
    {
621
637
      /* Merge keys is all keys that had a column refered to in the query */
622
638
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
623
 
        setReadSet((*reg_field)->position());
 
639
        setReadSet((*reg_field)->field_index);
624
640
    }
625
641
  }
626
642
 
771
787
 
772
788
Table *
773
789
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
774
 
                 Order *group, bool distinct, bool save_sum_fields,
 
790
                 order_st *group, bool distinct, bool save_sum_fields,
775
791
                 uint64_t select_options, ha_rows rows_limit,
776
792
                 const char *table_alias)
777
793
{
805
821
    {
806
822
      group= 0;                                 // Can't use group key
807
823
    }
808
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
824
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
809
825
    {
810
826
      /*
811
827
        marker == 4 means two things:
871
887
  table->getMutableShare()->setFields(field_count+1);
872
888
  table->setFields(table->getMutableShare()->getFields(true));
873
889
  reg_field= table->getMutableShare()->getFields(true);
874
 
  table->setAlias(table_alias);
 
890
  table->alias= table_alias;
875
891
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
876
892
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
877
893
  table->map=1;
965
981
            */
966
982
            (*argp)->maybe_null=1;
967
983
          }
968
 
          new_field->setPosition(fieldnr++);
 
984
          new_field->field_index= fieldnr++;
969
985
        }
970
986
      }
971
987
    }
1012
1028
        group_null_items++;
1013
1029
        new_field->flags|= GROUP_FLAG;
1014
1030
      }
1015
 
      new_field->setPosition(fieldnr++);
 
1031
      new_field->field_index= fieldnr++;
1016
1032
      *(reg_field++)= new_field;
1017
1033
    }
1018
1034
    if (!--hidden_field_count)
1045
1061
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1046
1062
  {
1047
1063
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1064
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare());
1049
1065
    if (group &&
1050
1066
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
1067
         param->group_length > table->cursor->getEngine()->max_key_length()))
1056
1072
  else
1057
1073
  {
1058
1074
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1075
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare());
1060
1076
  }
1061
1077
  if (! table->cursor)
1062
1078
    goto err;
1238
1254
    keyinfo->rec_per_key= 0;
1239
1255
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
1256
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
1257
    order_st *cur_group= group;
1242
1258
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
1259
    {
1244
1260
      Field *field=(*cur_group->item)->get_tmp_table_field();
1403
1419
 
1404
1420
/****************************************************************************/
1405
1421
 
 
1422
/**
 
1423
  Create a reduced Table object with properly set up Field list from a
 
1424
  list of field definitions.
 
1425
 
 
1426
    The created table doesn't have a table Cursor associated with
 
1427
    it, has no keys, no group/distinct, no copy_funcs array.
 
1428
    The sole purpose of this Table object is to use the power of Field
 
1429
    class to read/write data to/from table->getInsertRecord(). Then one can store
 
1430
    the record in any container (RB tree, hash, etc).
 
1431
    The table is created in Session mem_root, so are the table's fields.
 
1432
    Consequently, if you don't BLOB fields, you don't need to free it.
 
1433
 
 
1434
  @param session         connection handle
 
1435
  @param field_list  list of column definitions
 
1436
 
 
1437
  @return
 
1438
    0 if out of memory, Table object in case of success
 
1439
*/
 
1440
 
 
1441
Table *Session::create_virtual_tmp_table(List<CreateField> &field_list)
 
1442
{
 
1443
  uint32_t field_count= field_list.elements;
 
1444
  uint32_t blob_count= 0;
 
1445
  Field **field;
 
1446
  CreateField *cdef;                           /* column definition */
 
1447
  uint32_t record_length= 0;
 
1448
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
1449
  uint32_t null_pack_length;              /* NULL representation array length */
 
1450
 
 
1451
  table::Instance *table= getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
1452
  table->getMutableShare()->setFields(field_count + 1);
 
1453
  table->setFields(table->getMutableShare()->getFields(true));
 
1454
  field= table->getMutableShare()->getFields(true);
 
1455
  table->getMutableShare()->blob_field.resize(field_count+1);
 
1456
  table->getMutableShare()->fields= field_count;
 
1457
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
 
1458
  table->setup_tmp_table_column_bitmaps();
 
1459
 
 
1460
  table->in_use= this;           /* field->reset() may access table->in_use */
 
1461
 
 
1462
  /* Create all fields and calculate the total length of record */
 
1463
  List_iterator_fast<CreateField> it(field_list);
 
1464
  while ((cdef= it++))
 
1465
  {
 
1466
    *field= table->getMutableShare()->make_field(NULL,
 
1467
                                                 cdef->length,
 
1468
                                                 (cdef->flags & NOT_NULL_FLAG) ? false : true,
 
1469
                                                 (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
 
1470
                                                 (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
 
1471
                                                 cdef->decimals,
 
1472
                                                 cdef->sql_type,
 
1473
                                                 cdef->charset,
 
1474
                                                 cdef->unireg_check,
 
1475
                                                 cdef->interval,
 
1476
                                                 cdef->field_name);
 
1477
    if (!*field)
 
1478
      goto error;
 
1479
    (*field)->init(table);
 
1480
    record_length+= (*field)->pack_length();
 
1481
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
1482
      null_count++;
 
1483
 
 
1484
    if ((*field)->flags & BLOB_FLAG)
 
1485
      table->getMutableShare()->blob_field[blob_count++]= (uint32_t) (field - table->getFields());
 
1486
 
 
1487
    field++;
 
1488
  }
 
1489
  *field= NULL;                             /* mark the end of the list */
 
1490
  table->getMutableShare()->blob_field[blob_count]= 0;            /* mark the end of the list */
 
1491
  table->getMutableShare()->blob_fields= blob_count;
 
1492
 
 
1493
  null_pack_length= (null_count + 7)/8;
 
1494
  table->getMutableShare()->setRecordLength(record_length + null_pack_length);
 
1495
  table->getMutableShare()->rec_buff_length= ALIGN_SIZE(table->getMutableShare()->getRecordLength() + 1);
 
1496
  table->record[0]= (unsigned char*)alloc(table->getMutableShare()->rec_buff_length);
 
1497
  if (not table->getInsertRecord())
 
1498
    goto error;
 
1499
 
 
1500
  if (null_pack_length)
 
1501
  {
 
1502
    table->null_flags= (unsigned char*) table->getInsertRecord();
 
1503
    table->getMutableShare()->null_fields= null_count;
 
1504
    table->getMutableShare()->null_bytes= null_pack_length;
 
1505
  }
 
1506
  {
 
1507
    /* Set up field pointers */
 
1508
    unsigned char *null_pos= table->getInsertRecord();
 
1509
    unsigned char *field_pos= null_pos + table->getMutableShare()->null_bytes;
 
1510
    uint32_t null_bit= 1;
 
1511
 
 
1512
    for (field= table->getFields(); *field; ++field)
 
1513
    {
 
1514
      Field *cur_field= *field;
 
1515
      if ((cur_field->flags & NOT_NULL_FLAG))
 
1516
        cur_field->move_field(field_pos);
 
1517
      else
 
1518
      {
 
1519
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
1520
        null_bit<<= 1;
 
1521
        if (null_bit == (1 << 8))
 
1522
        {
 
1523
          ++null_pos;
 
1524
          null_bit= 1;
 
1525
        }
 
1526
      }
 
1527
      cur_field->reset();
 
1528
 
 
1529
      field_pos+= cur_field->pack_length();
 
1530
    }
 
1531
  }
 
1532
 
 
1533
  return table;
 
1534
 
 
1535
error:
 
1536
  for (field= table->getFields(); *field; ++field)
 
1537
  {
 
1538
    delete *field;                         /* just invokes field destructor */
 
1539
  }
 
1540
  return 0;
 
1541
}
 
1542
 
1406
1543
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
1544
                               boost::dynamic_bitset<>& write_set_arg)
1408
1545
{
1472
1609
  return false;
1473
1610
}
1474
1611
 
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
 
  */
 
1612
/* Return false if row hasn't changed */
 
1613
 
 
1614
bool Table::compare_record()
 
1615
{
1532
1616
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1533
 
    // Fixed-size record: do bitwise comparison of the records
1534
1617
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1535
 
 
 
1618
  
1536
1619
  /* Compare null bits */
1537
1620
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
1538
1621
    return true; /* Diff in NULL value */
1540
1623
  /* Compare updated fields */
1541
1624
  for (Field **ptr= field ; *ptr ; ptr++)
1542
1625
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
 
1626
    if (isWriteSet((*ptr)->field_index) &&
1544
1627
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
1545
1628
      return true;
1546
1629
  }
1622
1705
  timestamp_field(NULL),
1623
1706
  pos_in_table_list(NULL),
1624
1707
  group(NULL),
 
1708
  alias(NULL),
1625
1709
  null_flags(NULL),
1626
1710
  lock_position(0),
1627
1711
  lock_data_start(0),
1731
1815
  return false;
1732
1816
}
1733
1817
 
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
1818
} /* namespace drizzled */