42
42
#include <drizzled/field/double.h>
43
43
#include <drizzled/unireg.h>
44
44
#include <drizzled/message/table.pb.h>
45
#include <drizzled/sql_table.h>
46
#include <drizzled/charset.h>
47
#include <drizzled/internal/m_string.h>
48
#include <plugin/myisam/myisam.h>
49
#include <drizzled/plugin/storage_engine.h>
45
#include "drizzled/sql_table.h"
46
#include "drizzled/charset.h"
47
#include "drizzled/internal/m_string.h"
48
#include "plugin/myisam/myisam.h"
51
50
#include <drizzled/item/string.h>
52
51
#include <drizzled/item/int.h>
55
54
#include <drizzled/item/null.h>
56
55
#include <drizzled/temporal.h>
58
#include <drizzled/refresh_version.h>
60
#include <drizzled/table/singular.h>
62
#include <drizzled/table_proto.h>
63
#include <drizzled/typelib.h>
57
#include "drizzled/table/instance.h"
59
#include "drizzled/table_proto.h"
65
61
using namespace std;
66
extern pid_t current_pid;
70
67
extern plugin::StorageEngine *heap_engine;
71
68
extern plugin::StorageEngine *myisam_engine;
73
70
/* Functions defined in this cursor */
72
void open_table_error(TableShare *share, int error, int db_errno,
73
myf errortype, int errarg);
75
75
/*************************************************************************/
77
77
// @note this should all be the destructor
1013
1051
field_count= fieldnr;
1015
1053
*blob_field= 0; // End marker
1016
table->getMutableShare()->setFieldSize(field_count);
1054
table->getMutableShare()->fields= field_count;
1018
1056
/* If result table is small; use a heap */
1019
1057
/* future: storage engine selection can be made dynamic? */
1020
1058
if (blob_count || using_unique_constraint ||
1021
(session->getLex()->select_lex.options & SELECT_BIG_RESULT) ||
1022
(session->getLex()->current_select->olap == ROLLUP_TYPE) ||
1059
(session->lex->select_lex.options & SELECT_BIG_RESULT) ||
1060
(session->lex->current_select->olap == ROLLUP_TYPE) ||
1023
1061
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1025
1063
table->getMutableShare()->storage_engine= myisam_engine;
1026
table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
1064
table->cursor= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare());
1028
1066
(param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1029
1067
param->group_length > table->cursor->getEngine()->max_key_length()))
1382
1420
/****************************************************************************/
1423
Create a reduced Table object with properly set up Field list from a
1424
list of field definitions.
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.
1434
@param session connection handle
1435
@param field_list list of column definitions
1438
0 if out of memory, Table object in case of success
1441
Table *Session::create_virtual_tmp_table(List<CreateField> &field_list)
1443
uint32_t field_count= field_list.elements;
1444
uint32_t blob_count= 0;
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 */
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();
1460
table->in_use= this; /* field->reset() may access table->in_use */
1462
/* Create all fields and calculate the total length of record */
1463
List_iterator_fast<CreateField> it(field_list);
1464
while ((cdef= it++))
1466
*field= table->getMutableShare()->make_field(NULL,
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,
1479
(*field)->init(table);
1480
record_length+= (*field)->pack_length();
1481
if (! ((*field)->flags & NOT_NULL_FLAG))
1484
if ((*field)->flags & BLOB_FLAG)
1485
table->getMutableShare()->blob_field[blob_count++]= (uint32_t) (field - table->getFields());
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;
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())
1500
if (null_pack_length)
1502
table->null_flags= (unsigned char*) table->getInsertRecord();
1503
table->getMutableShare()->null_fields= null_count;
1504
table->getMutableShare()->null_bytes= null_pack_length;
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;
1512
for (field= table->getFields(); *field; ++field)
1514
Field *cur_field= *field;
1515
if ((cur_field->flags & NOT_NULL_FLAG))
1516
cur_field->move_field(field_pos);
1519
cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
1521
if (null_bit == (1 << 8))
1529
field_pos+= cur_field->pack_length();
1536
for (field= table->getFields(); *field; ++field)
1538
delete *field; /* just invokes field destructor */
1384
1543
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1385
1544
boost::dynamic_bitset<>& write_set_arg)
1454
True if the table's input and output record buffers are comparable using
1455
compare_records(TABLE*).
1457
bool Table::records_are_comparable()
1459
return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1460
write_set->is_subset_of(*read_set));
1464
Compares the input and outbut record buffers of the table to see if a row
1465
has changed. The algorithm iterates over updated columns and if they are
1466
nullable compares NULL bits in the buffer before comparing actual
1467
data. Special care must be taken to compare only the relevant NULL bits and
1468
mask out all others as they may be undefined. The storage engine will not
1469
and should not touch them.
1471
@param table The table to evaluate.
1473
@return true if row has changed.
1474
@return false otherwise.
1476
bool Table::compare_records()
1478
if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1481
Storage engine may not have read all columns of the record. Fields
1482
(including NULL bits) not in the write_set may not have been read and
1483
can therefore not be compared.
1485
for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1488
if (write_set->test(f->position()))
1490
if (f->real_maybe_null())
1492
unsigned char null_byte_index= f->null_ptr - record[0];
1494
if (((record[0][null_byte_index]) & f->null_bit) !=
1495
((record[1][null_byte_index]) & f->null_bit))
1498
if (f->cmp_binary_offset(getShare()->rec_buff_length))
1506
The storage engine has read all columns, so it's safe to compare all bits
1507
including those not in the write_set. This is cheaper than the
1508
field-by-field comparison done above.
1612
/* Return false if row hasn't changed */
1614
bool Table::compare_record()
1510
1616
if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1511
// Fixed-size record: do bitwise comparison of the records
1512
1617
return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1514
1619
/* Compare null bits */
1515
1620
if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
1516
1621
return true; /* Diff in NULL value */
1626
1732
quick_condition_rows(0),
1627
1733
timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1634
1736
record[0]= (unsigned char *) 0;
1635
1737
record[1]= (unsigned char *) 0;
1740
covering_keys.reset();
1744
keys_in_use_for_query.reset();
1745
keys_in_use_for_group_by.reset();
1746
keys_in_use_for_order_by.reset();
1748
memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
1749
memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
1751
memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1752
memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1638
1755
/*****************************************************************************
1702
void Table::filesort_free_buffers(bool full)
1704
if (sort.record_pointers)
1706
free((unsigned char*) sort.record_pointers);
1707
sort.record_pointers=0;
1711
if (sort.sort_keys )
1713
if ((unsigned char*) sort.sort_keys)
1714
free((unsigned char*) sort.sort_keys);
1719
if ((unsigned char*) sort.buffpek)
1720
free((unsigned char*) sort.buffpek);
1722
sort.buffpek_len= 0;
1728
free((char *) sort.addon_buf);
1729
free((char *) sort.addon_field);
1736
Is this instance of the table should be reopen or represents a name-lock?
1738
bool Table::needs_reopen_or_name_lock() const
1740
return getShare()->getVersion() != refresh_version;
1743
uint32_t Table::index_flags(uint32_t idx) const
1745
return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
1748
void Table::print_error(int error, myf errflag) const
1750
getShare()->getEngine()->print_error(error, errflag, *this);
1753
1818
} /* namespace drizzled */