~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/cursor.cc

  • Committer: Paul McCullagh
  • Date: 2010-09-22 13:04:27 UTC
  • mto: (1787.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1788.
  • Revision ID: paul.mccullagh@primebase.org-20100922130427-utakdj4ec4uiv1kc
Fixed PBXT recovery and shutdown, added shutdownPlugin() call to all plugins before the plugins are deleted

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
** General Cursor functions
55
55
****************************************************************************/
56
56
Cursor::Cursor(plugin::StorageEngine &engine_arg,
57
 
               Table &arg)
58
 
  : table(arg),
59
 
    engine(engine_arg),
60
 
    estimation_rows_to_insert(0),
 
57
               TableShare &share_arg)
 
58
  : table_share(&share_arg), table(0),
 
59
    estimation_rows_to_insert(0), engine(&engine_arg),
61
60
    ref(0),
62
61
    key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
63
62
    ref_length(sizeof(internal::my_off_t)),
80
79
 */
81
80
Cursor *Cursor::clone(memory::Root *mem_root)
82
81
{
83
 
  Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
 
82
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*table->getMutableShare());
84
83
 
85
84
  /*
86
85
    Allocate Cursor->ref here because otherwise ha_open will allocate it
90
89
  if (!(new_handler->ref= (unsigned char*) mem_root->alloc_root(ALIGN_SIZE(ref_length)*2)))
91
90
    return NULL;
92
91
 
93
 
  TableIdentifier identifier(getTable()->getShare()->getSchemaName(),
94
 
                             getTable()->getShare()->getTableName(),
95
 
                             getTable()->getShare()->getType());
 
92
  TableIdentifier identifier(table->getShare()->getSchemaName(),
 
93
                             table->getShare()->getTableName(),
 
94
                             table->getShare()->getType());
96
95
 
97
96
  if (new_handler && !new_handler->ha_open(identifier,
98
 
                                           getTable()->getDBStat(),
 
97
                                           table,
 
98
                                           table->getDBStat(),
99
99
                                           HA_OPEN_IGNORE_IF_LOCKED))
100
100
    return new_handler;
101
101
  return NULL;
111
111
  /* works only with key prefixes */
112
112
  assert(((keypart_map_arg + 1) & keypart_map_arg) == 0);
113
113
 
114
 
  const KeyPartInfo *key_part_found= getTable()->getShare()->getKeyInfo(key_position).key_part;
115
 
  const KeyPartInfo *end_key_part_found= key_part_found + getTable()->getShare()->getKeyInfo(key_position).key_parts;
 
114
  const KeyPartInfo *key_part_found= table->getShare()->getKeyInfo(key_position).key_part;
 
115
  const KeyPartInfo *end_key_part_found= key_part_found + table->getShare()->getKeyInfo(key_position).key_parts;
116
116
  uint32_t length= 0;
117
117
 
118
118
  while (key_part_found < end_key_part_found && keypart_map_arg)
175
175
  return end_bulk_insert();
176
176
}
177
177
 
 
178
void Cursor::change_table_ptr(Table *table_arg, TableShare *share)
 
179
{
 
180
  table= table_arg;
 
181
  table_share= share;
 
182
}
 
183
 
178
184
const key_map *Cursor::keys_to_use_for_scanning()
179
185
{
180
186
  return &key_map_empty;
182
188
 
183
189
bool Cursor::has_transactions()
184
190
{
185
 
  return (getTable()->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
 
191
  return (table->getShare()->db_type()->check_flag(HTON_BIT_DOES_TRANSACTIONS));
186
192
}
187
193
 
188
194
void Cursor::ha_statistic_increment(uint64_t system_status_var::*offset) const
189
195
{
190
 
  (getTable()->in_use->status_var.*offset)++;
 
196
  (table->in_use->status_var.*offset)++;
191
197
}
192
198
 
193
199
void **Cursor::ha_data(Session *session) const
194
200
{
195
 
  return session->getEngineData(getEngine());
 
201
  return session->getEngineData(engine);
196
202
}
197
203
 
198
204
bool Cursor::is_fatal_error(int error, uint32_t flags)
208
214
 
209
215
ha_rows Cursor::records() { return stats.records; }
210
216
uint64_t Cursor::tableSize() { return stats.index_file_length + stats.data_file_length; }
211
 
uint64_t Cursor::rowSize() { return getTable()->getRecordLength() + getTable()->sizeFields(); }
 
217
uint64_t Cursor::rowSize() { return table->getRecordLength() + table->sizeFields(); }
212
218
 
213
219
int Cursor::doOpen(const TableIdentifier &identifier, int mode, uint32_t test_if_locked)
214
220
{
222
228
  Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
223
229
*/
224
230
int Cursor::ha_open(const TableIdentifier &identifier,
 
231
                    Table *table_arg,
225
232
                    int mode,
226
233
                    int test_if_locked)
227
234
{
228
235
  int error;
229
236
 
 
237
  table= table_arg;
 
238
  assert(table->getShare() == table_share);
 
239
 
230
240
  if ((error= doOpen(identifier, mode, test_if_locked)))
231
241
  {
232
242
    if ((error == EACCES || error == EROFS) && mode == O_RDWR &&
233
 
        (getTable()->db_stat & HA_TRY_READ_ONLY))
 
243
        (table->db_stat & HA_TRY_READ_ONLY))
234
244
    {
235
 
      getTable()->db_stat|=HA_READ_ONLY;
 
245
      table->db_stat|=HA_READ_ONLY;
236
246
      error= doOpen(identifier, O_RDONLY,test_if_locked);
237
247
    }
238
248
  }
242
252
  }
243
253
  else
244
254
  {
245
 
    if (getTable()->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
246
 
      getTable()->db_stat|=HA_READ_ONLY;
 
255
    if (table->getShare()->db_options_in_use & HA_OPTION_READ_ONLY_DATA)
 
256
      table->db_stat|=HA_READ_ONLY;
247
257
    (void) extra(HA_EXTRA_NO_READCHECK);        // Not needed in SQL
248
258
 
249
259
    /* ref is already allocated for us if we're called from Cursor::clone() */
250
 
    if (!ref && !(ref= (unsigned char*) getTable()->alloc_root(ALIGN_SIZE(ref_length)*2)))
 
260
    if (!ref && !(ref= (unsigned char*) table->alloc_root(ALIGN_SIZE(ref_length)*2)))
251
261
    {
252
262
      close();
253
263
      error=HA_ERR_OUT_OF_MEM;
276
286
    TODO remove the test for HA_READ_ORDER
277
287
  */
278
288
  if (stats.deleted < 10 || primary_key >= MAX_KEY ||
279
 
      !(getTable()->index_flags(primary_key) & HA_READ_ORDER))
 
289
      !(table->index_flags(primary_key) & HA_READ_ORDER))
280
290
  {
281
291
    (void) startTableScan(1);
282
292
    while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
304
314
  @verbatim 1,5,15,25,35,... @endverbatim
305
315
*/
306
316
inline uint64_t
307
 
compute_next_insert_id(uint64_t nr, drizzle_system_variables *variables)
 
317
compute_next_insert_id(uint64_t nr,struct system_variables *variables)
308
318
{
309
319
  if (variables->auto_increment_increment == 1)
310
320
    return (nr+1); // optimization of the formula below
324
334
    Session::next_insert_id to be greater than the explicit value.
325
335
  */
326
336
  if ((next_insert_id > 0) && (nr >= next_insert_id))
327
 
    set_next_insert_id(compute_next_insert_id(nr, &getTable()->in_use->variables));
 
337
    set_next_insert_id(compute_next_insert_id(nr, &table->in_use->variables));
328
338
}
329
339
 
330
340
 
344
354
    The number X if it exists, "nr" otherwise.
345
355
*/
346
356
inline uint64_t
347
 
prev_insert_id(uint64_t nr, drizzle_system_variables *variables)
 
357
prev_insert_id(uint64_t nr, struct system_variables *variables)
348
358
{
349
359
  if (unlikely(nr < variables->auto_increment_offset))
350
360
  {
441
451
{
442
452
  uint64_t nr, nb_reserved_values;
443
453
  bool append= false;
444
 
  Session *session= getTable()->in_use;
445
 
  drizzle_system_variables *variables= &session->variables;
 
454
  Session *session= table->in_use;
 
455
  struct system_variables *variables= &session->variables;
446
456
 
447
457
  /*
448
458
    next_insert_id is a "cursor" into the reserved interval, it may go greater
454
464
     for an auto increment column, not a magic value like NULL is.
455
465
     same as sql_mode=NO_AUTO_VALUE_ON_ZERO */
456
466
 
457
 
  if ((nr= getTable()->next_number_field->val_int()) != 0
458
 
      || getTable()->auto_increment_field_not_null)
 
467
  if ((nr= table->next_number_field->val_int()) != 0
 
468
      || table->auto_increment_field_not_null)
459
469
  {
460
470
    /*
461
471
      Update next_insert_id if we had already generated a value in this
533
543
      nr= compute_next_insert_id(nr-1, variables);
534
544
    }
535
545
 
536
 
    if (getTable()->getShare()->next_number_keypart == 0)
 
546
    if (table->getShare()->next_number_keypart == 0)
537
547
    {
538
548
      /* We must defer the appending until "nr" has been possibly truncated */
539
549
      append= true;
540
550
    }
541
551
  }
542
552
 
543
 
  if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
 
553
  if (unlikely(table->next_number_field->store((int64_t) nr, true)))
544
554
  {
545
555
    /*
546
556
      first test if the query was aborted due to strict mode constraints
547
557
    */
548
 
    if (session->getKilled() == Session::KILL_BAD_DATA)
 
558
    if (session->killed == Session::KILL_BAD_DATA)
549
559
      return HA_ERR_AUTOINC_ERANGE;
550
560
 
551
561
    /*
556
566
      bother shifting the right bound (anyway any other value from this
557
567
      interval will cause a duplicate key).
558
568
    */
559
 
    nr= prev_insert_id(getTable()->next_number_field->val_int(), variables);
560
 
    if (unlikely(getTable()->next_number_field->store((int64_t) nr, true)))
561
 
      nr= getTable()->next_number_field->val_int();
 
569
    nr= prev_insert_id(table->next_number_field->val_int(), variables);
 
570
    if (unlikely(table->next_number_field->store((int64_t) nr, true)))
 
571
      nr= table->next_number_field->val_int();
562
572
  }
563
573
  if (append)
564
574
  {
612
622
      this statement used forced auto_increment values if there were some,
613
623
      wipe them away for other statements.
614
624
    */
615
 
    getTable()->in_use->auto_inc_intervals_forced.empty();
 
625
    table->in_use->auto_inc_intervals_forced.empty();
616
626
  }
617
627
}
618
628
 
658
668
   * possible resource to gain (and if there is... then there is a bug such
659
669
   * that in_use should have been set.
660
670
 */
661
 
  if (not getTable()->in_use)
 
671
  if (not table || not table->in_use)
662
672
    return;
663
673
 
664
 
  resource_context= getTable()->in_use->getResourceContext(getEngine());
 
674
  resource_context= table->in_use->getResourceContext(engine);
665
675
  /*
666
676
    When a storage engine method is called, the transaction must
667
677
    have been started, unless it's a DDL call, for which the
702
712
     * @todo Make TransactionServices generic to AfterTriggerServices
703
713
     * or similar...
704
714
     */
705
 
    Session *const session= getTable()->in_use;
 
715
    Session *const session= table->in_use;
706
716
    TransactionServices &transaction_services= TransactionServices::singleton();
707
 
    transaction_services.truncateTable(session, getTable());
 
717
    transaction_services.truncateTable(session, table);
708
718
  }
709
719
 
710
720
  return result;
803
813
  int error;
804
814
  if (!(error=index_next(buf)))
805
815
  {
806
 
    ptrdiff_t ptrdiff= buf - getTable()->getInsertRecord();
 
816
    ptrdiff_t ptrdiff= buf - table->getInsertRecord();
807
817
    unsigned char *save_record_0= NULL;
808
818
    KeyInfo *key_info= NULL;
809
819
    KeyPartInfo *key_part;
819
829
    */
820
830
    if (ptrdiff)
821
831
    {
822
 
      save_record_0= getTable()->getInsertRecord();
823
 
      getTable()->record[0]= buf;
824
 
      key_info= getTable()->key_info + active_index;
 
832
      save_record_0= table->getInsertRecord();
 
833
      table->record[0]= buf;
 
834
      key_info= table->key_info + active_index;
825
835
      key_part= key_info->key_part;
826
836
      key_part_end= key_part + key_info->key_parts;
827
837
      for (; key_part < key_part_end; key_part++)
831
841
      }
832
842
    }
833
843
 
834
 
    if (key_cmp_if_same(getTable(), key, active_index, keylen))
 
844
    if (key_cmp_if_same(table, key, active_index, keylen))
835
845
    {
836
 
      getTable()->status=STATUS_NOT_FOUND;
 
846
      table->status=STATUS_NOT_FOUND;
837
847
      error=HA_ERR_END_OF_FILE;
838
848
    }
839
849
 
840
850
    /* Move back if necessary. */
841
851
    if (ptrdiff)
842
852
    {
843
 
      getTable()->record[0]= save_record_0;
 
853
      table->record[0]= save_record_0;
844
854
      for (key_part= key_info->key_part; key_part < key_part_end; key_part++)
845
855
        key_part->field->move_field_offset(-ptrdiff);
846
856
    }
877
887
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
878
888
{
879
889
  uint32_t keys_per_block= (stats.block_size/2/
880
 
                        (getTable()->key_info[keynr].key_length + ref_length) + 1);
 
890
                        (table->key_info[keynr].key_length + ref_length) + 1);
881
891
  return ((double) (key_records + keys_per_block-1) /
882
892
          (double) keys_per_block);
883
893
}
906
916
 
907
917
  @note
908
918
    This method (or an overriding one in a derived class) must check for
909
 
    session->getKilled() and return HA_POS_ERROR if it is not zero. This is required
 
919
    session->killed and return HA_POS_ERROR if it is not zero. This is required
910
920
    for a user to be able to interrupt the calculation by killing the
911
921
    connection/query.
912
922
 
1184
1194
    key_compare_result_on_equal= ((end_key->flag == HA_READ_BEFORE_KEY) ? 1 :
1185
1195
                                  (end_key->flag == HA_READ_AFTER_KEY) ? -1 : 0);
1186
1196
  }
1187
 
  range_key_part= getTable()->key_info[active_index].key_part;
 
1197
  range_key_part= table->key_info[active_index].key_part;
1188
1198
 
1189
1199
  if (!start_key)                       // Read first record
1190
 
    result= index_first(getTable()->getInsertRecord());
 
1200
    result= index_first(table->getInsertRecord());
1191
1201
  else
1192
 
    result= index_read_map(getTable()->getInsertRecord(),
 
1202
    result= index_read_map(table->getInsertRecord(),
1193
1203
                           start_key->key,
1194
1204
                           start_key->keypart_map,
1195
1205
                           start_key->flag);
1222
1232
  if (eq_range)
1223
1233
  {
1224
1234
    /* We trust that index_next_same always gives a row in range */
1225
 
    return(index_next_same(getTable()->getInsertRecord(),
 
1235
    return(index_next_same(table->getInsertRecord(),
1226
1236
                                end_range->key,
1227
1237
                                end_range->length));
1228
1238
  }
1229
 
  result= index_next(getTable()->getInsertRecord());
 
1239
  result= index_next(table->getInsertRecord());
1230
1240
  if (result)
1231
1241
    return result;
1232
1242
  return(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
1394
1404
  {
1395
1405
    if (lock_type == F_RDLCK)
1396
1406
    {
1397
 
      DRIZZLE_CURSOR_RDLOCK_START(getTable()->getShare()->getSchemaName(),
1398
 
                                  getTable()->getShare()->getTableName());
 
1407
      DRIZZLE_CURSOR_RDLOCK_START(table_share->getSchemaName(),
 
1408
                                  table_share->getTableName());
1399
1409
    }
1400
1410
    else if (lock_type == F_WRLCK)
1401
1411
    {
1402
 
      DRIZZLE_CURSOR_WRLOCK_START(getTable()->getShare()->getSchemaName(),
1403
 
                                  getTable()->getShare()->getTableName());
 
1412
      DRIZZLE_CURSOR_WRLOCK_START(table_share->getSchemaName(),
 
1413
                                  table_share->getTableName());
1404
1414
    }
1405
1415
    else if (lock_type == F_UNLCK)
1406
1416
    {
1407
 
      DRIZZLE_CURSOR_UNLOCK_START(getTable()->getShare()->getSchemaName(),
1408
 
                                  getTable()->getShare()->getTableName());
 
1417
      DRIZZLE_CURSOR_UNLOCK_START(table_share->getSchemaName(),
 
1418
                                  table_share->getTableName());
1409
1419
    }
1410
1420
  }
1411
1421
 
1444
1454
int Cursor::ha_reset()
1445
1455
{
1446
1456
  /* Check that we have called all proper deallocation functions */
1447
 
  assert(! getTable()->getShare()->all_set.none());
1448
 
  assert(getTable()->key_read == 0);
 
1457
  assert((unsigned char*) table->def_read_set.getBitmap() +
 
1458
              table->getShare()->column_bitmap_size ==
 
1459
              (unsigned char*) table->def_write_set.getBitmap());
 
1460
  assert(table->getShare()->all_set.isSetAll());
 
1461
  assert(table->key_read == 0);
1449
1462
  /* ensure that ha_index_end / endTableScan has been called */
1450
1463
  assert(inited == NONE);
1451
1464
  /* Free cache used by filesort */
1452
 
  getTable()->free_io_cache();
 
1465
  table->free_io_cache();
1453
1466
  /* reset the bitmaps to point to defaults */
1454
 
  getTable()->default_column_bitmaps();
 
1467
  table->default_column_bitmaps();
1455
1468
  return(reset());
1456
1469
}
1457
1470
 
1466
1479
   * @TODO Technically, the below two lines can be take even further out of the
1467
1480
   * Cursor interface and into the fill_record() method.
1468
1481
   */
1469
 
  if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
 
1482
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
1470
1483
  {
1471
 
    getTable()->timestamp_field->set_time();
 
1484
    table->timestamp_field->set_time();
1472
1485
  }
1473
1486
 
1474
 
  DRIZZLE_INSERT_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
 
1487
  DRIZZLE_INSERT_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1475
1488
  setTransactionReadWrite();
1476
1489
  
1477
 
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*getTable(), buf)))
 
1490
  if (unlikely(plugin::EventObserver::beforeInsertRecord(*table, buf)))
1478
1491
  {
1479
1492
    error= ER_EVENT_OBSERVER_PLUGIN;
1480
1493
  }
1481
1494
  else
1482
1495
  {
1483
1496
    error= doInsertRecord(buf);
1484
 
    if (unlikely(plugin::EventObserver::afterInsertRecord(*getTable(), buf, error))) 
 
1497
    if (unlikely(plugin::EventObserver::afterInsertRecord(*table, buf, error))) 
1485
1498
    {
1486
1499
      error= ER_EVENT_OBSERVER_PLUGIN;
1487
1500
    }
1496
1509
    return error;
1497
1510
  }
1498
1511
 
1499
 
  if (unlikely(log_row_for_replication(getTable(), NULL, buf)))
 
1512
  if (unlikely(log_row_for_replication(table, NULL, buf)))
1500
1513
    return HA_ERR_RBR_LOGGING_FAILED;
1501
1514
 
1502
1515
  return 0;
1511
1524
    Some storage engines require that the new record is in getInsertRecord()
1512
1525
    (and the old record is in getUpdateRecord()).
1513
1526
   */
1514
 
  assert(new_data == getTable()->getInsertRecord());
 
1527
  assert(new_data == table->getInsertRecord());
1515
1528
 
1516
 
  DRIZZLE_UPDATE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
 
1529
  DRIZZLE_UPDATE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1517
1530
  setTransactionReadWrite();
1518
 
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*getTable(), old_data, new_data)))
 
1531
  if (unlikely(plugin::EventObserver::beforeUpdateRecord(*table, old_data, new_data)))
1519
1532
  {
1520
1533
    error= ER_EVENT_OBSERVER_PLUGIN;
1521
1534
  }
1522
1535
  else
1523
1536
  {
1524
 
    if (getTable()->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
 
1537
    if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
1525
1538
    {
1526
 
      getTable()->timestamp_field->set_time();
 
1539
      table->timestamp_field->set_time();
1527
1540
    }
1528
1541
 
1529
1542
    error= doUpdateRecord(old_data, new_data);
1530
 
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*getTable(), old_data, new_data, error)))
 
1543
    if (unlikely(plugin::EventObserver::afterUpdateRecord(*table, old_data, new_data, error)))
1531
1544
    {
1532
1545
      error= ER_EVENT_OBSERVER_PLUGIN;
1533
1546
    }
1542
1555
    return error;
1543
1556
  }
1544
1557
 
1545
 
  if (unlikely(log_row_for_replication(getTable(), old_data, new_data)))
 
1558
  if (unlikely(log_row_for_replication(table, old_data, new_data)))
1546
1559
    return HA_ERR_RBR_LOGGING_FAILED;
1547
1560
 
1548
1561
  return 0;
1549
1562
}
1550
 
TableShare *Cursor::getShare()
1551
 
{
1552
 
  return getTable()->getMutableShare();
1553
 
}
1554
1563
 
1555
1564
int Cursor::deleteRecord(const unsigned char *buf)
1556
1565
{
1557
1566
  int error;
1558
1567
 
1559
 
  DRIZZLE_DELETE_ROW_START(getTable()->getShare()->getSchemaName(), getTable()->getShare()->getTableName());
 
1568
  DRIZZLE_DELETE_ROW_START(table_share->getSchemaName(), table_share->getTableName());
1560
1569
  setTransactionReadWrite();
1561
 
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*getTable(), buf)))
 
1570
  if (unlikely(plugin::EventObserver::beforeDeleteRecord(*table, buf)))
1562
1571
  {
1563
1572
    error= ER_EVENT_OBSERVER_PLUGIN;
1564
1573
  }
1565
1574
  else
1566
1575
  {
1567
1576
    error= doDeleteRecord(buf);
1568
 
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*getTable(), buf, error)))
 
1577
    if (unlikely(plugin::EventObserver::afterDeleteRecord(*table, buf, error)))
1569
1578
    {
1570
1579
      error= ER_EVENT_OBSERVER_PLUGIN;
1571
1580
    }
1578
1587
  if (unlikely(error))
1579
1588
    return error;
1580
1589
 
1581
 
  if (unlikely(log_row_for_replication(getTable(), buf, NULL)))
 
1590
  if (unlikely(log_row_for_replication(table, buf, NULL)))
1582
1591
    return HA_ERR_RBR_LOGGING_FAILED;
1583
1592
 
1584
1593
  return 0;