~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2010-10-30 01:19:00 UTC
  • mto: (1892.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1893.
  • Revision ID: mordred@inaugust.com-20101030011900-2tdt8w9vt7a6pbk0
Fixed things to make things compile with clang

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
82
82
  if (db_stat)
83
83
    error= cursor->close();
84
84
  _alias.clear();
85
 
 
86
85
  if (field)
87
86
  {
88
87
    for (Field **ptr=field ; *ptr ; ptr++)
91
90
    }
92
91
    field= 0;
93
92
  }
94
 
  safe_delete(cursor);
 
93
  delete cursor;
 
94
  cursor= 0;                            /* For easier errorchecking */
95
95
 
96
96
  if (free_share)
97
97
  {
98
 
    release();
 
98
    if (getShare()->getType() == message::Table::STANDARD)
 
99
    {
 
100
      TableShare::release(getMutableShare());
 
101
    }
 
102
    else
 
103
    {
 
104
      delete getShare();
 
105
    }
 
106
    setShare(NULL);
99
107
  }
100
108
 
101
109
  return error;
112
120
                       uint32_t db_stat_arg)
113
121
{
114
122
  setShare(share);
115
 
  in_use= session;
116
 
 
117
123
  field= NULL;
118
124
 
119
125
  cursor= NULL;
126
132
  tablenr= 0;
127
133
  db_stat= db_stat_arg;
128
134
 
 
135
  in_use= session;
129
136
  record[0]= (unsigned char *) NULL;
130
137
  record[1]= (unsigned char *) NULL;
131
138
 
197
204
 
198
205
/* Deallocate temporary blob storage */
199
206
 
200
 
void free_blobs(Table *table)
 
207
void free_blobs(register Table *table)
201
208
{
202
209
  uint32_t *ptr, *end;
203
210
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
223
230
    
224
231
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
232
 
226
 
  List<String>::iterator it(strings.begin());
 
233
  List_iterator<String> it(strings);
227
234
  String *tmp;
228
235
  for (uint32_t i= 0; (tmp= it++); i++)
229
236
  {
239
246
 
240
247
        /* Check that the integer is in the internal */
241
248
 
242
 
int set_zone(int nr, int min_zone, int max_zone)
 
249
int set_zone(register int nr, int min_zone, int max_zone)
243
250
{
244
251
  if (nr<=min_zone)
245
252
    return (min_zone);
248
255
  return (nr);
249
256
} /* set_zone */
250
257
 
 
258
        /* Adjust number to next larger disk buffer */
 
259
 
 
260
ulong next_io_size(register ulong pos)
 
261
{
 
262
  register ulong offset;
 
263
  if ((offset= pos & (IO_SIZE-1)))
 
264
    return pos-offset+IO_SIZE;
 
265
  return pos;
 
266
} /* next_io_size */
 
267
 
251
268
 
252
269
/*
253
270
  Store an SQL quoted string.
323
340
}
324
341
 
325
342
/*
 
343
  Check if database name is valid
 
344
 
 
345
  SYNPOSIS
 
346
    check_db_name()
 
347
    org_name            Name of database and length
 
348
 
 
349
  RETURN
 
350
    false error
 
351
    true ok
 
352
*/
 
353
 
 
354
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
 
355
{
 
356
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
 
357
  {
 
358
    return false;
 
359
  }
 
360
 
 
361
  return schema_identifier.isValid();
 
362
}
 
363
 
 
364
/*
326
365
  Allow anything as a table name, as long as it doesn't contain an
327
366
  ' ' at the end
328
367
  returns 1 on error
500
539
    We must set bit in read set as update_auto_increment() is using the
501
540
    store() to check overflow of auto_increment values
502
541
  */
503
 
  setReadSet(found_next_number_field->position());
504
 
  setWriteSet(found_next_number_field->position());
 
542
  setReadSet(found_next_number_field->field_index);
 
543
  setWriteSet(found_next_number_field->field_index);
505
544
  if (getShare()->next_number_keypart)
506
545
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
507
546
}
550
589
    for (reg_field= field ; *reg_field ; reg_field++)
551
590
    {
552
591
      if ((*reg_field)->flags & PART_KEY_FLAG)
553
 
        setReadSet((*reg_field)->position());
 
592
        setReadSet((*reg_field)->field_index);
554
593
    }
555
594
  }
556
595
}
599
638
    {
600
639
      /* Merge keys is all keys that had a column refered to in the query */
601
640
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
602
 
        setReadSet((*reg_field)->position());
 
641
        setReadSet((*reg_field)->field_index);
603
642
    }
604
643
  }
605
644
 
640
679
void Table::setVariableWidth(void)
641
680
{
642
681
  assert(in_use);
643
 
  if (in_use && in_use->getLex()->sql_command == SQLCOM_CREATE_TABLE)
 
682
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
644
683
  {
645
684
    getMutableShare()->setVariableWidth();
646
685
    return;
750
789
 
751
790
Table *
752
791
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
753
 
                 Order *group, bool distinct, bool save_sum_fields,
 
792
                 order_st *group, bool distinct, bool save_sum_fields,
754
793
                 uint64_t select_options, ha_rows rows_limit,
755
794
                 const char *table_alias)
756
795
{
784
823
    {
785
824
      group= 0;                                 // Can't use group key
786
825
    }
787
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
826
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
788
827
    {
789
828
      /*
790
829
        marker == 4 means two things:
817
856
    copy_func_count+= param->sum_func_count;
818
857
  }
819
858
 
820
 
  table::Singular *table;
 
859
  table::Instance *table;
821
860
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
822
861
 
823
862
  if (not table->getMemRoot()->multi_alloc_root(0,
863
902
 
864
903
  table->getMutableShare()->blob_field.resize(field_count+1);
865
904
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
 
905
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
866
906
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
867
907
  table->getMutableShare()->table_charset= param->table_charset;
868
908
  table->getMutableShare()->keys_for_keyread.reset();
874
914
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
875
915
  param->using_indirect_summary_function= 0;
876
916
 
877
 
  List<Item>::iterator li(fields.begin());
 
917
  List_iterator_fast<Item> li(fields);
878
918
  Item *item;
879
919
  Field **tmp_from_field=from_field;
880
920
  while ((item=li++))
943
983
            */
944
984
            (*argp)->maybe_null=1;
945
985
          }
946
 
          new_field->setPosition(fieldnr++);
 
986
          new_field->field_index= fieldnr++;
947
987
        }
948
988
      }
949
989
    }
990
1030
        group_null_items++;
991
1031
        new_field->flags|= GROUP_FLAG;
992
1032
      }
993
 
      new_field->setPosition(fieldnr++);
 
1033
      new_field->field_index= fieldnr++;
994
1034
      *(reg_field++)= new_field;
995
1035
    }
996
1036
    if (!--hidden_field_count)
1013
1053
  field_count= fieldnr;
1014
1054
  *reg_field= 0;
1015
1055
  *blob_field= 0;                               // End marker
1016
 
  table->getMutableShare()->setFieldSize(field_count);
 
1056
  table->getMutableShare()->fields= field_count;
1017
1057
 
1018
1058
  /* If result table is small; use a heap */
1019
1059
  /* future: storage engine selection can be made dynamic? */
1020
1060
  if (blob_count || using_unique_constraint || 
1021
 
      (session->getLex()->select_lex.options & SELECT_BIG_RESULT) ||
1022
 
      (session->getLex()->current_select->olap == ROLLUP_TYPE) ||
 
1061
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
 
1062
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1023
1063
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
1024
1064
  {
1025
1065
    table->getMutableShare()->storage_engine= myisam_engine;
1216
1256
    keyinfo->rec_per_key= 0;
1217
1257
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1218
1258
    keyinfo->name= (char*) "group_key";
1219
 
    Order *cur_group= group;
 
1259
    order_st *cur_group= group;
1220
1260
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1221
1261
    {
1222
1262
      Field *field=(*cur_group->item)->get_tmp_table_field();
1450
1490
  return false;
1451
1491
}
1452
1492
 
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
 
  */
 
1493
/* Return false if row hasn't changed */
 
1494
 
 
1495
bool Table::compare_record()
 
1496
{
1510
1497
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1511
 
    // Fixed-size record: do bitwise comparison of the records
1512
1498
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1513
 
 
 
1499
  
1514
1500
  /* Compare null bits */
1515
1501
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
1516
1502
    return true; /* Diff in NULL value */
1518
1504
  /* Compare updated fields */
1519
1505
  for (Field **ptr= field ; *ptr ; ptr++)
1520
1506
  {
1521
 
    if (isWriteSet((*ptr)->position()) &&
 
1507
    if (isWriteSet((*ptr)->field_index) &&
1522
1508
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
1523
1509
      return true;
1524
1510
  }
1625
1611
  query_id(0),
1626
1612
  quick_condition_rows(0),
1627
1613
  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()
 
1614
  map(0)
1633
1615
{
1634
1616
  record[0]= (unsigned char *) 0;
1635
1617
  record[1]= (unsigned char *) 0;
 
1618
 
 
1619
  reginfo.reset();
 
1620
  covering_keys.reset();
 
1621
  quick_keys.reset();
 
1622
  merge_keys.reset();
 
1623
 
 
1624
  keys_in_use_for_query.reset();
 
1625
  keys_in_use_for_group_by.reset();
 
1626
  keys_in_use_for_order_by.reset();
 
1627
 
 
1628
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
1629
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
1630
 
 
1631
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
1632
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1636
1633
}
1637
1634
 
1638
1635
/*****************************************************************************
1654
1651
    print them to the .err log
1655
1652
  */
1656
1653
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1657
 
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
 
1654
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
1658
1655
                  error, getShare()->getPath());
1659
1656
  print_error(error, MYF(0));
1660
1657
 
1698
1695
  return false;
1699
1696
}
1700
1697
 
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
1698
} /* namespace drizzled */