~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

Fix merge issue.

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>
 
19
#include "config.h"
20
20
 
21
21
#include <float.h>
22
22
#include <fcntl.h>
28
28
#include <drizzled/error.h>
29
29
#include <drizzled/gettext.h>
30
30
 
31
 
#include <drizzled/plugin/transactional_storage_engine.h>
32
 
#include <drizzled/plugin/authorization.h>
 
31
#include "drizzled/plugin/transactional_storage_engine.h"
 
32
#include "drizzled/plugin/authorization.h"
33
33
#include <drizzled/nested_join.h>
34
34
#include <drizzled/sql_parse.h>
35
35
#include <drizzled/item/sum.h>
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"
50
49
 
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>
57
56
 
58
 
#include <drizzled/refresh_version.h>
59
 
 
60
 
#include <drizzled/table/singular.h>
61
 
 
62
 
#include <drizzled/table_proto.h>
63
 
#include <drizzled/typelib.h>
 
57
#include "drizzled/table/instance.h"
 
58
 
 
59
#include "drizzled/table_proto.h"
64
60
 
65
61
using namespace std;
66
62
 
67
63
namespace drizzled
68
64
{
69
65
 
 
66
extern pid_t current_pid;
70
67
extern plugin::StorageEngine *heap_engine;
71
68
extern plugin::StorageEngine *myisam_engine;
72
69
 
73
70
/* Functions defined in this cursor */
74
71
 
 
72
void open_table_error(TableShare *share, int error, int db_errno,
 
73
                      myf errortype, int errarg);
 
74
 
75
75
/*************************************************************************/
76
76
 
77
77
// @note this should all be the destructor
81
81
 
82
82
  if (db_stat)
83
83
    error= cursor->close();
84
 
  _alias.clear();
85
 
 
 
84
  free((char*) alias);
 
85
  alias= NULL;
86
86
  if (field)
87
87
  {
88
88
    for (Field **ptr=field ; *ptr ; ptr++)
91
91
    }
92
92
    field= 0;
93
93
  }
94
 
  safe_delete(cursor);
 
94
  delete cursor;
 
95
  cursor= 0;                            /* For easier errorchecking */
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,
112
118
                       uint32_t db_stat_arg)
113
119
{
114
120
  setShare(share);
115
 
  in_use= session;
116
 
 
117
121
  field= NULL;
118
122
 
119
123
  cursor= NULL;
126
130
  tablenr= 0;
127
131
  db_stat= db_stat_arg;
128
132
 
 
133
  in_use= session;
129
134
  record[0]= (unsigned char *) NULL;
130
135
  record[1]= (unsigned char *) NULL;
131
136
 
137
142
 
138
143
  pos_in_table_list= NULL;
139
144
  group= NULL;
140
 
  _alias.clear();
 
145
  alias= NULL;
141
146
  null_flags= NULL;
142
147
 
143
148
  lock_position= 0;
197
202
 
198
203
/* Deallocate temporary blob storage */
199
204
 
200
 
void free_blobs(Table *table)
 
205
void free_blobs(register Table *table)
201
206
{
202
207
  uint32_t *ptr, *end;
203
208
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
223
228
    
224
229
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
230
 
226
 
  List<String>::iterator it(strings.begin());
 
231
  List_iterator<String> it(strings);
227
232
  String *tmp;
228
233
  for (uint32_t i= 0; (tmp= it++); i++)
229
234
  {
239
244
 
240
245
        /* Check that the integer is in the internal */
241
246
 
242
 
int set_zone(int nr, int min_zone, int max_zone)
 
247
int set_zone(register int nr, int min_zone, int max_zone)
243
248
{
244
249
  if (nr<=min_zone)
245
250
    return (min_zone);
248
253
  return (nr);
249
254
} /* set_zone */
250
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
 
251
266
 
252
267
/*
253
268
  Store an SQL quoted string.
323
338
}
324
339
 
325
340
/*
 
341
  Check if database name is valid
 
342
 
 
343
  SYNPOSIS
 
344
    check_db_name()
 
345
    org_name            Name of database and length
 
346
 
 
347
  RETURN
 
348
    false error
 
349
    true ok
 
350
*/
 
351
 
 
352
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
 
353
{
 
354
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
 
355
  {
 
356
    return false;
 
357
  }
 
358
 
 
359
  return schema_identifier.isValid();
 
360
}
 
361
 
 
362
/*
326
363
  Allow anything as a table name, as long as it doesn't contain an
327
364
  ' ' at the end
328
365
  returns 1 on error
500
537
    We must set bit in read set as update_auto_increment() is using the
501
538
    store() to check overflow of auto_increment values
502
539
  */
503
 
  setReadSet(found_next_number_field->position());
504
 
  setWriteSet(found_next_number_field->position());
 
540
  setReadSet(found_next_number_field->field_index);
 
541
  setWriteSet(found_next_number_field->field_index);
505
542
  if (getShare()->next_number_keypart)
506
543
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
507
544
}
550
587
    for (reg_field= field ; *reg_field ; reg_field++)
551
588
    {
552
589
      if ((*reg_field)->flags & PART_KEY_FLAG)
553
 
        setReadSet((*reg_field)->position());
 
590
        setReadSet((*reg_field)->field_index);
554
591
    }
555
592
  }
556
593
}
599
636
    {
600
637
      /* Merge keys is all keys that had a column refered to in the query */
601
638
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
602
 
        setReadSet((*reg_field)->position());
 
639
        setReadSet((*reg_field)->field_index);
603
640
    }
604
641
  }
605
642
 
640
677
void Table::setVariableWidth(void)
641
678
{
642
679
  assert(in_use);
643
 
  if (in_use && in_use->getLex()->sql_command == SQLCOM_CREATE_TABLE)
 
680
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
644
681
  {
645
682
    getMutableShare()->setVariableWidth();
646
683
    return;
750
787
 
751
788
Table *
752
789
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
753
 
                 Order *group, bool distinct, bool save_sum_fields,
 
790
                 order_st *group, bool distinct, bool save_sum_fields,
754
791
                 uint64_t select_options, ha_rows rows_limit,
755
792
                 const char *table_alias)
756
793
{
784
821
    {
785
822
      group= 0;                                 // Can't use group key
786
823
    }
787
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
824
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
788
825
    {
789
826
      /*
790
827
        marker == 4 means two things:
817
854
    copy_func_count+= param->sum_func_count;
818
855
  }
819
856
 
820
 
  table::Singular *table;
 
857
  table::Instance *table;
821
858
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
822
859
 
823
860
  if (not table->getMemRoot()->multi_alloc_root(0,
850
887
  table->getMutableShare()->setFields(field_count+1);
851
888
  table->setFields(table->getMutableShare()->getFields(true));
852
889
  reg_field= table->getMutableShare()->getFields(true);
853
 
  table->setAlias(table_alias);
 
890
  table->alias= table_alias;
854
891
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
855
892
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
856
893
  table->map=1;
863
900
 
864
901
  table->getMutableShare()->blob_field.resize(field_count+1);
865
902
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
 
903
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
866
904
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
867
905
  table->getMutableShare()->table_charset= param->table_charset;
868
906
  table->getMutableShare()->keys_for_keyread.reset();
874
912
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
875
913
  param->using_indirect_summary_function= 0;
876
914
 
877
 
  List<Item>::iterator li(fields.begin());
 
915
  List_iterator_fast<Item> li(fields);
878
916
  Item *item;
879
917
  Field **tmp_from_field=from_field;
880
918
  while ((item=li++))
943
981
            */
944
982
            (*argp)->maybe_null=1;
945
983
          }
946
 
          new_field->setPosition(fieldnr++);
 
984
          new_field->field_index= fieldnr++;
947
985
        }
948
986
      }
949
987
    }
990
1028
        group_null_items++;
991
1029
        new_field->flags|= GROUP_FLAG;
992
1030
      }
993
 
      new_field->setPosition(fieldnr++);
 
1031
      new_field->field_index= fieldnr++;
994
1032
      *(reg_field++)= new_field;
995
1033
    }
996
1034
    if (!--hidden_field_count)
1013
1051
  field_count= fieldnr;
1014
1052
  *reg_field= 0;
1015
1053
  *blob_field= 0;                               // End marker
1016
 
  table->getMutableShare()->setFieldSize(field_count);
 
1054
  table->getMutableShare()->fields= field_count;
1017
1055
 
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)
1024
1062
  {
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());
1027
1065
    if (group &&
1028
1066
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1029
1067
         param->group_length > table->cursor->getEngine()->max_key_length()))
1034
1072
  else
1035
1073
  {
1036
1074
    table->getMutableShare()->storage_engine= heap_engine;
1037
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
1075
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare());
1038
1076
  }
1039
1077
  if (! table->cursor)
1040
1078
    goto err;
1216
1254
    keyinfo->rec_per_key= 0;
1217
1255
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1218
1256
    keyinfo->name= (char*) "group_key";
1219
 
    Order *cur_group= group;
 
1257
    order_st *cur_group= group;
1220
1258
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1221
1259
    {
1222
1260
      Field *field=(*cur_group->item)->get_tmp_table_field();
1381
1419
 
1382
1420
/****************************************************************************/
1383
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
 
1384
1543
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1385
1544
                               boost::dynamic_bitset<>& write_set_arg)
1386
1545
{
1450
1609
  return false;
1451
1610
}
1452
1611
 
1453
 
/**
1454
 
   True if the table's input and output record buffers are comparable using
1455
 
   compare_records(TABLE*).
1456
 
 */
1457
 
bool Table::records_are_comparable()
1458
 
{
1459
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1460
 
          write_set->is_subset_of(*read_set));
1461
 
}
1462
 
 
1463
 
/**
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.
1470
 
 
1471
 
   @param table The table to evaluate.
1472
 
 
1473
 
   @return true if row has changed.
1474
 
   @return false otherwise.
1475
 
*/
1476
 
bool Table::compare_records()
1477
 
{
1478
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1479
 
  {
1480
 
    /*
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.
1484
 
    */
1485
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1486
 
    {
1487
 
      Field *f= *ptr;
1488
 
      if (write_set->test(f->position()))
1489
 
      {
1490
 
        if (f->real_maybe_null())
1491
 
        {
1492
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1493
 
 
1494
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1495
 
              ((record[1][null_byte_index]) & f->null_bit))
1496
 
            return true;
1497
 
        }
1498
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1499
 
          return true;
1500
 
      }
1501
 
    }
1502
 
    return false;
1503
 
  }
1504
 
 
1505
 
  /*
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.
1509
 
  */
 
1612
/* Return false if row hasn't changed */
 
1613
 
 
1614
bool Table::compare_record()
 
1615
{
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());
1513
 
 
 
1618
  
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 */
1518
1623
  /* Compare updated fields */
1519
1624
  for (Field **ptr= field ; *ptr ; ptr++)
1520
1625
  {
1521
 
    if (isWriteSet((*ptr)->position()) &&
 
1626
    if (isWriteSet((*ptr)->field_index) &&
1522
1627
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
1523
1628
      return true;
1524
1629
  }
1600
1705
  timestamp_field(NULL),
1601
1706
  pos_in_table_list(NULL),
1602
1707
  group(NULL),
 
1708
  alias(NULL),
1603
1709
  null_flags(NULL),
1604
1710
  lock_position(0),
1605
1711
  lock_data_start(0),
1625
1731
  query_id(0),
1626
1732
  quick_condition_rows(0),
1627
1733
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1628
 
  map(0),
1629
 
  quick_rows(),
1630
 
  const_key_parts(),
1631
 
  quick_key_parts(),
1632
 
  quick_n_ranges()
 
1734
  map(0)
1633
1735
{
1634
1736
  record[0]= (unsigned char *) 0;
1635
1737
  record[1]= (unsigned char *) 0;
 
1738
 
 
1739
  reginfo.reset();
 
1740
  covering_keys.reset();
 
1741
  quick_keys.reset();
 
1742
  merge_keys.reset();
 
1743
 
 
1744
  keys_in_use_for_query.reset();
 
1745
  keys_in_use_for_group_by.reset();
 
1746
  keys_in_use_for_order_by.reset();
 
1747
 
 
1748
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
1749
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
1750
 
 
1751
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
1752
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1636
1753
}
1637
1754
 
1638
1755
/*****************************************************************************
1654
1771
    print them to the .err log
1655
1772
  */
1656
1773
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1657
 
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
 
1774
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
1658
1775
                  error, getShare()->getPath());
1659
1776
  print_error(error, MYF(0));
1660
1777
 
1698
1815
  return false;
1699
1816
}
1700
1817
 
1701
 
 
1702
 
void Table::filesort_free_buffers(bool full)
1703
 
{
1704
 
  if (sort.record_pointers)
1705
 
  {
1706
 
    free((unsigned char*) sort.record_pointers);
1707
 
    sort.record_pointers=0;
1708
 
  }
1709
 
  if (full)
1710
 
  {
1711
 
    if (sort.sort_keys )
1712
 
    {
1713
 
      if ((unsigned char*) sort.sort_keys)
1714
 
        free((unsigned char*) sort.sort_keys);
1715
 
      sort.sort_keys= 0;
1716
 
    }
1717
 
    if (sort.buffpek)
1718
 
    {
1719
 
      if ((unsigned char*) sort.buffpek)
1720
 
        free((unsigned char*) sort.buffpek);
1721
 
      sort.buffpek= 0;
1722
 
      sort.buffpek_len= 0;
1723
 
    }
1724
 
  }
1725
 
 
1726
 
  if (sort.addon_buf)
1727
 
  {
1728
 
    free((char *) sort.addon_buf);
1729
 
    free((char *) sort.addon_field);
1730
 
    sort.addon_buf=0;
1731
 
    sort.addon_field=0;
1732
 
  }
1733
 
}
1734
 
 
1735
 
/*
1736
 
  Is this instance of the table should be reopen or represents a name-lock?
1737
 
*/
1738
 
bool Table::needs_reopen_or_name_lock() const
1739
 
1740
 
  return getShare()->getVersion() != refresh_version;
1741
 
}
1742
 
 
1743
 
uint32_t Table::index_flags(uint32_t idx) const
1744
 
{
1745
 
  return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
1746
 
}
1747
 
 
1748
 
void Table::print_error(int error, myf errflag) const
1749
 
{
1750
 
  getShare()->getEngine()->print_error(error, errflag, *this);
1751
 
}
1752
 
 
1753
1818
} /* namespace drizzled */