~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Lee Bieber
  • Date: 2010-12-15 16:23:36 UTC
  • mfrom: (1995.1.2 build)
  • Revision ID: kalebral@gmail.com-20101215162336-juntyt4gw4vgohg4
Merge Andrew - fix bug 628912: Crash / segfault in drizzled::Item_func::arguments (this=0x35) at ./drizzled/function/func.h
Merge Andrew - 663919: next query after KILL QUERY will error

Show diffs side-by-side

added added

removed removed

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