~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Brian Aker
  • Date: 2011-02-17 10:09:00 UTC
  • mfrom: (2173.2.1 clean-include-usuage)
  • Revision ID: brian@tangent.org-20110217100900-4tpuxxzdl1sj00sh
Merge Monty for headers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Insert of records */
18
18
 
19
 
#include "config.h"
 
19
#include <config.h>
20
20
#include <cstdio>
21
21
#include <drizzled/sql_select.h>
22
22
#include <drizzled/show.h>
25
25
#include <drizzled/probes.h>
26
26
#include <drizzled/sql_base.h>
27
27
#include <drizzled/sql_load.h>
28
 
#include <drizzled/field/timestamp.h>
 
28
#include <drizzled/field/epoch.h>
29
29
#include <drizzled/lock.h>
30
 
#include "drizzled/sql_table.h"
31
 
#include "drizzled/pthread_globals.h"
32
 
#include "drizzled/transaction_services.h"
33
 
#include "drizzled/plugin/transactional_storage_engine.h"
 
30
#include <drizzled/sql_table.h>
 
31
#include <drizzled/pthread_globals.h>
 
32
#include <drizzled/transaction_services.h>
 
33
#include <drizzled/plugin/transactional_storage_engine.h>
 
34
#include <drizzled/select_insert.h>
 
35
#include <drizzled/select_create.h>
34
36
 
35
 
#include "drizzled/table/shell.h"
 
37
#include <drizzled/table/shell.h>
36
38
 
37
39
namespace drizzled
38
40
{
227
229
  end of dispatch_command().
228
230
*/
229
231
 
230
 
bool mysql_insert(Session *session,TableList *table_list,
 
232
bool insert_query(Session *session,TableList *table_list,
231
233
                  List<Item> &fields,
232
234
                  List<List_item> &values_list,
233
235
                  List<Item> &update_fields,
271
273
  values= its++;
272
274
  value_count= values->elements;
273
275
 
274
 
  if (mysql_prepare_insert(session, table_list, table, fields, values,
 
276
  if (prepare_insert(session, table_list, table, fields, values,
275
277
                           update_fields, update_values, duplic, &unused_conds,
276
278
                           false,
277
279
                           (fields.elements || !value_count ||
281
283
      table->cursor->ha_release_auto_increment();
282
284
    if (!joins_freed)
283
285
      free_underlaid_joins(session, &session->lex->select_lex);
284
 
    session->abort_on_warning= 0;
 
286
    session->setAbortOnWarning(false);
285
287
    DRIZZLE_INSERT_DONE(1, 0);
286
288
    return true;
287
289
  }
320
322
        table->cursor->ha_release_auto_increment();
321
323
      if (!joins_freed)
322
324
        free_underlaid_joins(session, &session->lex->select_lex);
323
 
      session->abort_on_warning= 0;
 
325
      session->setAbortOnWarning(false);
324
326
      DRIZZLE_INSERT_DONE(1, 0);
325
327
 
326
328
      return true;
331
333
        table->cursor->ha_release_auto_increment();
332
334
      if (!joins_freed)
333
335
        free_underlaid_joins(session, &session->lex->select_lex);
334
 
      session->abort_on_warning= 0;
 
336
      session->setAbortOnWarning(false);
335
337
      DRIZZLE_INSERT_DONE(1, 0);
336
338
      return true;
337
339
    }
372
374
  }
373
375
 
374
376
 
375
 
  session->abort_on_warning= !ignore;
 
377
  session->setAbortOnWarning(not ignore);
376
378
 
377
379
  table->mark_columns_needed_for_insert();
378
380
 
483
485
      table->cursor->ha_release_auto_increment();
484
486
    if (!joins_freed)
485
487
      free_underlaid_joins(session, &session->lex->select_lex);
486
 
    session->abort_on_warning= 0;
 
488
    session->setAbortOnWarning(false);
487
489
    DRIZZLE_INSERT_DONE(1, 0);
488
490
    return true;
489
491
  }
492
494
                                    !session->cuted_fields))
493
495
  {
494
496
    session->row_count_func= info.copied + info.deleted + info.updated;
495
 
    session->my_ok((ulong) session->row_count_func,
 
497
    session->my_ok((ulong) session->rowCount(),
496
498
                   info.copied + info.deleted + info.touched, id);
497
499
  }
498
500
  else
505
507
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
506
508
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
507
509
    session->row_count_func= info.copied + info.deleted + info.updated;
508
 
    session->my_ok((ulong) session->row_count_func,
 
510
    session->my_ok((ulong) session->rowCount(),
509
511
                   info.copied + info.deleted + info.touched, id, buff);
510
512
  }
511
 
  session->status_var.inserted_row_count+= session->row_count_func;
512
 
  session->abort_on_warning= 0;
513
 
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
 
513
  session->status_var.inserted_row_count+= session->rowCount();
 
514
  session->setAbortOnWarning(false);
 
515
  DRIZZLE_INSERT_DONE(0, session->rowCount());
514
516
 
515
517
  return false;
516
518
}
520
522
  Check if table can be updated
521
523
 
522
524
  SYNOPSIS
523
 
     mysql_prepare_insert_check_table()
 
525
     prepare_insert_check_table()
524
526
     session            Thread handle
525
527
     table_list         Table list
526
528
     fields             List of fields to be updated
532
534
     true  ERROR
533
535
*/
534
536
 
535
 
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
 
537
static bool prepare_insert_check_table(Session *session, TableList *table_list,
536
538
                                             List<Item> &,
537
539
                                             bool select_insert)
538
540
{
560
562
  Prepare items in INSERT statement
561
563
 
562
564
  SYNOPSIS
563
 
    mysql_prepare_insert()
 
565
    prepare_insert()
564
566
    session                     Thread handler
565
567
    table_list          Global/local table list
566
568
    table               Table to insert into (can be NULL if table should
587
589
    true  error
588
590
*/
589
591
 
590
 
bool mysql_prepare_insert(Session *session, TableList *table_list,
 
592
bool prepare_insert(Session *session, TableList *table_list,
591
593
                          Table *table, List<Item> &fields, List_item *values,
592
594
                          List<Item> &update_fields, List<Item> &update_values,
593
595
                          enum_duplicates duplic,
610
612
    inserting (for INSERT ... SELECT this is done by changing table_list,
611
613
    because INSERT ... SELECT share Select_Lex it with SELECT.
612
614
  */
613
 
  if (!select_insert)
 
615
  if (not select_insert)
614
616
  {
615
617
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
616
618
         un;
632
634
      return(true);
633
635
  }
634
636
 
635
 
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
 
637
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
636
638
    return(true);
637
639
 
638
640
 
658
660
 
659
661
    if (!res && check_fields)
660
662
    {
661
 
      bool saved_abort_on_warning= session->abort_on_warning;
662
 
      session->abort_on_warning= abort_on_warning;
 
663
      bool saved_abort_on_warning= session->abortOnWarning();
 
664
 
 
665
      session->setAbortOnWarning(abort_on_warning);
663
666
      res= check_that_all_fields_are_given_values(session,
664
667
                                                  table ? table :
665
668
                                                  context->table_list->table,
666
669
                                                  context->table_list);
667
 
      session->abort_on_warning= saved_abort_on_warning;
 
670
      session->setAbortOnWarning(saved_abort_on_warning);
668
671
    }
669
672
 
670
673
    if (!res && duplic == DUP_UPDATE)
675
678
    /* Restore the current context. */
676
679
    ctx_state.restore_state(context, table_list);
677
680
 
678
 
    if (!res)
 
681
    if (not res)
679
682
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
680
683
  }
681
684
 
682
685
  if (res)
683
686
    return(res);
684
687
 
685
 
  if (!table)
 
688
  if (not table)
686
689
    table= table_list->table;
687
690
 
688
 
  if (!select_insert)
 
691
  if (not select_insert)
689
692
  {
690
693
    TableList *duplicate;
691
694
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
695
698
      return true;
696
699
    }
697
700
  }
 
701
 
698
702
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
699
703
    table->prepare_for_position();
700
704
 
868
872
          /*
869
873
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
870
874
            like a regular UPDATE statement: it should not affect the value of a
871
 
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
 
875
            next SELECT LAST_INSERT_ID() or insert_id().
872
876
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
873
877
            handled separately by Session::arg_of_last_insert_id_function.
874
878
          */
1014
1018
      }
1015
1019
    }
1016
1020
  }
1017
 
  return session->abort_on_warning ? err : 0;
 
1021
  return session->abortOnWarning() ? err : 0;
1018
1022
}
1019
1023
 
1020
1024
/***************************************************************************
1026
1030
  make insert specific preparation and checks after opening tables
1027
1031
 
1028
1032
  SYNOPSIS
1029
 
    mysql_insert_select_prepare()
 
1033
    insert_select_prepare()
1030
1034
    session         thread handler
1031
1035
 
1032
1036
  RETURN
1034
1038
    true  Error
1035
1039
*/
1036
1040
 
1037
 
bool mysql_insert_select_prepare(Session *session)
 
1041
bool insert_select_prepare(Session *session)
1038
1042
{
1039
1043
  LEX *lex= session->lex;
1040
1044
  Select_Lex *select_lex= &lex->select_lex;
1044
1048
    clause if table is VIEW
1045
1049
  */
1046
1050
 
1047
 
  if (mysql_prepare_insert(session, lex->query_tables,
 
1051
  if (prepare_insert(session, lex->query_tables,
1048
1052
                           lex->query_tables->table, lex->field_list, 0,
1049
1053
                           lex->update_list, lex->value_list,
1050
1054
                           lex->duplicates,
1103
1107
 
1104
1108
  if (!res && fields->elements)
1105
1109
  {
1106
 
    bool saved_abort_on_warning= session->abort_on_warning;
1107
 
    session->abort_on_warning= !info.ignore;
 
1110
    bool saved_abort_on_warning= session->abortOnWarning();
 
1111
    session->setAbortOnWarning(not info.ignore);
1108
1112
    res= check_that_all_fields_are_given_values(session, table_list->table,
1109
1113
                                                table_list);
1110
 
    session->abort_on_warning= saved_abort_on_warning;
 
1114
    session->setAbortOnWarning(saved_abort_on_warning);
1111
1115
  }
1112
1116
 
1113
1117
  if (info.handle_duplicates == DUP_UPDATE && !res)
1200
1204
  table->next_number_field=table->found_next_number_field;
1201
1205
 
1202
1206
  session->cuted_fields=0;
 
1207
 
1203
1208
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1204
1209
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
1210
 
1205
1211
  if (info.handle_duplicates == DUP_REPLACE)
1206
1212
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
 
1213
 
1207
1214
  if (info.handle_duplicates == DUP_UPDATE)
1208
1215
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1209
 
  session->abort_on_warning= !info.ignore;
 
1216
 
 
1217
  session->setAbortOnWarning(not info.ignore);
1210
1218
  table->mark_columns_needed_for_insert();
1211
1219
 
1212
1220
 
1255
1263
    table->cursor->ha_reset();
1256
1264
  }
1257
1265
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1258
 
  session->abort_on_warning= 0;
 
1266
  session->setAbortOnWarning(false);
1259
1267
  return;
1260
1268
}
1261
1269
 
1268
1276
  if (unit->offset_limit_cnt)
1269
1277
  {                                             // using limit offset,count
1270
1278
    unit->offset_limit_cnt--;
1271
 
    return(0);
 
1279
    return false;
1272
1280
  }
1273
1281
 
1274
1282
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1275
1283
  store_values(values);
1276
1284
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1277
1285
  if (session->is_error())
1278
 
    return(1);
 
1286
    return true;
1279
1287
 
1280
1288
  // Release latches in case bulk insert takes a long time
1281
1289
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1325
1333
    fill_record(session, table->getFields(), values, true);
1326
1334
}
1327
1335
 
1328
 
void select_insert::send_error(uint32_t errcode,const char *err)
 
1336
void select_insert::send_error(drizzled::error_t errcode,const char *err)
1329
1337
{
1330
 
 
1331
 
 
1332
1338
  my_message(errcode, err, MYF(0));
1333
 
 
1334
 
  return;
1335
1339
}
1336
1340
 
1337
1341
 
1380
1384
    (session->arg_of_last_insert_id_function ?
1381
1385
     session->first_successful_insert_id_in_prev_stmt :
1382
1386
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1383
 
  session->my_ok((ulong) session->row_count_func,
 
1387
  session->my_ok((ulong) session->rowCount(),
1384
1388
                 info.copied + info.deleted + info.touched, id, buff);
1385
 
  session->status_var.inserted_row_count+= session->row_count_func; 
1386
 
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
 
1389
  session->status_var.inserted_row_count+= session->rowCount(); 
 
1390
  DRIZZLE_INSERT_SELECT_DONE(0, session->rowCount());
1387
1391
  return 0;
1388
1392
}
1389
1393
 
1485
1489
                                      List<Item> *items,
1486
1490
                                      bool is_if_not_exists,
1487
1491
                                      DrizzleLock **lock,
1488
 
                                      TableIdentifier &identifier)
 
1492
                                      identifier::Table::const_reference identifier)
1489
1493
{
1490
1494
  TableShare share(message::Table::INTERNAL);
1491
1495
  uint32_t select_field_count= items->elements;
1493
1497
  List_iterator_fast<Item> it(*items);
1494
1498
  Item *item;
1495
1499
  Field *tmp_field;
1496
 
  bool not_used;
1497
1500
 
1498
1501
  if (not (identifier.isTmp()) && create_table->table->db_stat)
1499
1502
  {
1513
1516
 
1514
1517
  {
1515
1518
    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
1519
 
1521
1520
    if (not table_proto.engine().name().compare("MyISAM"))
1522
1521
      tmp_table.getMutableShare()->db_low_byte_first= true;
1523
1522
    else if (not table_proto.engine().name().compare("MEMORY"))
1524
1523
      tmp_table.getMutableShare()->db_low_byte_first= true;
1525
1524
 
1526
 
    tmp_table.null_row= false;
1527
 
    tmp_table.maybe_null= false;
1528
 
 
1529
1525
    tmp_table.in_use= session;
1530
1526
 
1531
1527
    while ((item=it++))
1576
1572
  */
1577
1573
  Table *table= 0;
1578
1574
  {
1579
 
    if (not mysql_create_table_no_lock(session,
1580
 
                                       identifier,
1581
 
                                       create_info,
1582
 
                                       table_proto,
1583
 
                                       alter_info,
1584
 
                                       false,
1585
 
                                       select_field_count,
1586
 
                                       is_if_not_exists))
 
1575
    if (not create_table_no_lock(session,
 
1576
                                 identifier,
 
1577
                                 create_info,
 
1578
                                 table_proto,
 
1579
                                 alter_info,
 
1580
                                 false,
 
1581
                                 select_field_count,
 
1582
                                 is_if_not_exists))
1587
1583
    {
1588
1584
      if (create_info->table_existed && not identifier.isTmp())
1589
1585
      {
1607
1603
 
1608
1604
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1609
1605
          {
1610
 
            plugin::StorageEngine::dropTable(*session, identifier);
 
1606
            (void)plugin::StorageEngine::dropTable(*session, identifier);
1611
1607
          }
1612
1608
          else
1613
1609
          {
1616
1612
        }
1617
1613
        else
1618
1614
        {
1619
 
          plugin::StorageEngine::dropTable(*session, identifier);
 
1615
          (void)plugin::StorageEngine::dropTable(*session, identifier);
1620
1616
        }
1621
1617
      }
1622
1618
      else
1639
1635
  }
1640
1636
 
1641
1637
  table->reginfo.lock_type=TL_WRITE;
1642
 
  if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
 
1638
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
1643
1639
  {
1644
1640
    if (*lock)
1645
1641
    {
1649
1645
 
1650
1646
    if (not create_info->table_existed)
1651
1647
      session->drop_open_table(table, identifier);
 
1648
 
1652
1649
    return NULL;
1653
1650
  }
1654
1651
 
1716
1713
  session->cuted_fields=0;
1717
1714
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1718
1715
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
1716
 
1719
1717
  if (info.handle_duplicates == DUP_REPLACE)
1720
1718
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
 
1719
 
1721
1720
  if (info.handle_duplicates == DUP_UPDATE)
1722
1721
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
 
1722
 
1723
1723
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1724
 
  session->abort_on_warning= !info.ignore;
 
1724
  session->setAbortOnWarning(not info.ignore);
1725
1725
  if (check_that_all_fields_are_given_values(session, table, table_list))
1726
1726
    return(1);
 
1727
 
1727
1728
  table->mark_columns_needed_for_insert();
1728
1729
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1729
1730
  return(0);
1735
1736
}
1736
1737
 
1737
1738
 
1738
 
void select_create::send_error(uint32_t errcode,const char *err)
 
1739
void select_create::send_error(drizzled::error_t errcode,const char *err)
1739
1740
{
1740
1741
  /*
1741
1742
    This will execute any rollbacks that are necessary before writing
1749
1750
 
1750
1751
  */
1751
1752
  select_insert::send_error(errcode, err);
1752
 
 
1753
 
  return;
1754
1753
}
1755
1754
 
1756
1755
 
1769
1768
    if (!table->getShare()->getType())
1770
1769
    {
1771
1770
      TransactionServices &transaction_services= TransactionServices::singleton();
1772
 
      transaction_services.autocommitOrRollback(session, 0);
 
1771
      transaction_services.autocommitOrRollback(*session, 0);
1773
1772
      (void) session->endActiveTransaction();
1774
1773
    }
1775
1774