~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_insert.cc

  • Committer: Brian Aker
  • Date: 2010-10-20 20:26:18 UTC
  • mfrom: (1859.2.13 refactor)
  • Revision ID: brian@tangent.org-20101020202618-9222n39lm329urv5
Merge for Brian 

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 ||
278
278
                            (0) != 0), !ignore))
279
 
  {
280
 
    if (table != NULL)
281
 
      table->cursor->ha_release_auto_increment();
282
 
    if (!joins_freed)
283
 
      free_underlaid_joins(session, &session->lex->select_lex);
284
 
    session->setAbortOnWarning(false);
285
 
    DRIZZLE_INSERT_DONE(1, 0);
286
 
    return true;
287
 
  }
 
279
    goto abort;
288
280
 
289
281
  /* mysql_prepare_insert set table_list->table if it was not set */
290
282
  table= table_list->table;
315
307
    if (values->elements != value_count)
316
308
    {
317
309
      my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
318
 
 
319
 
      if (table != NULL)
320
 
        table->cursor->ha_release_auto_increment();
321
 
      if (!joins_freed)
322
 
        free_underlaid_joins(session, &session->lex->select_lex);
323
 
      session->setAbortOnWarning(false);
324
 
      DRIZZLE_INSERT_DONE(1, 0);
325
 
 
326
 
      return true;
 
310
      goto abort;
327
311
    }
328
312
    if (setup_fields(session, 0, *values, MARK_COLUMNS_READ, 0, 0))
329
 
    {
330
 
      if (table != NULL)
331
 
        table->cursor->ha_release_auto_increment();
332
 
      if (!joins_freed)
333
 
        free_underlaid_joins(session, &session->lex->select_lex);
334
 
      session->setAbortOnWarning(false);
335
 
      DRIZZLE_INSERT_DONE(1, 0);
336
 
      return true;
337
 
    }
 
313
      goto abort;
338
314
  }
339
315
  its.rewind ();
340
316
 
372
348
  }
373
349
 
374
350
 
375
 
  session->setAbortOnWarning(not ignore);
 
351
  session->abort_on_warning= !ignore;
376
352
 
377
353
  table->mark_columns_needed_for_insert();
378
354
 
478
454
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
479
455
 
480
456
  if (error)
481
 
  {
482
 
    if (table != NULL)
483
 
      table->cursor->ha_release_auto_increment();
484
 
    if (!joins_freed)
485
 
      free_underlaid_joins(session, &session->lex->select_lex);
486
 
    session->setAbortOnWarning(false);
487
 
    DRIZZLE_INSERT_DONE(1, 0);
488
 
    return true;
489
 
  }
490
 
 
 
457
    goto abort;
491
458
  if (values_list.elements == 1 && (!(session->options & OPTION_WARNINGS) ||
492
459
                                    !session->cuted_fields))
493
460
  {
494
461
    session->row_count_func= info.copied + info.deleted + info.updated;
495
 
    session->my_ok((ulong) session->rowCount(),
 
462
    session->my_ok((ulong) session->row_count_func,
496
463
                   info.copied + info.deleted + info.touched, id);
497
464
  }
498
465
  else
505
472
      snprintf(buff, sizeof(buff), ER(ER_INSERT_INFO), (ulong) info.records,
506
473
              (ulong) (info.deleted + info.updated), (ulong) session->cuted_fields);
507
474
    session->row_count_func= info.copied + info.deleted + info.updated;
508
 
    session->my_ok((ulong) session->rowCount(),
 
475
    session->my_ok((ulong) session->row_count_func,
509
476
                   info.copied + info.deleted + info.touched, id, buff);
510
477
  }
511
 
  session->status_var.inserted_row_count+= session->rowCount();
512
 
  session->setAbortOnWarning(false);
513
 
  DRIZZLE_INSERT_DONE(0, session->rowCount());
514
 
 
 
478
  session->status_var.inserted_row_count+= session->row_count_func;
 
479
  session->abort_on_warning= 0;
 
480
  DRIZZLE_INSERT_DONE(0, session->row_count_func);
515
481
  return false;
 
482
 
 
483
abort:
 
484
  if (table != NULL)
 
485
    table->cursor->ha_release_auto_increment();
 
486
  if (!joins_freed)
 
487
    free_underlaid_joins(session, &session->lex->select_lex);
 
488
  session->abort_on_warning= 0;
 
489
  DRIZZLE_INSERT_DONE(1, 0);
 
490
  return true;
516
491
}
517
492
 
518
493
 
520
495
  Check if table can be updated
521
496
 
522
497
  SYNOPSIS
523
 
     prepare_insert_check_table()
 
498
     mysql_prepare_insert_check_table()
524
499
     session            Thread handle
525
500
     table_list         Table list
526
501
     fields             List of fields to be updated
532
507
     true  ERROR
533
508
*/
534
509
 
535
 
static bool prepare_insert_check_table(Session *session, TableList *table_list,
 
510
static bool mysql_prepare_insert_check_table(Session *session, TableList *table_list,
536
511
                                             List<Item> &,
537
512
                                             bool select_insert)
538
513
{
560
535
  Prepare items in INSERT statement
561
536
 
562
537
  SYNOPSIS
563
 
    prepare_insert()
 
538
    mysql_prepare_insert()
564
539
    session                     Thread handler
565
540
    table_list          Global/local table list
566
541
    table               Table to insert into (can be NULL if table should
587
562
    true  error
588
563
*/
589
564
 
590
 
bool prepare_insert(Session *session, TableList *table_list,
 
565
bool mysql_prepare_insert(Session *session, TableList *table_list,
591
566
                          Table *table, List<Item> &fields, List_item *values,
592
567
                          List<Item> &update_fields, List<Item> &update_values,
593
568
                          enum_duplicates duplic,
610
585
    inserting (for INSERT ... SELECT this is done by changing table_list,
611
586
    because INSERT ... SELECT share Select_Lex it with SELECT.
612
587
  */
613
 
  if (not select_insert)
 
588
  if (!select_insert)
614
589
  {
615
590
    for (Select_Lex_Unit *un= select_lex->first_inner_unit();
616
591
         un;
632
607
      return(true);
633
608
  }
634
609
 
635
 
  if (prepare_insert_check_table(session, table_list, fields, select_insert))
 
610
  if (mysql_prepare_insert_check_table(session, table_list, fields, select_insert))
636
611
    return(true);
637
612
 
638
613
 
658
633
 
659
634
    if (!res && check_fields)
660
635
    {
661
 
      bool saved_abort_on_warning= session->abortOnWarning();
662
 
 
663
 
      session->setAbortOnWarning(abort_on_warning);
 
636
      bool saved_abort_on_warning= session->abort_on_warning;
 
637
      session->abort_on_warning= abort_on_warning;
664
638
      res= check_that_all_fields_are_given_values(session,
665
639
                                                  table ? table :
666
640
                                                  context->table_list->table,
667
641
                                                  context->table_list);
668
 
      session->setAbortOnWarning(saved_abort_on_warning);
 
642
      session->abort_on_warning= saved_abort_on_warning;
669
643
    }
670
644
 
671
645
    if (!res && duplic == DUP_UPDATE)
676
650
    /* Restore the current context. */
677
651
    ctx_state.restore_state(context, table_list);
678
652
 
679
 
    if (not res)
 
653
    if (!res)
680
654
      res= setup_fields(session, 0, update_values, MARK_COLUMNS_READ, 0, 0);
681
655
  }
682
656
 
683
657
  if (res)
684
658
    return(res);
685
659
 
686
 
  if (not table)
 
660
  if (!table)
687
661
    table= table_list->table;
688
662
 
689
 
  if (not select_insert)
 
663
  if (!select_insert)
690
664
  {
691
665
    TableList *duplicate;
692
666
    if ((duplicate= unique_table(table_list, table_list->next_global, true)))
696
670
      return true;
697
671
    }
698
672
  }
699
 
 
700
673
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
701
674
    table->prepare_for_position();
702
675
 
848
821
          table->cursor->adjust_next_insert_id_after_explicit_value(
849
822
            table->next_number_field->val_int());
850
823
        info->touched++;
851
 
 
852
 
        if (! table->records_are_comparable() || table->compare_records())
 
824
        if ((table->cursor->getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) &&
 
825
            ! table->write_set->is_subset_of(*table->read_set)) ||
 
826
            table->compare_record())
853
827
        {
854
828
          if ((error=table->cursor->updateRecord(table->getUpdateRecord(),
855
829
                                                table->getInsertRecord())) &&
870
844
          /*
871
845
            If ON DUP KEY UPDATE updates a row instead of inserting one, it's
872
846
            like a regular UPDATE statement: it should not affect the value of a
873
 
            next SELECT LAST_INSERT_ID() or insert_id().
 
847
            next SELECT LAST_INSERT_ID() or mysql_insert_id().
874
848
            Except if LAST_INSERT_ID(#) was in the INSERT query, which is
875
849
            handled separately by Session::arg_of_last_insert_id_function.
876
850
          */
1016
990
      }
1017
991
    }
1018
992
  }
1019
 
  return session->abortOnWarning() ? err : 0;
 
993
  return session->abort_on_warning ? err : 0;
1020
994
}
1021
995
 
1022
996
/***************************************************************************
1028
1002
  make insert specific preparation and checks after opening tables
1029
1003
 
1030
1004
  SYNOPSIS
1031
 
    insert_select_prepare()
 
1005
    mysql_insert_select_prepare()
1032
1006
    session         thread handler
1033
1007
 
1034
1008
  RETURN
1036
1010
    true  Error
1037
1011
*/
1038
1012
 
1039
 
bool insert_select_prepare(Session *session)
 
1013
bool mysql_insert_select_prepare(Session *session)
1040
1014
{
1041
1015
  LEX *lex= session->lex;
1042
1016
  Select_Lex *select_lex= &lex->select_lex;
1046
1020
    clause if table is VIEW
1047
1021
  */
1048
1022
 
1049
 
  if (prepare_insert(session, lex->query_tables,
 
1023
  if (mysql_prepare_insert(session, lex->query_tables,
1050
1024
                           lex->query_tables->table, lex->field_list, 0,
1051
1025
                           lex->update_list, lex->value_list,
1052
1026
                           lex->duplicates,
1105
1079
 
1106
1080
  if (!res && fields->elements)
1107
1081
  {
1108
 
    bool saved_abort_on_warning= session->abortOnWarning();
1109
 
    session->setAbortOnWarning(not info.ignore);
 
1082
    bool saved_abort_on_warning= session->abort_on_warning;
 
1083
    session->abort_on_warning= !info.ignore;
1110
1084
    res= check_that_all_fields_are_given_values(session, table_list->table,
1111
1085
                                                table_list);
1112
 
    session->setAbortOnWarning(saved_abort_on_warning);
 
1086
    session->abort_on_warning= saved_abort_on_warning;
1113
1087
  }
1114
1088
 
1115
1089
  if (info.handle_duplicates == DUP_UPDATE && !res)
1202
1176
  table->next_number_field=table->found_next_number_field;
1203
1177
 
1204
1178
  session->cuted_fields=0;
1205
 
 
1206
1179
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1207
1180
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1208
 
 
1209
1181
  if (info.handle_duplicates == DUP_REPLACE)
1210
1182
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1211
 
 
1212
1183
  if (info.handle_duplicates == DUP_UPDATE)
1213
1184
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1214
 
 
1215
 
  session->setAbortOnWarning(not info.ignore);
 
1185
  session->abort_on_warning= !info.ignore;
1216
1186
  table->mark_columns_needed_for_insert();
1217
1187
 
1218
1188
 
1261
1231
    table->cursor->ha_reset();
1262
1232
  }
1263
1233
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1264
 
  session->setAbortOnWarning(false);
 
1234
  session->abort_on_warning= 0;
1265
1235
  return;
1266
1236
}
1267
1237
 
1274
1244
  if (unit->offset_limit_cnt)
1275
1245
  {                                             // using limit offset,count
1276
1246
    unit->offset_limit_cnt--;
1277
 
    return false;
 
1247
    return(0);
1278
1248
  }
1279
1249
 
1280
1250
  session->count_cuted_fields= CHECK_FIELD_WARN;        // Calculate cuted fields
1281
1251
  store_values(values);
1282
1252
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
1283
1253
  if (session->is_error())
1284
 
    return true;
 
1254
    return(1);
1285
1255
 
1286
1256
  // Release latches in case bulk insert takes a long time
1287
1257
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
1331
1301
    fill_record(session, table->getFields(), values, true);
1332
1302
}
1333
1303
 
1334
 
void select_insert::send_error(drizzled::error_t errcode,const char *err)
 
1304
void select_insert::send_error(uint32_t errcode,const char *err)
1335
1305
{
 
1306
 
 
1307
 
1336
1308
  my_message(errcode, err, MYF(0));
 
1309
 
 
1310
  return;
1337
1311
}
1338
1312
 
1339
1313
 
1382
1356
    (session->arg_of_last_insert_id_function ?
1383
1357
     session->first_successful_insert_id_in_prev_stmt :
1384
1358
     (info.copied ? autoinc_value_of_last_inserted_row : 0));
1385
 
  session->my_ok((ulong) session->rowCount(),
 
1359
  session->my_ok((ulong) session->row_count_func,
1386
1360
                 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());
 
1361
  session->status_var.inserted_row_count+= session->row_count_func; 
 
1362
  DRIZZLE_INSERT_SELECT_DONE(0, session->row_count_func);
1389
1363
  return 0;
1390
1364
}
1391
1365
 
1487
1461
                                      List<Item> *items,
1488
1462
                                      bool is_if_not_exists,
1489
1463
                                      DrizzleLock **lock,
1490
 
                                      identifier::Table::const_reference identifier)
 
1464
                                      TableIdentifier &identifier)
1491
1465
{
1492
1466
  TableShare share(message::Table::INTERNAL);
1493
1467
  uint32_t select_field_count= items->elements;
1495
1469
  List_iterator_fast<Item> it(*items);
1496
1470
  Item *item;
1497
1471
  Field *tmp_field;
 
1472
  bool not_used;
1498
1473
 
1499
1474
  if (not (identifier.isTmp()) && create_table->table->db_stat)
1500
1475
  {
1504
1479
      create_info->table_existed= 1;            // Mark that table existed
1505
1480
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1506
1481
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1507
 
                          create_table->getTableName());
 
1482
                          create_table->table_name);
1508
1483
      return create_table->table;
1509
1484
    }
1510
1485
 
1511
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1486
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1512
1487
    return NULL;
1513
1488
  }
1514
1489
 
1515
1490
  {
1516
1491
    table::Shell tmp_table(share);              // Used during 'CreateField()'
 
1492
    tmp_table.timestamp_field= 0;
 
1493
 
 
1494
    tmp_table.getMutableShare()->db_create_options= 0;
 
1495
    tmp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1517
1496
 
1518
1497
    if (not table_proto.engine().name().compare("MyISAM"))
1519
1498
      tmp_table.getMutableShare()->db_low_byte_first= true;
1520
1499
    else if (not table_proto.engine().name().compare("MEMORY"))
1521
1500
      tmp_table.getMutableShare()->db_low_byte_first= true;
1522
1501
 
 
1502
    tmp_table.null_row= false;
 
1503
    tmp_table.maybe_null= false;
 
1504
 
1523
1505
    tmp_table.in_use= session;
1524
1506
 
1525
1507
    while ((item=it++))
1570
1552
  */
1571
1553
  Table *table= 0;
1572
1554
  {
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))
 
1555
    if (not mysql_create_table_no_lock(session,
 
1556
                                       identifier,
 
1557
                                       create_info,
 
1558
                                       table_proto,
 
1559
                                       alter_info,
 
1560
                                       false,
 
1561
                                       select_field_count,
 
1562
                                       is_if_not_exists))
1581
1563
    {
1582
1564
      if (create_info->table_existed && not identifier.isTmp())
1583
1565
      {
1586
1568
          or it was created via different mysqld front-end to the
1587
1569
          cluster. We don't have much options but throw an error.
1588
1570
        */
1589
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->getTableName());
 
1571
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name);
1590
1572
        return NULL;
1591
1573
      }
1592
1574
 
1593
1575
      if (not identifier.isTmp())
1594
1576
      {
1595
 
        /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
1596
 
        boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
1597
 
 
1598
 
        if (create_table->table)
 
1577
        LOCK_open.lock(); /* CREATE TABLE... has found that the table already exists for insert and is adapting to use it */
 
1578
        if (session->reopen_name_locked_table(create_table))
1599
1579
        {
1600
 
          table::Concurrent *concurrent_table= static_cast<table::Concurrent *>(create_table->table);
1601
 
 
1602
 
          if (concurrent_table->reopen_name_locked_table(create_table, session))
1603
 
          {
1604
 
            (void)plugin::StorageEngine::dropTable(*session, identifier);
1605
 
          }
1606
 
          else
1607
 
          {
1608
 
            table= create_table->table;
1609
 
          }
 
1580
          quick_rm_table(*session, identifier);
1610
1581
        }
1611
1582
        else
1612
1583
        {
1613
 
          (void)plugin::StorageEngine::dropTable(*session, identifier);
 
1584
          table= create_table->table;
1614
1585
        }
 
1586
        LOCK_open.unlock();
1615
1587
      }
1616
1588
      else
1617
1589
      {
1624
1596
            it preparable for open. But let us do close_temporary_table() here
1625
1597
            just in case.
1626
1598
          */
1627
 
          session->drop_temporary_table(identifier);
 
1599
          session->drop_temporary_table(create_table);
1628
1600
        }
1629
1601
      }
1630
1602
    }
1633
1605
  }
1634
1606
 
1635
1607
  table->reginfo.lock_type=TL_WRITE;
1636
 
  if (not ((*lock)= session->lockTables(&table, 1, DRIZZLE_LOCK_IGNORE_FLUSH)))
 
1608
  if (! ((*lock)= mysql_lock_tables(session, &table, 1,
 
1609
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)))
1637
1610
  {
1638
1611
    if (*lock)
1639
1612
    {
1640
 
      session->unlockTables(*lock);
 
1613
      mysql_unlock_tables(session, *lock);
1641
1614
      *lock= 0;
1642
1615
    }
1643
1616
 
1698
1671
 
1699
1672
  /* Mark all fields that are given values */
1700
1673
  for (Field **f= field ; *f ; f++)
1701
 
  {
1702
 
    table->setWriteSet((*f)->position());
1703
 
  }
 
1674
    table->setWriteSet((*f)->field_index);
1704
1675
 
1705
1676
  /* Don't set timestamp if used */
1706
1677
  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1710
1681
  session->cuted_fields=0;
1711
1682
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1712
1683
    table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1713
 
 
1714
1684
  if (info.handle_duplicates == DUP_REPLACE)
1715
1685
    table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
1716
 
 
1717
1686
  if (info.handle_duplicates == DUP_UPDATE)
1718
1687
    table->cursor->extra(HA_EXTRA_INSERT_WITH_UPDATE);
1719
 
 
1720
1688
  table->cursor->ha_start_bulk_insert((ha_rows) 0);
1721
 
  session->setAbortOnWarning(not info.ignore);
 
1689
  session->abort_on_warning= !info.ignore;
1722
1690
  if (check_that_all_fields_are_given_values(session, table, table_list))
1723
1691
    return(1);
1724
 
 
1725
1692
  table->mark_columns_needed_for_insert();
1726
1693
  table->cursor->extra(HA_EXTRA_WRITE_CACHE);
1727
1694
  return(0);
1733
1700
}
1734
1701
 
1735
1702
 
1736
 
void select_create::send_error(drizzled::error_t errcode,const char *err)
 
1703
void select_create::send_error(uint32_t errcode,const char *err)
1737
1704
{
1738
1705
  /*
1739
1706
    This will execute any rollbacks that are necessary before writing
1747
1714
 
1748
1715
  */
1749
1716
  select_insert::send_error(errcode, err);
 
1717
 
 
1718
  return;
1750
1719
}
1751
1720
 
1752
1721
 
1765
1734
    if (!table->getShare()->getType())
1766
1735
    {
1767
1736
      TransactionServices &transaction_services= TransactionServices::singleton();
1768
 
      transaction_services.autocommitOrRollback(*session, 0);
 
1737
      transaction_services.autocommitOrRollback(session, 0);
1769
1738
      (void) session->endActiveTransaction();
1770
1739
    }
1771
1740
 
1773
1742
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1774
1743
    if (m_plock)
1775
1744
    {
1776
 
      session->unlockTables(*m_plock);
 
1745
      mysql_unlock_tables(session, *m_plock);
1777
1746
      *m_plock= NULL;
1778
1747
      m_plock= NULL;
1779
1748
    }
1803
1772
 
1804
1773
  if (m_plock)
1805
1774
  {
1806
 
    session->unlockTables(*m_plock);
 
1775
    mysql_unlock_tables(session, *m_plock);
1807
1776
    *m_plock= NULL;
1808
1777
    m_plock= NULL;
1809
1778
  }