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 */
17
17
/* Insert of records */
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/epoch.h>
28
#include <drizzled/field/timestamp.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>
34
#include <drizzled/select_insert.h>
35
#include <drizzled/select_create.h>
37
#include <drizzled/table/shell.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"
274
269
value_count= values->elements;
276
if (prepare_insert(session, table_list, table, fields, values,
271
if (mysql_prepare_insert(session, table_list, table, fields, values,
277
272
update_fields, update_values, duplic, &unused_conds,
279
274
(fields.elements || !value_count ||
280
275
(0) != 0), !ignore))
283
table->cursor->ha_release_auto_increment();
285
free_underlaid_joins(session, &session->getLex()->select_lex);
286
session->setAbortOnWarning(false);
287
DRIZZLE_INSERT_DONE(1, 0);
291
278
/* mysql_prepare_insert set table_list->table if it was not set */
292
279
table= table_list->table;
294
context= &session->getLex()->select_lex.context;
281
context= &session->lex->select_lex.context;
296
283
These three asserts test the hypothesis that the resetting of the name
297
284
resolution context below is not necessary at all since the list of local
317
304
if (values->elements != value_count)
319
306
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
322
table->cursor->ha_release_auto_increment();
324
free_underlaid_joins(session, &session->getLex()->select_lex);
325
session->setAbortOnWarning(false);
326
DRIZZLE_INSERT_DONE(1, 0);
330
309
if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
333
table->cursor->ha_release_auto_increment();
335
free_underlaid_joins(session, &session->getLex()->select_lex);
336
session->setAbortOnWarning(false);
337
DRIZZLE_INSERT_DONE(1, 0);
341
its= values_list.begin();
343
314
/* Restore the current context. */
344
315
ctx_state.restore_state(context, table_list);
480
452
table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
485
table->cursor->ha_release_auto_increment();
487
free_underlaid_joins(session, &session->getLex()->select_lex);
488
session->setAbortOnWarning(false);
489
DRIZZLE_INSERT_DONE(1, 0);
493
456
if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
494
457
!session->cuted_fields))
496
459
session->row_count_func= info.copied + info.deleted + info.updated;
497
session->my_ok((ulong) session->rowCount(),
460
session->my_ok((ulong) session->row_count_func,
498
461
info.copied + info.deleted + info.touched, id);
507
470
snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
508
471
(ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
509
472
session->row_count_func= info.copied + info.deleted + info.updated;
510
session->my_ok((ulong) session->rowCount(),
473
session->my_ok((ulong) session->row_count_func,
511
474
info.copied + info.deleted + info.touched, id, buff);
513
session->status_var.inserted_row_count+= session->rowCount();
514
session->setAbortOnWarning(false);
515
DRIZZLE_INSERT_DONE(0, session->rowCount());
476
session->status_var.inserted_row_count+= session->row_count_func;
477
session->abort_on_warning= 0;
478
DRIZZLE_INSERT_DONE(0, session->row_count_func);
483
table->cursor->ha_release_auto_increment();
485
free_underlaid_joins(session, &session->lex->select_lex);
486
session->abort_on_warning= 0;
487
DRIZZLE_INSERT_DONE(1, 0);
550
if (setup_tables_and_check_access(session, &session->getLex()->select_lex.context,
551
&session->getLex()->select_lex.top_join_list,
521
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
522
&session->lex->select_lex.top_join_list,
553
&session->getLex()->select_lex.leaf_tables,
524
&session->lex->select_lex.leaf_tables,
661
632
if (!res && check_fields)
663
bool saved_abort_on_warning= session->abortOnWarning();
665
session->setAbortOnWarning(abort_on_warning);
634
bool saved_abort_on_warning= session->abort_on_warning;
635
session->abort_on_warning= abort_on_warning;
666
636
res= check_that_all_fields_are_given_values(session,
668
638
context->table_list->table,
669
639
context->table_list);
670
session->setAbortOnWarning(saved_abort_on_warning);
640
session->abort_on_warning= saved_abort_on_warning;
673
643
if (!res && duplic == DUP_UPDATE)
823
key.resize(table->getShare()->max_unique_length);
792
if (!(key=(char*) malloc(table->getShare()->max_unique_length)))
825
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);
826
799
if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
827
&key[0], HA_WHOLE_KEY,
800
(unsigned char*) key, HA_WHOLE_KEY,
828
801
HA_READ_KEY_EXACT))))
965
941
info->last_errno= error;
966
942
/* current_select is NULL if this is a delayed insert */
967
if (session->getLex()->current_select)
968
session->getLex()->current_select->no_error= 0; // Give error
943
if (session->lex->current_select)
944
session->lex->current_select->no_error= 0; // Give error
969
945
table->print_error(error,MYF(0));
972
948
table->cursor->restore_auto_increment(prev_insert_id);
973
table->column_bitmaps_set(*save_read_set, *save_write_set);
951
table->column_bitmaps_set(save_read_set, save_write_set);
1072
1050
List<Item> *update_fields,
1073
1051
List<Item> *update_values,
1074
1052
enum_duplicates duplic,
1075
bool ignore_check_option_errors) :
1076
table_list(table_list_par), table(table_par), fields(fields_par),
1077
autoinc_value_of_last_inserted_row(0),
1078
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)
1058
memset(&info, 0, sizeof(info));
1080
1059
info.handle_duplicates= duplic;
1081
1060
info.ignore= ignore_check_option_errors;
1082
1061
info.update_fields= update_fields;
1099
1079
select, LEX::current_select should point to the first select while
1100
1080
we are fixing fields from insert list.
1102
session->getLex()->current_select= &session->getLex()->select_lex;
1082
lex->current_select= &lex->select_lex;
1103
1083
res= check_insert_fields(session, table_list, *fields, values,
1104
1084
!insert_into_view, &map) ||
1105
1085
setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0);
1107
1087
if (!res && fields->elements)
1109
bool saved_abort_on_warning= session->abortOnWarning();
1110
session->setAbortOnWarning(not info.ignore);
1089
bool saved_abort_on_warning= session->abort_on_warning;
1090
session->abort_on_warning= !info.ignore;
1111
1091
res= check_that_all_fields_are_given_values(session, table_list->table,
1113
session->setAbortOnWarning(saved_abort_on_warning);
1093
session->abort_on_warning= saved_abort_on_warning;
1116
1096
if (info.handle_duplicates == DUP_UPDATE && !res)
1118
Name_resolution_context *context= &session->getLex()->select_lex.context;
1098
Name_resolution_context *context= &lex->select_lex.context;
1119
1099
Name_resolution_context_state ctx_state;
1121
1101
/* Save the state of the current name resolution context. */
1133
1113
We use next_name_resolution_table descructively, so check it first (views?)
1135
1115
assert (!table_list->next_name_resolution_table);
1136
if (session->getLex()->select_lex.group_list.elements == 0 and
1137
not session->getLex()->select_lex.with_sum_func)
1116
if (lex->select_lex.group_list.elements == 0 &&
1117
!lex->select_lex.with_sum_func)
1139
1119
We must make a single context out of the two separate name resolution contexts :
1140
1120
the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
1183
1163
if (unique_table(table_list, table_list->next_global))
1185
1165
/* Using same table for INSERT and SELECT */
1186
session->getLex()->current_select->options|= OPTION_BUFFER_RESULT;
1187
session->getLex()->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1166
lex->current_select->options|= OPTION_BUFFER_RESULT;
1167
lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1189
else if (not (session->getLex()->current_select->options & OPTION_BUFFER_RESULT))
1169
else if (!(lex->current_select->options & OPTION_BUFFER_RESULT))
1192
1172
We must not yet prepare the result table if it is the same as one of the
1203
1183
table->next_number_field=table->found_next_number_field;
1205
1185
session->cuted_fields=0;
1207
1186
if (info.ignore || info.handle_duplicates != DUP_ERROR)
1208
1187
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1210
1188
if (info.handle_duplicates == DUP_REPLACE)
1211
1189
table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1213
1190
if (info.handle_duplicates == DUP_UPDATE)
1214
1191
table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1216
session->setAbortOnWarning(not info.ignore);
1192
session->abort_on_warning= !info.ignore;
1217
1193
table->mark_columns_needed_for_insert();
1270
1246
bool select_insert::send_data(List<Item> &values)
1275
1251
if (unit->offset_limit_cnt)
1276
1252
{ // using limit offset,count
1277
1253
unit->offset_limit_cnt--;
1281
1257
session->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
1282
1258
store_values(values);
1283
1259
session->count_cuted_fields= CHECK_FIELD_IGNORE;
1284
1260
if (session->is_error())
1287
1263
// Release latches in case bulk insert takes a long time
1288
1264
plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1383
1363
(session->arg_of_last_insert_id_function ?
1384
1364
session->first_successful_insert_id_in_prev_stmt :
1385
1365
(info.copied ? autoinc_value_of_last_inserted_row : 0));
1386
session->my_ok((ulong) session->rowCount(),
1366
session->my_ok((ulong) session->row_count_func,
1387
1367
info.copied + info.deleted + info.touched, id, buff);
1388
session->status_var.inserted_row_count+= session->rowCount();
1389
DRIZZLE_INSERT_SELECT_DONE(0, session->rowCount());
1368
session->status_var.inserted_row_count+= session->row_count_func;
1369
DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1488
1468
List<Item> *items,
1489
1469
bool is_if_not_exists,
1490
1470
DrizzleLock **lock,
1491
identifier::Table::const_reference identifier)
1471
TableIdentifier &identifier)
1473
Table tmp_table; // Used during 'CreateField()'
1493
1474
TableShare share(message::Table::INTERNAL);
1494
1476
uint32_t select_field_count= items->elements;
1495
1477
/* Add selected items to field list */
1496
List<Item>::iterator it(items->begin());
1478
List_iterator_fast<Item> it(*items);
1498
1480
Field *tmp_field;
1500
1483
if (not (identifier.isTmp()) && create_table->table->db_stat)
1505
1488
create_info->table_existed= 1; // Mark that table existed
1506
1489
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1507
1490
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1508
create_table->getTableName());
1491
create_table->table_name);
1509
1492
return create_table->table;
1512
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
1495
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1499
tmp_table.timestamp_field= 0;
1500
tmp_table.setShare(&share);
1502
tmp_table.getMutableShare()->db_create_options= 0;
1503
tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
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;
1510
tmp_table.null_row= false;
1511
tmp_table.maybe_null= false;
1517
table::Shell tmp_table(share); // Used during 'CreateField()'
1519
if (not table_proto.engine().name().compare("MyISAM"))
1520
tmp_table.getMutableShare()->db_low_byte_first= true;
1521
else if (not table_proto.engine().name().compare("MEMORY"))
1522
tmp_table.getMutableShare()->db_low_byte_first= true;
1524
tmp_table.in_use= session;
1528
CreateField *cr_field;
1529
Field *field, *def_field;
1530
if (item->type() == Item::FUNC_ITEM)
1532
if (item->result_type() != STRING_RESULT)
1534
field= item->tmp_table_field(&tmp_table);
1538
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
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);
1543
field= create_tmp_field(session, &tmp_table, item, item->type(),
1544
(Item ***) 0, &tmp_field, &def_field, false,
1549
!(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1550
((Item_field *)item)->field :
1556
if (item->maybe_null)
1558
cr_field->flags &= ~NOT_NULL_FLAG;
1561
alter_info->create_list.push_back(cr_field);
1521
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1523
field= create_tmp_field(session, &tmp_table, item, item->type(),
1524
(Item ***) 0, &tmp_field, &def_field, false,
1527
!(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1528
((Item_field *)item)->field :
1531
if (item->maybe_null)
1532
cr_field->flags &= ~NOT_NULL_FLAG;
1533
alter_info->create_list.push_back(cr_field);
1587
1557
or it was created via different mysqld front-end to the
1588
1558
cluster. We don't have much options but throw an error.
1590
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
1560
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1594
1564
if (not identifier.isTmp())
1596
/* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1597
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1599
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))
1601
table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1603
if (concurrent_table->reopen_name_locked_table(create_table, session))
1605
(void)plugin::StorageEngine::dropTable(*session, identifier);
1609
table= create_table->table;
1569
quick_rm_table(*session, identifier);
1614
(void)plugin::StorageEngine::dropTable(*session, identifier);
1572
table= create_table->table;
1625
1583
it preparable for open. But let us do close_temporary_table() here
1628
session->drop_temporary_table(identifier);
1586
session->drop_temporary_table(create_table);
1632
if (not table) // open failed
1590
if (!table) // open failed
1636
1594
table->reginfo.lock_type=TL_WRITE;
1637
if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
1595
if (! ((*lock)= mysql_lock_tables(session, &table, 1,
1596
DRIZZLE_LOCK_IGNORE_FLUSH, ¬_used)))
1641
session->unlockTables(*lock);
1600
mysql_unlock_tables(session, *lock);
1645
1604
if (not create_info->table_existed)
1646
1605
session->drop_open_table(table, identifier);
1712
1668
session->cuted_fields=0;
1713
1669
if (info.ignore || info.handle_duplicates != DUP_ERROR)
1714
1670
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1716
1671
if (info.handle_duplicates == DUP_REPLACE)
1717
1672
table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1719
1673
if (info.handle_duplicates == DUP_UPDATE)
1720
1674
table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1722
1675
table->cursor->ha_start_bulk_insert((ha_rows) 0);
1723
session->setAbortOnWarning(not info.ignore);
1676
session->abort_on_warning= !info.ignore;
1724
1677
if (check_that_all_fields_are_given_values(session, table, table_list))
1727
1679
table->mark_columns_needed_for_insert();
1728
1680
table->cursor->extra(HA_EXTRA_WRITE_CACHE);