~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Mats Kindahl
  • Date: 2008-08-07 06:24:22 UTC
  • mfrom: (265 drizzle)
  • mto: (264.1.19 codestyle)
  • mto: This revision was merged to the branch mainline in revision 266.
  • Revision ID: mats@mysql.com-20080807062422-20kyv6ssp4grfm0s
Manual merge of lp:drizzle into ~mkindahl/remove-mem-casts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
  Drizzle has a different form of DELAYED then MySQL. DELAYED is just
23
23
  a hint to the the sorage engine (which can then do whatever it likes.
24
24
*/
25
 
#include <drizzled/server_includes.h>
26
 
#include <drizzled/sql_select.h>
27
 
#include <drizzled/sql_show.h>
 
25
 
 
26
#include "mysql_priv.h"
 
27
#include "sql_select.h"
 
28
#include "sql_show.h"
 
29
#include "slave.h"
28
30
#include "rpl_mi.h"
29
31
#include <drizzled/drizzled_error_messages.h>
30
32
 
34
36
#define my_safe_alloca(size, min_length) my_alloca(size)
35
37
#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
36
38
#else
37
 
#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : malloc(size))
38
 
#define my_safe_afree(ptr, size, min_length) if (size > min_length) free(ptr)
 
39
#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
 
40
#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
39
41
#endif
40
42
 
41
43
 
61
63
    -1          Error
62
64
*/
63
65
 
64
 
static int check_insert_fields(THD *thd, TableList *table_list,
 
66
static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
65
67
                               List<Item> &fields, List<Item> &values,
66
68
                               bool check_unique,
67
69
                               table_map *map __attribute__((unused)))
68
70
{
69
 
  Table *table= table_list->table;
 
71
  TABLE *table= table_list->table;
70
72
 
71
73
  if (fields.elements == 0 && values.elements != 0)
72
74
  {
132
134
                       table->timestamp_field->field_index);
133
135
      }
134
136
    }
135
 
    /* Mark all virtual columns for write*/
136
 
    if (table->vfield)
137
 
      table->mark_virtual_columns();
138
137
  }
139
138
 
140
139
  return 0;
160
159
    -1          Error
161
160
*/
162
161
 
163
 
static int check_update_fields(THD *thd, TableList *insert_table_list,
 
162
static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
164
163
                               List<Item> &update_fields,
165
164
                               table_map *map __attribute__((unused)))
166
165
{
167
 
  Table *table= insert_table_list->table;
 
166
  TABLE *table= insert_table_list->table;
168
167
  bool timestamp_mark= false;
169
168
 
170
169
  if (table->timestamp_field)
227
226
  end of dispatch_command().
228
227
*/
229
228
 
230
 
bool mysql_insert(THD *thd,TableList *table_list,
 
229
bool mysql_insert(THD *thd,TABLE_LIST *table_list,
231
230
                  List<Item> &fields,
232
231
                  List<List_item> &values_list,
233
232
                  List<Item> &update_fields,
239
238
  bool transactional_table, joins_freed= false;
240
239
  bool changed;
241
240
  bool was_insert_delayed= (table_list->lock_type ==  TL_WRITE_DELAYED);
242
 
  uint32_t value_count;
 
241
  uint value_count;
243
242
  ulong counter = 1;
244
243
  uint64_t id;
245
244
  COPY_INFO info;
246
 
  Table *table= 0;
 
245
  TABLE *table= 0;
247
246
  List_iterator_fast<List_item> its(values_list);
248
247
  List_item *values;
249
248
  Name_resolution_context *context;
279
278
  }
280
279
  lock_type= table_list->lock_type;
281
280
 
282
 
  thd->set_proc_info("init");
 
281
  thd_proc_info(thd, "init");
283
282
  thd->used_tables=0;
284
283
  values= its++;
285
284
  value_count= values->elements;
351
350
  thd->cuted_fields = 0L;
352
351
  table->next_number_field=table->found_next_number_field;
353
352
 
 
353
#ifdef HAVE_REPLICATION
354
354
  if (thd->slave_thread &&
355
355
      (info.handle_duplicates == DUP_UPDATE) &&
356
356
      (table->next_number_field != NULL) &&
357
357
      rpl_master_has_bug(&active_mi->rli, 24432))
358
358
    goto abort;
 
359
#endif
359
360
 
360
361
  error=0;
361
 
  thd->set_proc_info("update");
 
362
  thd_proc_info(thd, "update");
362
363
  if (duplic == DUP_REPLACE)
363
364
    table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
364
365
  if (duplic == DUP_UPDATE)
436
437
  {
437
438
    /*
438
439
      Do not do this release if this is a delayed insert, it would steal
439
 
      auto_inc values from the delayed_insert thread as they share Table.
 
440
      auto_inc values from the delayed_insert thread as they share TABLE.
440
441
    */
441
442
    table->file->ha_release_auto_increment();
442
443
    if (table->file->ha_end_bulk_insert() && !error)
504
505
                thd->transaction.stmt.modified_non_trans_table);
505
506
 
506
507
  }
507
 
  thd->set_proc_info("end");
 
508
  thd_proc_info(thd, "end");
508
509
  /*
509
510
    We'll report to the client this id:
510
511
    - if the table contains an autoincrement column and we successfully
552
553
    ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
553
554
  }
554
555
  thd->abort_on_warning= 0;
555
 
  DRIZZLE_INSERT_END();
 
556
  MYSQL_INSERT_END();
556
557
  return(false);
557
558
 
558
559
abort:
561
562
  if (!joins_freed)
562
563
    free_underlaid_joins(thd, &thd->lex->select_lex);
563
564
  thd->abort_on_warning= 0;
564
 
  DRIZZLE_INSERT_END();
 
565
  MYSQL_INSERT_END();
565
566
  return(true);
566
567
}
567
568
 
582
583
     true  ERROR
583
584
*/
584
585
 
585
 
static bool mysql_prepare_insert_check_table(THD *thd, TableList *table_list,
 
586
static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
586
587
                                             List<Item> &fields __attribute__((unused)),
587
588
                                             bool select_insert)
588
589
{
637
638
    true  error
638
639
*/
639
640
 
640
 
bool mysql_prepare_insert(THD *thd, TableList *table_list,
641
 
                          Table *table, List<Item> &fields, List_item *values,
 
641
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
 
642
                          TABLE *table, List<Item> &fields, List_item *values,
642
643
                          List<Item> &update_fields, List<Item> &update_values,
643
644
                          enum_duplicates duplic,
644
645
                          COND **where __attribute__((unused)),
737
738
 
738
739
  if (!select_insert)
739
740
  {
740
 
    TableList *duplicate;
 
741
    TABLE_LIST *duplicate;
741
742
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 1)))
742
743
    {
743
744
      update_non_unique_table_error(table_list, "INSERT", duplicate);
744
745
      return(true);
745
746
    }
 
747
    select_lex->first_execution= 0;
746
748
  }
747
749
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
748
750
    table->prepare_for_position();
752
754
 
753
755
        /* Check if there is more uniq keys after field */
754
756
 
755
 
static int last_uniq_key(Table *table,uint32_t keynr)
 
757
static int last_uniq_key(TABLE *table,uint keynr)
756
758
{
757
759
  while (++keynr < table->s->keys)
758
760
    if (table->key_info[keynr].flags & HA_NOSAME)
788
790
*/
789
791
 
790
792
 
791
 
int write_record(THD *thd, Table *table,COPY_INFO *info)
 
793
int write_record(THD *thd, TABLE *table,COPY_INFO *info)
792
794
{
793
795
  int error;
794
796
  char *key=0;
806
808
  {
807
809
    while ((error=table->file->ha_write_row(table->record[0])))
808
810
    {
809
 
      uint32_t key_nr;
 
811
      uint key_nr;
810
812
      /*
811
813
        If we do more than one iteration of this loop, from the second one the
812
814
        row will have an explicit value in the autoinc field, which was set at
872
874
            goto err;
873
875
          }
874
876
        }
875
 
        key_copy((unsigned char*) key,table->record[0],table->key_info+key_nr,0);
 
877
        key_copy((uchar*) key,table->record[0],table->key_info+key_nr,0);
876
878
        if ((error=(table->file->index_read_idx_map(table->record[1],key_nr,
877
 
                                                    (unsigned char*) key, HA_WHOLE_KEY,
 
879
                                                    (uchar*) key, HA_WHOLE_KEY,
878
880
                                                    HA_READ_KEY_EXACT))))
879
881
          goto err;
880
882
      }
902
904
        info->touched++;
903
905
        if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
904
906
             !bitmap_is_subset(table->write_set, table->read_set)) ||
905
 
            table->compare_record())
 
907
            compare_record(table))
906
908
        {
907
909
          if ((error=table->file->ha_update_row(table->record[1],
908
910
                                                table->record[0])) &&
1034
1036
  Check that all fields with arn't null_fields are used
1035
1037
******************************************************************************/
1036
1038
 
1037
 
int check_that_all_fields_are_given_values(THD *thd, Table *entry,
1038
 
                                           TableList *table_list)
 
1039
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
 
1040
                                           TABLE_LIST *table_list)
1039
1041
{
1040
1042
  int err= 0;
1041
1043
  MY_BITMAP *write_set= entry->write_set;
1085
1087
{
1086
1088
  LEX *lex= thd->lex;
1087
1089
  SELECT_LEX *select_lex= &lex->select_lex;
 
1090
  TABLE_LIST *first_select_leaf_table;
1088
1091
  
1089
1092
 
1090
1093
  /*
1119
1122
  assert(select_lex->leaf_tables != 0);
1120
1123
  lex->leaf_tables_insert= select_lex->leaf_tables;
1121
1124
  /* skip all leaf tables belonged to view where we are insert */
1122
 
  select_lex->leaf_tables= select_lex->leaf_tables->next_leaf;
 
1125
  for (first_select_leaf_table= select_lex->leaf_tables->next_leaf;
 
1126
       first_select_leaf_table &&
 
1127
       first_select_leaf_table->belong_to_view &&
 
1128
       first_select_leaf_table->belong_to_view ==
 
1129
       lex->leaf_tables_insert->belong_to_view;
 
1130
       first_select_leaf_table= first_select_leaf_table->next_leaf)
 
1131
  {}
 
1132
  select_lex->leaf_tables= first_select_leaf_table;
1123
1133
  return(false);
1124
1134
}
1125
1135
 
1126
1136
 
1127
 
select_insert::select_insert(TableList *table_list_par, Table *table_par,
 
1137
select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par,
1128
1138
                             List<Item> *fields_par,
1129
1139
                             List<Item> *update_fields,
1130
1140
                             List<Item> *update_values,
1218
1228
      while ((item= li++))
1219
1229
      {
1220
1230
        item->transform(&Item::update_value_transformer,
1221
 
                        (unsigned char*)lex->current_select);
 
1231
                        (uchar*)lex->current_select);
1222
1232
      }
1223
1233
    }
1224
1234
 
1261
1271
  restore_record(table,s->default_values);              // Get empty record
1262
1272
  table->next_number_field=table->found_next_number_field;
1263
1273
 
 
1274
#ifdef HAVE_REPLICATION
1264
1275
  if (thd->slave_thread &&
1265
1276
      (info.handle_duplicates == DUP_UPDATE) &&
1266
1277
      (table->next_number_field != NULL) &&
1267
1278
      rpl_master_has_bug(&active_mi->rli, 24432))
1268
1279
    return(1);
 
1280
#endif
1269
1281
 
1270
1282
  thd->cuted_fields=0;
1271
1283
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1389
1401
    fill_record(thd, table->field, values, 1);
1390
1402
}
1391
1403
 
1392
 
void select_insert::send_error(uint32_t errcode,const char *err)
 
1404
void select_insert::send_error(uint errcode,const char *err)
1393
1405
{
1394
1406
  
1395
1407
 
1517
1529
***************************************************************************/
1518
1530
 
1519
1531
/*
1520
 
  Create table from lists of fields and items (or just return Table
 
1532
  Create table from lists of fields and items (or just return TABLE
1521
1533
  object for pre-opened existing table).
1522
1534
 
1523
1535
  SYNOPSIS
1525
1537
      thd          in     Thread object
1526
1538
      create_info  in     Create information (like MAX_ROWS, ENGINE or
1527
1539
                          temporary table flag)
1528
 
      create_table in     Pointer to TableList object providing database
 
1540
      create_table in     Pointer to TABLE_LIST object providing database
1529
1541
                          and name for table to be created or to be open
1530
1542
      alter_info   in/out Initial list of columns and indexes for the table
1531
1543
                          to be created
1532
1544
      items        in     List of items which should be used to produce rest
1533
1545
                          of fields for the table (corresponding fields will
1534
1546
                          be added to the end of alter_info->create_list)
1535
 
      lock         out    Pointer to the DRIZZLE_LOCK object for table created
 
1547
      lock         out    Pointer to the MYSQL_LOCK object for table created
1536
1548
                          (or open temporary table) will be returned in this
1537
1549
                          parameter. Since this table is not included in
1538
1550
                          THD::lock caller is responsible for explicitly
1543
1555
    This function behaves differently for base and temporary tables:
1544
1556
    - For base table we assume that either table exists and was pre-opened
1545
1557
      and locked at open_and_lock_tables() stage (and in this case we just
1546
 
      emit error or warning and return pre-opened Table object) or special
 
1558
      emit error or warning and return pre-opened TABLE object) or special
1547
1559
      placeholder was put in table cache that guarantees that this table
1548
1560
      won't be created or opened until the placeholder will be removed
1549
1561
      (so there is an exclusive lock on this table).
1554
1566
    SELECT it should be changed before it can be used in other contexts.
1555
1567
 
1556
1568
  RETURN VALUES
1557
 
    non-zero  Pointer to Table object for table created or opened
 
1569
    non-zero  Pointer to TABLE object for table created or opened
1558
1570
    0         Error
1559
1571
*/
1560
1572
 
1561
 
static Table *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
1562
 
                                      TableList *create_table,
 
1573
static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
 
1574
                                      TABLE_LIST *create_table,
1563
1575
                                      Alter_info *alter_info,
1564
1576
                                      List<Item> *items,
1565
 
                                      DRIZZLE_LOCK **lock,
 
1577
                                      MYSQL_LOCK **lock,
1566
1578
                                      TABLEOP_HOOKS *hooks)
1567
1579
{
1568
 
  Table tmp_table;              // Used during 'Create_field()'
 
1580
  TABLE tmp_table;              // Used during 'Create_field()'
1569
1581
  TABLE_SHARE share;
1570
 
  Table *table= 0;
1571
 
  uint32_t select_field_count= items->elements;
 
1582
  TABLE *table= 0;
 
1583
  uint select_field_count= items->elements;
1572
1584
  /* Add selected items to field list */
1573
1585
  List_iterator_fast<Item> it(*items);
1574
1586
  Item *item;
1602
1614
  tmp_table.s->db_low_byte_first= 
1603
1615
        test(create_info->db_type == myisam_hton ||
1604
1616
             create_info->db_type == heap_hton);
1605
 
  tmp_table.null_row= false;
1606
 
  tmp_table.maybe_null= false;
 
1617
  tmp_table.null_row=tmp_table.maybe_null=0;
1607
1618
 
1608
1619
  while ((item=it++))
1609
1620
  {
1641
1652
    binlog when a HEAP table is opened for the first time since startup, must
1642
1653
    not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
1643
1654
    don't want to delete from it) 2) it would be written before the CREATE
1644
 
    Table, which is a wrong order. So we keep binary logging disabled when we
 
1655
    TABLE, which is a wrong order. So we keep binary logging disabled when we
1645
1656
    open_table().
1646
1657
  */
1647
1658
  {
1649
1660
    if (!mysql_create_table_no_lock(thd, create_table->db,
1650
1661
                                    create_table->table_name,
1651
1662
                                    create_info, alter_info, 0,
1652
 
                                    select_field_count, true))
 
1663
                                    select_field_count))
1653
1664
    {
1654
1665
      if (create_info->table_existed &&
1655
1666
          !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1665
1676
 
1666
1677
      if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1667
1678
      {
1668
 
        pthread_mutex_lock(&LOCK_open);
 
1679
        VOID(pthread_mutex_lock(&LOCK_open));
1669
1680
        if (reopen_name_locked_table(thd, create_table, false))
1670
1681
        {
1671
1682
          quick_rm_table(create_info->db_type, create_table->db,
1674
1685
        }
1675
1686
        else
1676
1687
          table= create_table->table;
1677
 
        pthread_mutex_unlock(&LOCK_open);
 
1688
        VOID(pthread_mutex_unlock(&LOCK_open));
1678
1689
      }
1679
1690
      else
1680
1691
      {
1681
 
        if (!(table= open_table(thd, create_table, (bool*) 0,
1682
 
                                DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
 
1692
        if (!(table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
 
1693
                                MYSQL_OPEN_TEMPORARY_ONLY)) &&
1683
1694
            !create_info->table_existed)
1684
1695
        {
1685
1696
          /*
1699
1710
  table->reginfo.lock_type=TL_WRITE;
1700
1711
  hooks->prelock(&table, 1);                    // Call prelock hooks
1701
1712
  if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
1702
 
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)) ||
 
1713
                                    MYSQL_LOCK_IGNORE_FLUSH, &not_used)) ||
1703
1714
        hooks->postlock(&table, 1))
1704
1715
  {
1705
1716
    if (*lock)
1719
1730
int
1720
1731
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
1721
1732
{
1722
 
  DRIZZLE_LOCK *extra_lock= NULL;
 
1733
  MYSQL_LOCK *extra_lock= NULL;
1723
1734
  
1724
1735
 
1725
1736
  TABLEOP_HOOKS *hook_ptr= NULL;
1743
1754
   */
1744
1755
  class MY_HOOKS : public TABLEOP_HOOKS {
1745
1756
  public:
1746
 
    MY_HOOKS(select_create *x, TableList *create_table,
1747
 
             TableList *select_tables)
 
1757
    MY_HOOKS(select_create *x, TABLE_LIST *create_table,
 
1758
             TABLE_LIST *select_tables)
1748
1759
      : ptr(x), all_tables(*create_table)
1749
1760
      {
1750
1761
        all_tables.next_global= select_tables;
1751
1762
      }
1752
1763
 
1753
1764
  private:
1754
 
    virtual int do_postlock(Table **tables, uint32_t count)
 
1765
    virtual int do_postlock(TABLE **tables, uint count)
1755
1766
    {
1756
1767
      THD *thd= const_cast<THD*>(ptr->get_thd());
1757
1768
      if (int error= decide_logging_format(thd, &all_tables))
1758
1769
        return error;
1759
1770
 
1760
 
      Table const *const table = *tables;
 
1771
      TABLE const *const table = *tables;
1761
1772
      if (thd->current_stmt_binlog_row_based  &&
1762
1773
          !table->s->tmp_table &&
1763
1774
          !ptr->get_create_info()->table_existed)
1768
1779
    }
1769
1780
 
1770
1781
    select_create *ptr;
1771
 
    TableList all_tables;
 
1782
    TABLE_LIST all_tables;
1772
1783
  };
1773
1784
 
1774
1785
  MY_HOOKS hooks(this, create_table, select_tables);
1839
1850
}
1840
1851
 
1841
1852
void
1842
 
select_create::binlog_show_create_table(Table **tables, uint32_t count)
 
1853
select_create::binlog_show_create_table(TABLE **tables, uint count)
1843
1854
{
1844
1855
  /*
1845
1856
    Note 1: In RBR mode, we generate a CREATE TABLE statement for the
1864
1875
  char buf[2048];
1865
1876
  String query(buf, sizeof(buf), system_charset_info);
1866
1877
  int result;
1867
 
  TableList tmp_table_list;
 
1878
  TABLE_LIST tmp_table_list;
1868
1879
 
1869
1880
  memset(&tmp_table_list, 0, sizeof(tmp_table_list));
1870
1881
  tmp_table_list.table = *tables;
1885
1896
}
1886
1897
 
1887
1898
 
1888
 
void select_create::send_error(uint32_t errcode,const char *err)
 
1899
void select_create::send_error(uint errcode,const char *err)
1889
1900
{
1890
1901
  
1891
1902