~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Brian Aker
  • Date: 2010-09-12 01:42:27 UTC
  • mto: (1759.2.1 build)
  • mto: This revision was merged to the branch mainline in revision 1762.
  • Revision ID: brian@tangent.org-20100912014227-krt6d9z5ohqrokhb
Add two plugins to handle the string and math functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Insert of records */
32
32
#include "drizzled/transaction_services.h"
33
33
#include "drizzled/plugin/transactional_storage_engine.h"
34
34
 
35
 
#include "drizzled/table/shell.h"
36
 
 
37
35
namespace drizzled
38
36
{
39
37
 
129
127
      }
130
128
      else
131
129
      {
132
 
        table->setWriteSet(table->timestamp_field->position());
 
130
        table->setWriteSet(table->timestamp_field->field_index);
133
131
      }
134
132
    }
135
133
  }
170
168
      Unmark the timestamp field so that we can check if this is modified
171
169
      by update_fields
172
170
    */
173
 
    timestamp_mark= table->write_set->test(table->timestamp_field->position());
174
 
    table->write_set->reset(table->timestamp_field->position());
 
171
    timestamp_mark= table->write_set->testAndClear(table->timestamp_field->field_index);
175
172
  }
176
173
 
177
174
  /* Check the fields we are going to modify */
189
186
 
190
187
    if (timestamp_mark)
191
188
    {
192
 
      table->setWriteSet(table->timestamp_field->position());
 
189
      table->setWriteSet(table->timestamp_field->field_index);
193
190
    }
194
191
  }
195
192
  return 0;
276
273
                           false,
277
274
                           (fields.elements || !value_count ||
278
275
                            (0) != 0), !ignore))
279
 
  {
280
 
    if (table != NULL)
281
 
      table->cursor->ha_release_auto_increment();
282
 
    if (!joins_freed)
283
 
      free_underlaid_joins(session, &session->lex->select_lex);
284
 
    session->abort_on_warning= 0;
285
 
    DRIZZLE_INSERT_DONE(1, 0);
286
 
    return true;
287
 
  }
 
276
    goto abort;
288
277
 
289
278
  /* mysql_prepare_insert set table_list->table if it was not set */
290
279
  table= table_list->table;
315
304
    if (values->elements != value_count)
316
305
    {
317
306
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
318
 
 
319
 
      if (table != NULL)
320
 
        table->cursor->ha_release_auto_increment();
321
 
      if (!joins_freed)
322
 
        free_underlaid_joins(session, &session->lex->select_lex);
323
 
      session->abort_on_warning= 0;
324
 
      DRIZZLE_INSERT_DONE(1, 0);
325
 
 
326
 
      return true;
 
307
      goto abort;
327
308
    }
328
309
    if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
329
 
    {
330
 
      if (table != NULL)
331
 
        table->cursor->ha_release_auto_increment();
332
 
      if (!joins_freed)
333
 
        free_underlaid_joins(session, &session->lex->select_lex);
334
 
      session->abort_on_warning= 0;
335
 
      DRIZZLE_INSERT_DONE(1, 0);
336
 
      return true;
337
 
    }
 
310
      goto abort;
338
311
  }
339
312
  its.rewind ();
340
313
 
344
317
  /*
345
318
    Fill in the given fields and dump it to the table cursor
346
319
  */
 
320
  memset(&info, 0, sizeof(info));
347
321
  info.ignore= ignore;
348
322
  info.handle_duplicates=duplic;
349
323
  info.update_fields= &update_fields;
478
452
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
479
453
 
480
454
  if (error)
481
 
  {
482
 
    if (table != NULL)
483
 
      table->cursor->ha_release_auto_increment();
484
 
    if (!joins_freed)
485
 
      free_underlaid_joins(session, &session->lex->select_lex);
486
 
    session->abort_on_warning= 0;
487
 
    DRIZZLE_INSERT_DONE(1, 0);
488
 
    return true;
489
 
  }
490
 
 
 
455
    goto abort;
491
456
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
492
457
                                    !session->cuted_fields))
493
458
  {
511
476
  session->status_var.inserted_row_count+= session->row_count_func;
512
477
  session->abort_on_warning= 0;
513
478
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
514
 
 
515
479
  return false;
 
480
 
 
481
abort:
 
482
  if (table != NULL)
 
483
    table->cursor->ha_release_auto_increment();
 
484
  if (!joins_freed)
 
485
    free_underlaid_joins(session, &session->lex->select_lex);
 
486
  session->abort_on_warning= 0;
 
487
  DRIZZLE_INSERT_DONE(1, 0);
 
488
  return true;
516
489
}
517
490
 
518
491
 
743
716
int write_record(Session *session, Table *table,CopyInfo *info)
744
717
{
745
718
  int error;
746
 
  std::vector<unsigned char> key;
747
 
  boost::dynamic_bitset<> *save_read_set, *save_write_set;
 
719
  char *key=0;
 
720
  MyBitmap *save_read_set, *save_write_set;
748
721
  uint64_t prev_insert_id= table->cursor->next_insert_id;
749
722
  uint64_t insert_id_for_cur_row= 0;
750
723
 
814
787
          goto err;
815
788
        }
816
789
 
817
 
        if (not key.size())
 
790
        if (!key)
818
791
        {
819
 
          key.resize(table->getShare()->max_unique_length);
 
792
          if (!(key=(char*) malloc(table->getShare()->max_unique_length)))
 
793
          {
 
794
            error=ENOMEM;
 
795
            goto err;
 
796
          }
820
797
        }
821
 
        key_copy(&key[0], table->getInsertRecord(), table->key_info+key_nr, 0);
 
798
        key_copy((unsigned char*) key,table->getInsertRecord(),table->key_info+key_nr,0);
822
799
        if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
823
 
                                                    &key[0], HA_WHOLE_KEY,
 
800
                                                    (unsigned char*) key, HA_WHOLE_KEY,
824
801
                                                    HA_READ_KEY_EXACT))))
825
802
          goto err;
826
803
      }
846
823
          table->cursor->adjust_next_insert_id_after_explicit_value(
847
824
            table->next_number_field->val_int());
848
825
        info->touched++;
849
 
 
850
 
        if (! table->records_are_comparable() || table->compare_records())
 
826
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
827
             !bitmap_is_subset(table->write_set, table->read_set)) ||
 
828
            table->compare_record())
851
829
        {
852
830
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
853
831
                                                table->getInsertRecord())) &&
937
915
    */
938
916
    if (table->read_set != save_read_set ||
939
917
        table->write_set != save_write_set)
940
 
      table->column_bitmaps_set(*save_read_set, *save_write_set);
 
918
      table->column_bitmaps_set(save_read_set, save_write_set);
941
919
  }
942
920
  else if ((error=table->cursor->insertRecord(table->getInsertRecord())))
943
921
  {
953
931
  session->record_first_successful_insert_id_in_cur_stmt(table->cursor->insert_id_for_cur_row);
954
932
 
955
933
gok_or_after_err:
 
934
  if (key)
 
935
    free(key);
956
936
  if (!table->cursor->has_transactions())
957
937
    session->transaction.stmt.markModifiedNonTransData();
958
938
  return(0);
966
946
 
967
947
before_err:
968
948
  table->cursor->restore_auto_increment(prev_insert_id);
969
 
  table->column_bitmaps_set(*save_read_set, *save_write_set);
970
 
  return 1;
 
949
  if (key)
 
950
    free(key);
 
951
  table->column_bitmaps_set(save_read_set, save_write_set);
 
952
  return(1);
971
953
}
972
954
 
973
955
 
1068
1050
                             List<Item> *update_fields,
1069
1051
                             List<Item> *update_values,
1070
1052
                             enum_duplicates duplic,
1071
 
                             bool ignore_check_option_errors) :
1072
 
  table_list(table_list_par), table(table_par), fields(fields_par),
1073
 
  autoinc_value_of_last_inserted_row(0),
1074
 
  insert_into_view(table_list_par && 0 != 0)
 
1053
                             bool ignore_check_option_errors)
 
1054
  :table_list(table_list_par), table(table_par), fields(fields_par),
 
1055
   autoinc_value_of_last_inserted_row(0),
 
1056
   insert_into_view(table_list_par && 0 != 0)
1075
1057
{
 
1058
  memset(&info, 0, sizeof(info));
1076
1059
  info.handle_duplicates= duplic;
1077
1060
  info.ignore= ignore_check_option_errors;
1078
1061
  info.update_fields= update_fields;
1487
1470
                                      DrizzleLock **lock,
1488
1471
                                      TableIdentifier &identifier)
1489
1472
{
 
1473
  Table tmp_table;              // Used during 'CreateField()'
1490
1474
  TableShare share(message::Table::INTERNAL);
 
1475
  Table *table= 0;
1491
1476
  uint32_t select_field_count= items->elements;
1492
1477
  /* Add selected items to field list */
1493
1478
  List_iterator_fast<Item> it(*items);
1503
1488
      create_info->table_existed= 1;            // Mark that table existed
1504
1489
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1505
1490
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1506
 
                          create_table->getTableName());
 
1491
                          create_table->table_name);
1507
1492
      return create_table->table;
1508
1493
    }
1509
1494
 
1510
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1495
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1511
1496
    return NULL;
1512
1497
  }
1513
1498
 
 
1499
  tmp_table.timestamp_field= 0;
 
1500
  tmp_table.setShare(&share);
 
1501
 
 
1502
  tmp_table.getMutableShare()->db_create_options= 0;
 
1503
  tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
 
1504
 
 
1505
  if (not table_proto.engine().name().compare("MyISAM"))
 
1506
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1507
  else if (not table_proto.engine().name().compare("MEMORY"))
 
1508
    tmp_table.getMutableShare()->db_low_byte_first= true;
 
1509
 
 
1510
  tmp_table.null_row= false;
 
1511
  tmp_table.maybe_null= false;
 
1512
 
 
1513
  while ((item=it++))
1514
1514
  {
1515
 
    table::Shell tmp_table(share);              // Used during 'CreateField()'
1516
 
    tmp_table.timestamp_field= 0;
1517
 
 
1518
 
    tmp_table.getMutableShare()->db_create_options= 0;
1519
 
    tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1520
 
 
1521
 
    if (not table_proto.engine().name().compare("MyISAM"))
1522
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1523
 
    else if (not table_proto.engine().name().compare("MEMORY"))
1524
 
      tmp_table.getMutableShare()->db_low_byte_first= true;
1525
 
 
1526
 
    tmp_table.null_row= false;
1527
 
    tmp_table.maybe_null= false;
1528
 
 
1529
 
    tmp_table.in_use= session;
1530
 
 
1531
 
    while ((item=it++))
1532
 
    {
1533
 
      CreateField *cr_field;
1534
 
      Field *field, *def_field;
1535
 
      if (item->type() == Item::FUNC_ITEM)
1536
 
      {
1537
 
        if (item->result_type() != STRING_RESULT)
1538
 
        {
1539
 
          field= item->tmp_table_field(&tmp_table);
1540
 
        }
1541
 
        else
1542
 
        {
1543
 
          field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1544
 
        }
1545
 
      }
 
1515
    CreateField *cr_field;
 
1516
    Field *field, *def_field;
 
1517
    if (item->type() == Item::FUNC_ITEM)
 
1518
      if (item->result_type() != STRING_RESULT)
 
1519
        field= item->tmp_table_field(&tmp_table);
1546
1520
      else
1547
 
      {
1548
 
        field= create_tmp_field(session, &tmp_table, item, item->type(),
1549
 
                                (Item ***) 0, &tmp_field, &def_field, false,
1550
 
                                false, false, 0);
1551
 
      }
1552
 
 
1553
 
      if (!field ||
1554
 
          !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1555
 
                                            ((Item_field *)item)->field :
1556
 
                                            (Field*) 0))))
1557
 
      {
1558
 
        return NULL;
1559
 
      }
1560
 
 
1561
 
      if (item->maybe_null)
1562
 
      {
1563
 
        cr_field->flags &= ~NOT_NULL_FLAG;
1564
 
      }
1565
 
 
1566
 
      alter_info->create_list.push_back(cr_field);
1567
 
    }
 
1521
        field= item->tmp_table_field_from_field_type(&tmp_table, 0);
 
1522
    else
 
1523
      field= create_tmp_field(session, &tmp_table, item, item->type(),
 
1524
                              (Item ***) 0, &tmp_field, &def_field, false,
 
1525
                              false, false, 0);
 
1526
    if (!field ||
 
1527
        !(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
 
1528
                                           ((Item_field *)item)->field :
 
1529
                                           (Field*) 0))))
 
1530
      return NULL;
 
1531
    if (item->maybe_null)
 
1532
      cr_field->flags &= ~NOT_NULL_FLAG;
 
1533
    alter_info->create_list.push_back(cr_field);
1568
1534
  }
1569
1535
 
1570
1536
  /*
1574
1540
    creating base table on which name we have exclusive lock. So code below
1575
1541
    should not cause deadlocks or races.
1576
1542
  */
1577
 
  Table *table= 0;
1578
1543
  {
1579
1544
    if (not mysql_create_table_no_lock(session,
1580
1545
                                       identifier,
1592
1557
          or it was created via different mysqld front-end to the
1593
1558
          cluster. We don't have much options but throw an error.
1594
1559
        */
1595
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1560
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1596
1561
        return NULL;
1597
1562
      }
1598
1563
 
1599
1564
      if (not identifier.isTmp())
1600
1565
      {
1601
 
        /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1602
 
        boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1603
 
 
1604
 
        if (create_table->table)
 
1566
        LOCK_open.lock(); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1567
        if (session->reopen_name_locked_table(create_table, false))
1605
1568
        {
1606
 
          table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1607
 
 
1608
 
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1609
 
          {
1610
 
            plugin::StorageEngine::dropTable(*session, identifier);
1611
 
          }
1612
 
          else
1613
 
          {
1614
 
            table= create_table->table;
1615
 
          }
 
1569
          quick_rm_table(*session, identifier);
1616
1570
        }
1617
1571
        else
1618
 
        {
1619
 
          plugin::StorageEngine::dropTable(*session, identifier);
1620
 
        }
 
1572
          table= create_table->table;
 
1573
        LOCK_open.unlock();
1621
1574
      }
1622
1575
      else
1623
1576
      {
1630
1583
            it preparable for open. But let us do close_temporary_table() here
1631
1584
            just in case.
1632
1585
          */
1633
 
          session->drop_temporary_table(identifier);
 
1586
          session->drop_temporary_table(create_table);
1634
1587
        }
1635
1588
      }
1636
1589
    }
1637
 
    if (not table)                                   // open failed
 
1590
    if (!table)                                   // open failed
1638
1591
      return NULL;
1639
1592
  }
1640
1593
 
1641
1594
  table->reginfo.lock_type=TL_WRITE;
1642
 
  if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
 
1595
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1596
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1643
1597
  {
1644
1598
    if (*lock)
1645
1599
    {
1646
 
      session->unlockTables(*lock);
 
1600
      mysql_unlock_tables(session, *lock);
1647
1601
      *lock= 0;
1648
1602
    }
1649
1603
 
1704
1658
 
1705
1659
  /* Mark all fields that are given values */
1706
1660
  for (Field **f= field ; *f ; f++)
1707
 
  {
1708
 
    table->setWriteSet((*f)->position());
1709
 
  }
 
1661
    table->setWriteSet((*f)->field_index);
1710
1662
 
1711
1663
  /* Don't set timestamp if used */
1712
1664
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1777
1729
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1778
1730
    if (m_plock)
1779
1731
    {
1780
 
      session->unlockTables(*m_plock);
 
1732
      mysql_unlock_tables(session, *m_plock);
1781
1733
      *m_plock= NULL;
1782
1734
      m_plock= NULL;
1783
1735
    }
1807
1759
 
1808
1760
  if (m_plock)
1809
1761
  {
1810
 
    session->unlockTables(*m_plock);
 
1762
    mysql_unlock_tables(session, *m_plock);
1811
1763
    *m_plock= NULL;
1812
1764
    m_plock= NULL;
1813
1765
  }