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 */
19
19
#include "config.h"
21
20
#include <drizzled/sql_select.h>
22
21
#include <drizzled/show.h>
23
22
#include <drizzled/error.h>
315
295
if (values->elements != value_count)
317
297
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
320
table->cursor->ha_release_auto_increment();
322
free_underlaid_joins(session, &session->lex->select_lex);
323
session->abort_on_warning= 0;
324
DRIZZLE_INSERT_DONE(1, 0);
328
300
if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
331
table->cursor->ha_release_auto_increment();
333
free_underlaid_joins(session, &session->lex->select_lex);
334
session->abort_on_warning= 0;
335
DRIZZLE_INSERT_DONE(1, 0);
446
413
transactional_table= table->cursor->has_transactions();
448
415
changed= (info.copied || info.deleted || info.updated);
449
if ((changed && error <= 0) || session->transaction.stmt.hasModifiedNonTransData())
416
if ((changed && error <= 0) || session->transaction.stmt.modified_non_trans_table)
451
if (session->transaction.stmt.hasModifiedNonTransData())
452
session->transaction.all.markModifiedNonTransData();
418
if (session->transaction.stmt.modified_non_trans_table)
419
session->transaction.all.modified_non_trans_table= true;
454
assert(transactional_table || !changed || session->transaction.stmt.hasModifiedNonTransData());
421
assert(transactional_table || !changed || session->transaction.stmt.modified_non_trans_table);
457
424
session->set_proc_info("end");
502
snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
460
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
503
461
(ulong) (info.records - info.copied), (ulong) session->cuted_fields);
505
snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
463
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
506
464
(ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
507
465
session->row_count_func= info.copied + info.deleted + info.updated;
508
466
session->my_ok((ulong) session->row_count_func,
509
467
info.copied + info.deleted + info.touched, id, buff);
511
session->status_var.inserted_row_count+= session->row_count_func;
512
469
session->abort_on_warning= 0;
513
470
DRIZZLE_INSERT_DONE(0, session->row_count_func);
475
table->cursor->ha_release_auto_increment();
477
free_underlaid_joins(session, &session->lex->select_lex);
478
session->abort_on_warning= 0;
479
DRIZZLE_INSERT_DONE(1, 0);
819
key.resize(table->getShare()->max_unique_length);
784
if (!(key=(char*) malloc(table->s->max_unique_length)))
821
key_copy(&key[0], table->getInsertRecord(), table->key_info+key_nr, 0);
822
if ((error=(table->cursor->index_read_idx_map(table->getUpdateRecord(),key_nr,
823
&key[0], HA_WHOLE_KEY,
790
key_copy((unsigned char*) key,table->record[0],table->key_info+key_nr,0);
791
if ((error=(table->cursor->index_read_idx_map(table->record[1],key_nr,
792
(unsigned char*) key, HA_WHOLE_KEY,
824
793
HA_READ_KEY_EXACT))))
846
815
table->cursor->adjust_next_insert_id_after_explicit_value(
847
816
table->next_number_field->val_int());
850
if (! table->records_are_comparable() || table->compare_records())
818
if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
819
!bitmap_is_subset(table->write_set, table->read_set)) ||
820
table->compare_record())
852
if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
853
table->getInsertRecord())) &&
822
if ((error=table->cursor->ha_update_row(table->record[1],
823
table->record[0])) &&
854
824
error != HA_ERR_RECORD_IS_THE_SAME)
856
826
if (info->ignore &&
1068
1042
List<Item> *update_fields,
1069
1043
List<Item> *update_values,
1070
1044
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)
1045
bool ignore_check_option_errors)
1046
:table_list(table_list_par), table(table_par), fields(fields_par),
1047
autoinc_value_of_last_inserted_row(0),
1048
insert_into_view(table_list_par && 0 != 0)
1050
memset(&info, 0, sizeof(info));
1076
1051
info.handle_duplicates= duplic;
1077
1052
info.ignore= ignore_check_option_errors;
1078
1053
info.update_fields= update_fields;
1352
1326
We must invalidate the table in the query cache before binlog writing
1353
and autocommitOrRollback.
1327
and ha_autocommit_or_rollback.
1355
if (session->transaction.stmt.hasModifiedNonTransData())
1356
session->transaction.all.markModifiedNonTransData();
1329
if (session->transaction.stmt.modified_non_trans_table)
1330
session->transaction.all.modified_non_trans_table= true;
1358
1332
assert(trans_table || !changed ||
1359
session->transaction.stmt.hasModifiedNonTransData());
1333
session->transaction.stmt.modified_non_trans_table);
1361
1335
table->cursor->ha_release_auto_increment();
1369
1343
char buff[160];
1370
1344
if (info.ignore)
1371
snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
1345
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1372
1346
(ulong) (info.records - info.copied), (ulong) session->cuted_fields);
1374
snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
1348
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
1375
1349
(ulong) (info.deleted+info.updated), (ulong) session->cuted_fields);
1376
1350
session->row_count_func= info.copied + info.deleted + info.updated;
1481
1454
static Table *create_table_from_items(Session *session, HA_CREATE_INFO *create_info,
1482
1455
TableList *create_table,
1483
message::Table &table_proto,
1456
message::Table *table_proto,
1484
1457
AlterInfo *alter_info,
1485
1458
List<Item> *items,
1486
1459
bool is_if_not_exists,
1488
TableIdentifier &identifier)
1460
DRIZZLE_LOCK **lock)
1490
TableShare share(message::Table::INTERNAL);
1462
Table tmp_table; // Used during 'CreateField()'
1491
1465
uint32_t select_field_count= items->elements;
1492
1466
/* Add selected items to field list */
1493
1467
List_iterator_fast<Item> it(*items);
1503
1480
create_info->table_existed= 1; // Mark that table existed
1504
1481
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1505
1482
ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1506
create_table->getTableName());
1483
create_table->table_name);
1507
1484
return create_table->table;
1510
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
1487
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1492
tmp_table.timestamp_field= 0;
1493
tmp_table.s= &share;
1495
tmp_table.s->db_create_options=0;
1496
tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
1497
tmp_table.s->db_low_byte_first=
1498
test(create_info->db_type == myisam_engine ||
1499
create_info->db_type == heap_engine);
1500
tmp_table.null_row= false;
1501
tmp_table.maybe_null= false;
1515
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
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;
1526
tmp_table.null_row= false;
1527
tmp_table.maybe_null= false;
1529
tmp_table.in_use= session;
1533
CreateField *cr_field;
1534
Field *field, *def_field;
1535
if (item->type() == Item::FUNC_ITEM)
1537
if (item->result_type() != STRING_RESULT)
1539
field= item->tmp_table_field(&tmp_table);
1543
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1505
CreateField *cr_field;
1506
Field *field, *def_field;
1507
if (item->type() == Item::FUNC_ITEM)
1508
if (item->result_type() != STRING_RESULT)
1509
field= item->tmp_table_field(&tmp_table);
1548
field= create_tmp_field(session, &tmp_table, item, item->type(),
1549
(Item ***) 0, &tmp_field, &def_field, false,
1554
!(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1555
((Item_field *)item)->field :
1561
if (item->maybe_null)
1563
cr_field->flags &= ~NOT_NULL_FLAG;
1566
alter_info->create_list.push_back(cr_field);
1511
field= item->tmp_table_field_from_field_type(&tmp_table, 0);
1513
field= create_tmp_field(session, &tmp_table, item, item->type(),
1514
(Item ***) 0, &tmp_field, &def_field, 0, 0, 0, 0,
1517
!(cr_field=new CreateField(field,(item->type() == Item::FIELD_ITEM ?
1518
((Item_field *)item)->field :
1521
if (item->maybe_null)
1522
cr_field->flags &= ~NOT_NULL_FLAG;
1523
alter_info->create_list.push_back(cr_field);
1526
TableIdentifier identifier(create_table->db,
1527
create_table->table_name,
1528
lex_identified_temp_table ? TEMP_TABLE :
1571
1533
Create and lock table.
1574
1536
creating base table on which name we have exclusive lock. So code below
1575
1537
should not cause deadlocks or races.
1579
if (not mysql_create_table_no_lock(session,
1540
if (!mysql_create_table_no_lock(session,
1588
if (create_info->table_existed && not identifier.isTmp())
1549
if (create_info->table_existed &&
1550
!(lex_identified_temp_table))
1591
1553
This means that someone created table underneath server
1592
1554
or it was created via different mysqld front-end to the
1593
1555
cluster. We don't have much options but throw an error.
1595
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
1557
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1599
if (not identifier.isTmp())
1561
if (!(lex_identified_temp_table))
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());
1604
if (create_table->table)
1563
pthread_mutex_lock(&LOCK_open); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1564
if (session->reopen_name_locked_table(create_table, false))
1606
table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1608
if (concurrent_table->reopen_name_locked_table(create_table, session))
1610
plugin::StorageEngine::dropTable(*session, identifier);
1614
table= create_table->table;
1566
quick_rm_table(*session, identifier);
1619
plugin::StorageEngine::dropTable(*session, identifier);
1569
table= create_table->table;
1570
pthread_mutex_unlock(&LOCK_open);
1624
if (not (table= session->openTable(create_table, (bool*) 0,
1625
DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
1626
not create_info->table_existed)
1574
if (!(table= session->openTable(create_table, (bool*) 0,
1575
DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
1576
!create_info->table_existed)
1629
1579
This shouldn't happen as creation of temporary table should make
1630
1580
it preparable for open. But let us do close_temporary_table() here
1633
session->drop_temporary_table(identifier);
1583
session->drop_temporary_table(create_table);
1637
if (not table) // open failed
1587
if (!table) // open failed
1641
1591
table->reginfo.lock_type=TL_WRITE;
1642
if (! ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH, ¬_used)))
1592
if (! ((*lock)= mysql_lock_tables(session, &table, 1,
1593
DRIZZLE_LOCK_IGNORE_FLUSH, ¬_used)))
1646
session->unlockTables(*lock);
1597
mysql_unlock_tables(session, *lock);
1650
if (not create_info->table_existed)
1651
session->drop_open_table(table, identifier);
1601
if (!create_info->table_existed)
1602
session->drop_open_table(table, create_table->db, create_table->table_name);
1660
1611
select_create::prepare(List<Item> &values, Select_Lex_Unit *u)
1662
DrizzleLock *extra_lock= NULL;
1613
bool lex_identified_temp_table= (table_proto->type() == message::Table::TEMPORARY);
1615
DRIZZLE_LOCK *extra_lock= NULL;
1664
For replication, the CREATE-SELECT statement is written
1665
in two pieces: the first transaction messsage contains
1666
the CREATE TABLE statement as a CreateTableStatement message
1667
necessary to create the table.
1669
The second transaction message contains all the InsertStatement
1670
and associated InsertRecords that should go into the table.
1617
For row-based replication, the CREATE-SELECT statement is written
1618
in two pieces: the first one contain the CREATE TABLE statement
1619
necessary to create the table and the second part contain the rows
1620
that should go into the table.
1622
For non-temporary tables, the start of the CREATE-SELECT
1623
implicitly commits the previous transaction, and all events
1624
forming the statement will be stored the transaction cache. At end
1625
of the statement, the entire statement is committed as a
1626
transaction, and all events are written to the binary log.
1628
On the master, the table is locked for the duration of the
1629
statement, but since the CREATE part is replicated as a simple
1630
statement, there is no way to lock the table for accesses on the
1631
slave. Hence, we have to hold on to the CREATE part of the
1632
statement until the statement has finished.
1675
if (not (table= create_table_from_items(session, create_info, create_table,
1677
alter_info, &values,
1679
&extra_lock, identifier)))
1638
Start a statement transaction before the create if we are using
1639
row-based replication for the statement. If we are creating a
1640
temporary table, we need to start a statement transaction.
1643
if (!(table= create_table_from_items(session, create_info, create_table,
1645
alter_info, &values,
1681
1648
return(-1); // abort() deletes table
1684
1650
if (extra_lock)
1686
1652
assert(m_plock == NULL);
1688
if (identifier.isTmp())
1654
if (lex_identified_temp_table)
1689
1655
m_plock= &m_lock;
1691
1657
m_plock= &session->extra_lock;
1693
1659
*m_plock= extra_lock;
1696
if (table->getShare()->sizeFields() < values.elements)
1662
if (table->s->fields < values.elements)
1698
1664
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
1702
1668
/* First field to copy */
1703
field= table->getFields() + table->getShare()->sizeFields() - values.elements;
1669
field= table->field+table->s->fields - values.elements;
1705
1671
/* Mark all fields that are given values */
1706
1672
for (Field **f= field ; *f ; f++)
1708
table->setWriteSet((*f)->position());
1673
table->setWriteSet((*f)->field_index);
1711
1675
/* Don't set timestamp if used */
1712
1676
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;