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"
35
#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>
34
#include <drizzled/select_insert.h>
35
#include <drizzled/select_create.h>
36
#include <drizzled/table/shell.h>
37
#include <drizzled/alter_info.h>
38
#include <drizzled/sql_parse.h>
39
#include <drizzled/sql_lex.h>
40
#include <drizzled/statistics_variables.h>
41
#include <drizzled/session/transactions.h>
40
45
extern plugin::StorageEngine *heap_engine;
41
46
extern plugin::StorageEngine *myisam_engine;
69
74
Table *table= table_list->table;
71
if (fields.elements == 0 && values.elements != 0)
76
if (fields.size() == 0 && values.size() != 0)
73
if (values.elements != table->getShare()->sizeFields())
78
if (values.size() != table->getShare()->sizeFields())
75
80
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
87
92
{ // Part field list
88
Select_Lex *select_lex= &session->lex->select_lex;
93
Select_Lex *select_lex= &session->lex().select_lex;
89
94
Name_resolution_context *context= &select_lex->context;
90
95
Name_resolution_context_state ctx_state;
93
if (fields.elements != values.elements)
98
if (fields.size() != values.size())
95
100
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
227
232
end of dispatch_command().
230
bool mysql_insert(Session *session,TableList *table_list,
235
bool insert_query(Session *session,TableList *table_list,
231
236
List<Item> &fields,
232
237
List<List_item> &values_list,
233
238
List<Item> &update_fields,
256
260
the current connection mode or table operation.
258
262
upgrade_lock_type(session, &table_list->lock_type, duplic,
259
values_list.elements > 1);
263
values_list.size() > 1);
261
265
if (session->openTablesLock(table_list))
267
lock_type= table_list->lock_type;
269
271
session->set_proc_info("init");
270
272
session->used_tables=0;
272
value_count= values->elements;
274
value_count= values->size();
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,
277
(fields.elements || !value_count ||
279
(fields.size() || !value_count ||
278
280
(0) != 0), !ignore))
280
282
if (table != NULL)
281
283
table->cursor->ha_release_auto_increment();
282
284
if (!joins_freed)
283
free_underlaid_joins(session, &session->lex->select_lex);
284
session->abort_on_warning= 0;
285
free_underlaid_joins(session, &session->lex().select_lex);
286
session->setAbortOnWarning(false);
285
287
DRIZZLE_INSERT_DONE(1, 0);
289
291
/* mysql_prepare_insert set table_list->table if it was not set */
290
292
table= table_list->table;
292
context= &session->lex->select_lex.context;
294
context= &session->lex().select_lex.context;
294
296
These three asserts test the hypothesis that the resetting of the name
295
297
resolution context below is not necessary at all since the list of local
312
314
while ((values= its++))
315
if (values->elements != value_count)
317
if (values->size() != value_count)
317
319
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
319
321
if (table != NULL)
320
322
table->cursor->ha_release_auto_increment();
321
323
if (!joins_freed)
322
free_underlaid_joins(session, &session->lex->select_lex);
323
session->abort_on_warning= 0;
324
free_underlaid_joins(session, &session->lex().select_lex);
325
session->setAbortOnWarning(false);
324
326
DRIZZLE_INSERT_DONE(1, 0);
330
332
if (table != NULL)
331
333
table->cursor->ha_release_auto_increment();
332
334
if (!joins_freed)
333
free_underlaid_joins(session, &session->lex->select_lex);
334
session->abort_on_warning= 0;
335
free_underlaid_joins(session, &session->lex().select_lex);
336
session->setAbortOnWarning(false);
335
337
DRIZZLE_INSERT_DONE(1, 0);
341
its= values_list.begin();
341
343
/* Restore the current context. */
342
344
ctx_state.restore_state(context, table_list);
369
371
if (duplic != DUP_ERROR || ignore)
370
372
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
371
table->cursor->ha_start_bulk_insert(values_list.elements);
373
table->cursor->ha_start_bulk_insert(values_list.size());
375
session->abort_on_warning= !ignore;
377
session->setAbortOnWarning(not ignore);
377
379
table->mark_columns_needed_for_insert();
379
381
while ((values= its++))
381
if (fields.elements || !value_count)
383
if (fields.size() || !value_count)
383
385
table->restoreRecordAsDefault(); // Get empty record
384
386
if (fill_record(session, fields, *values))
386
if (values_list.elements != 1 && ! session->is_error())
388
if (values_list.size() != 1 && ! session->is_error())
482
484
if (table != NULL)
483
485
table->cursor->ha_release_auto_increment();
484
486
if (!joins_freed)
485
free_underlaid_joins(session, &session->lex->select_lex);
486
session->abort_on_warning= 0;
487
free_underlaid_joins(session, &session->lex().select_lex);
488
session->setAbortOnWarning(false);
487
489
DRIZZLE_INSERT_DONE(1, 0);
491
if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
493
if (values_list.size() == 1 && (!(session->options & OPTION_WARNINGS) ||
492
494
!session->cuted_fields))
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);
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);
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());
548
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
549
&session->lex->select_lex.top_join_list,
550
if (setup_tables_and_check_access(session, &session->lex().select_lex.context,
551
&session->lex().select_lex.top_join_list,
551
&session->lex->select_lex.leaf_tables,
553
&session->lex().select_lex.leaf_tables,
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,
595
597
bool select_insert,
596
598
bool check_fields, bool abort_on_warning)
598
Select_Lex *select_lex= &session->lex->select_lex;
600
Select_Lex *select_lex= &session->lex().select_lex;
599
601
Name_resolution_context *context= &select_lex->context;
600
602
Name_resolution_context_state ctx_state;
601
603
bool insert_into_view= (0 != 0);
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))
659
661
if (!res && check_fields)
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();
665
session->setAbortOnWarning(abort_on_warning);
663
666
res= check_that_all_fields_are_given_values(session,
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);
670
673
if (!res && duplic == DUP_UPDATE)
675
678
/* Restore the current context. */
676
679
ctx_state.restore_state(context, table_list);
679
682
res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
686
689
table= table_list->table;
691
if (not select_insert)
690
693
TableList *duplicate;
691
694
if ((duplicate= unique_table(table_list, table_list->next_global, true)))
834
838
assert(table->insert_values.size());
835
839
table->storeRecordAsInsert();
836
840
table->restoreRecord();
837
assert(info->update_fields->elements ==
838
info->update_values->elements);
841
assert(info->update_fields->size() ==
842
info->update_values->size());
839
843
if (fill_record(session, *info->update_fields,
840
844
*info->update_values,
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.
961
965
info->last_errno= error;
962
966
/* current_select is NULL if this is a delayed insert */
963
if (session->lex->current_select)
964
session->lex->current_select->no_error= 0; // Give error
967
if (session->lex().current_select)
968
session->lex().current_select->no_error= 0; // Give error
965
969
table->print_error(error,MYF(0));
1002
1006
* However, if an actual NULL value was specified
1003
* for the field and the field is a NOT NULL field,
1007
* for the field and the field is a NOT NULL field,
1004
1008
* throw ER_BAD_NULL_ERROR.
1006
1010
* Per the SQL standard, inserting NULL into a NOT NULL
1044
1048
clause if table is VIEW
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,
1096
1099
select, LEX::current_select should point to the first select while
1097
1100
we are fixing fields from insert list.
1099
lex->current_select= &lex->select_lex;
1102
session->lex().current_select= &session->lex().select_lex;
1100
1103
res= check_insert_fields(session, table_list, *fields, values,
1101
1104
!insert_into_view, &map) ||
1102
1105
setup_fields(session, 0, values, MARK_COLUMNS_READ, 0, 0);
1104
if (!res && fields->elements)
1107
if (!res && fields->size())
1106
bool saved_abort_on_warning= session->abort_on_warning;
1107
session->abort_on_warning= !info.ignore;
1109
bool saved_abort_on_warning= session->abortOnWarning();
1110
session->setAbortOnWarning(not info.ignore);
1108
1111
res= check_that_all_fields_are_given_values(session, table_list->table,
1110
session->abort_on_warning= saved_abort_on_warning;
1113
session->setAbortOnWarning(saved_abort_on_warning);
1113
1116
if (info.handle_duplicates == DUP_UPDATE && !res)
1115
Name_resolution_context *context= &lex->select_lex.context;
1118
Name_resolution_context *context= &session->lex().select_lex.context;
1116
1119
Name_resolution_context_state ctx_state;
1118
1121
/* Save the state of the current name resolution context. */
1130
1133
We use next_name_resolution_table descructively, so check it first (views?)
1132
1135
assert (!table_list->next_name_resolution_table);
1133
if (lex->select_lex.group_list.elements == 0 &&
1134
!lex->select_lex.with_sum_func)
1136
if (session->lex().select_lex.group_list.elements == 0 and
1137
not session->lex().select_lex.with_sum_func)
1136
1139
We must make a single context out of the two separate name resolution contexts :
1137
1140
the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
1150
1153
order to get correct values from those fields when the select
1151
1154
employs a temporary table.
1153
List_iterator<Item> li(*info.update_values);
1156
List<Item>::iterator li(info.update_values->begin());
1156
1159
while ((item= li++))
1158
1161
item->transform(&Item::update_value_transformer,
1159
(unsigned char*)lex->current_select);
1162
(unsigned char*)session->lex().current_select);
1180
1183
if (unique_table(table_list, table_list->next_global))
1182
1185
/* Using same table for INSERT and SELECT */
1183
lex->current_select->options|= OPTION_BUFFER_RESULT;
1184
lex->current_select->join->select_options|= OPTION_BUFFER_RESULT;
1186
session->lex().current_select->options|= OPTION_BUFFER_RESULT;
1187
session->lex().current_select->join->select_options|= OPTION_BUFFER_RESULT;
1186
else if (!(lex->current_select->options & OPTION_BUFFER_RESULT))
1189
else if (not (session->lex().current_select->options & OPTION_BUFFER_RESULT))
1189
1192
We must not yet prepare the result table if it is the same as one of the
1200
1203
table->next_number_field=table->found_next_number_field;
1202
1205
session->cuted_fields=0;
1203
1207
if (info.ignore || info.handle_duplicates != DUP_ERROR)
1204
1208
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1205
1210
if (info.handle_duplicates == DUP_REPLACE)
1206
1211
table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1207
1213
if (info.handle_duplicates == DUP_UPDATE)
1208
1214
table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1209
session->abort_on_warning= !info.ignore;
1216
session->setAbortOnWarning(not info.ignore);
1210
1217
table->mark_columns_needed_for_insert();
1233
1240
int select_insert::prepare2(void)
1236
if (session->lex->current_select->options & OPTION_BUFFER_RESULT)
1242
if (session->lex().current_select->options & OPTION_BUFFER_RESULT)
1237
1243
table->cursor->ha_start_bulk_insert((ha_rows) 0);
1263
1270
bool select_insert::send_data(List<Item> &values)
1268
1275
if (unit->offset_limit_cnt)
1269
1276
{ // using limit offset,count
1270
1277
unit->offset_limit_cnt--;
1274
1281
session->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
1275
1282
store_values(values);
1276
1283
session->count_cuted_fields= CHECK_FIELD_IGNORE;
1277
1284
if (session->is_error())
1280
1287
// Release latches in case bulk insert takes a long time
1281
1288
plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1320
1327
void select_insert::store_values(List<Item> &values)
1322
if (fields->elements)
1323
1330
fill_record(session, *fields, values, true);
1325
1332
fill_record(session, table->getFields(), values, true);
1328
void select_insert::send_error(uint32_t errcode,const char *err)
1335
void select_insert::send_error(drizzled::error_t errcode,const char *err)
1332
1337
my_message(errcode, err, MYF(0));
1380
1383
(session->arg_of_last_insert_id_function ?
1381
1384
session->first_successful_insert_id_in_prev_stmt :
1382
1385
(info.copied ? autoinc_value_of_last_inserted_row : 0));
1383
session->my_ok((ulong) session->row_count_func,
1386
session->my_ok((ulong) session->rowCount(),
1384
1387
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);
1388
session->status_var.inserted_row_count+= session->rowCount();
1389
DRIZZLE_INSERT_SELECT_DONE(0, session->rowCount());
1485
1488
List<Item> *items,
1486
1489
bool is_if_not_exists,
1487
1490
DrizzleLock **lock,
1488
TableIdentifier &identifier)
1491
const identifier::Table& identifier)
1490
1493
TableShare share(message::Table::INTERNAL);
1491
uint32_t select_field_count= items->elements;
1494
uint32_t select_field_count= items->size();
1492
1495
/* Add selected items to field list */
1493
List_iterator_fast<Item> it(*items);
1496
List<Item>::iterator it(items->begin());
1495
1498
Field *tmp_field;
1498
1500
if (not (identifier.isTmp()) && create_table->table->db_stat)
1515
1517
table::Shell tmp_table(share); // Used during 'CreateField()'
1516
tmp_table.timestamp_field= 0;
1518
tmp_table.getMutableShare()->db_create_options= 0;
1519
tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1521
1519
if (not table_proto.engine().name().compare("MyISAM"))
1522
1520
tmp_table.getMutableShare()->db_low_byte_first= true;
1523
1521
else if (not table_proto.engine().name().compare("MEMORY"))
1524
1522
tmp_table.getMutableShare()->db_low_byte_first= true;
1526
tmp_table.null_row= false;
1527
tmp_table.maybe_null= false;
1529
1524
tmp_table.in_use= session;
1531
1526
while ((item=it++))
1608
1603
if (concurrent_table->reopen_name_locked_table(create_table, session))
1610
plugin::StorageEngine::dropTable(*session, identifier);
1605
(void)plugin::StorageEngine::dropTable(*session, identifier);
1641
1636
table->reginfo.lock_type=TL_WRITE;
1642
if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, ¬_used)))
1637
if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
1662
1658
DrizzleLock *extra_lock= NULL;
1664
1660
For replication, the CREATE-SELECT statement is written
1665
in two pieces: the first transaction messsage contains
1661
in two pieces: the first transaction messsage contains
1666
1662
the CREATE TABLE statement as a CreateTableStatement message
1667
1663
necessary to create the table.
1669
1665
The second transaction message contains all the InsertStatement
1670
1666
and associated InsertRecords that should go into the table.
1693
1689
*m_plock= extra_lock;
1696
if (table->getShare()->sizeFields() < values.elements)
1692
if (table->getShare()->sizeFields() < values.size())
1698
1694
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
1702
1698
/* First field to copy */
1703
field= table->getFields() + table->getShare()->sizeFields() - values.elements;
1699
field= table->getFields() + table->getShare()->sizeFields() - values.size();
1705
1701
/* Mark all fields that are given values */
1706
1702
for (Field **f= field ; *f ; f++)
1716
1712
session->cuted_fields=0;
1717
1713
if (info.ignore || info.handle_duplicates != DUP_ERROR)
1718
1714
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1719
1716
if (info.handle_duplicates == DUP_REPLACE)
1720
1717
table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1721
1719
if (info.handle_duplicates == DUP_UPDATE)
1722
1720
table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1723
1722
table->cursor->ha_start_bulk_insert((ha_rows) 0);
1724
session->abort_on_warning= !info.ignore;
1723
session->setAbortOnWarning(not info.ignore);
1725
1724
if (check_that_all_fields_are_given_values(session, table, table_list))
1727
1727
table->mark_columns_needed_for_insert();
1728
1728
table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1738
void select_create::send_error(uint32_t errcode,const char *err)
1738
void select_create::send_error(drizzled::error_t errcode,const char *err)
1741
1741
This will execute any rollbacks that are necessary before writing
1769
1767
if (!table->getShare()->getType())
1771
1769
TransactionServices &transaction_services= TransactionServices::singleton();
1772
transaction_services.autocommitOrRollback(session, 0);
1770
transaction_services.autocommitOrRollback(*session, 0);
1773
1771
(void) session->endActiveTransaction();