~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_delete.cc

  • Committer: Brian Aker
  • Date: 2008-08-12 03:12:57 UTC
  • Revision ID: brian@tangent.org-20080812031257-ln3uk87y1r22byeg
First pass of new sql_db.cc work

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
  end of dispatch_command().
31
31
*/
32
32
 
33
 
bool mysql_delete(THD *thd, TableList *table_list, COND *conds,
 
33
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
34
34
                  SQL_LIST *order, ha_rows limit, uint64_t options,
35
35
                  bool reset_auto_increment)
36
36
{
37
37
  bool          will_batch;
38
38
  int           error, loc_error;
39
 
  Table         *table;
 
39
  TABLE         *table;
40
40
  SQL_SELECT    *select=0;
41
41
  READ_RECORD   info;
42
42
  bool          using_limit=limit != HA_POS_ERROR;
43
43
  bool          transactional_table, safe_update, const_cond;
44
44
  bool          const_cond_result;
45
45
  ha_rows       deleted= 0;
46
 
  uint32_t usable_index= MAX_KEY;
 
46
  uint usable_index= MAX_KEY;
47
47
  SELECT_LEX   *select_lex= &thd->lex->select_lex;
48
48
  THD::killed_state killed_status= THD::NOT_KILLED;
49
49
  
65
65
  /* check ORDER BY even if it can be ignored */
66
66
  if (order && order->elements)
67
67
  {
68
 
    TableList   tables;
 
68
    TABLE_LIST   tables;
69
69
    List<Item>   fields;
70
70
    List<Item>   all_fields;
71
71
 
75
75
 
76
76
      if (select_lex->setup_ref_array(thd, order->elements) ||
77
77
          setup_order(thd, select_lex->ref_pointer_array, &tables,
78
 
                    fields, all_fields, (order_st*) order->first))
 
78
                    fields, all_fields, (ORDER*) order->first))
79
79
    {
80
80
      delete select;
81
81
      free_underlaid_joins(thd, &thd->lex->select_lex);
121
121
      - there should be no delete triggers associated with the table.
122
122
  */
123
123
  if (!using_limit && const_cond_result &&
 
124
      !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
124
125
      (thd->lex->sql_command == SQLCOM_TRUNCATE ||
125
126
       (!thd->current_stmt_binlog_row_based)))
126
127
  {
162
163
    delete select;
163
164
    free_underlaid_joins(thd, select_lex);
164
165
    thd->row_count_func= 0;
165
 
    DRIZZLE_DELETE_END();
 
166
    MYSQL_DELETE_END();
166
167
    my_ok(thd, (ha_rows) thd->row_count_func);
167
168
    /*
168
169
      We don't need to call reset_auto_increment in this case, because
190
191
 
191
192
  if (order && order->elements)
192
193
  {
193
 
    uint32_t         length= 0;
 
194
    uint         length= 0;
194
195
    SORT_FIELD  *sortorder;
195
196
    ha_rows examined_rows;
196
197
    
197
198
    if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
198
 
      usable_index= get_index_for_order(table, (order_st*)(order->first), limit);
 
199
      usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
199
200
 
200
201
    if (usable_index == MAX_KEY)
201
202
    {
202
203
      table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
203
204
                                                   MYF(MY_FAE | MY_ZEROFILL));
204
205
    
205
 
      if (!(sortorder= make_unireg_sortorder((order_st*) order->first,
 
206
      if (!(sortorder= make_unireg_sortorder((ORDER*) order->first,
206
207
                                             &length, NULL)) ||
207
208
          (table->sort.found_records = filesort(thd, table, sortorder, length,
208
209
                                                select, HA_POS_ERROR, 1,
340
341
  assert(transactional_table || !deleted || thd->transaction.stmt.modified_non_trans_table);
341
342
  free_underlaid_joins(thd, select_lex);
342
343
 
343
 
  DRIZZLE_DELETE_END();
 
344
  MYSQL_DELETE_END();
344
345
  if (error < 0 || (thd->lex->ignore && !thd->is_fatal_error))
345
346
  {
346
347
    thd->row_count_func= deleted;
349
350
  return(error >= 0 || thd->is_error());
350
351
 
351
352
err:
352
 
  DRIZZLE_DELETE_END();
 
353
  MYSQL_DELETE_END();
353
354
  return(true);
354
355
}
355
356
 
367
368
    false OK
368
369
    true  error
369
370
*/
370
 
int mysql_prepare_delete(THD *thd, TableList *table_list, Item **conds)
 
371
int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
371
372
{
372
373
  SELECT_LEX *select_lex= &thd->lex->select_lex;
373
374
  
394
395
      setup_conds(thd, table_list, select_lex->leaf_tables, conds))
395
396
    return(true);
396
397
  {
397
 
    TableList *duplicate;
 
398
    TABLE_LIST *duplicate;
398
399
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 0)))
399
400
    {
400
401
      update_non_unique_table_error(table_list, "DELETE", duplicate);
419
420
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b)
420
421
{
421
422
  handler *file= (handler*)arg;
422
 
  return file->cmp_ref((const unsigned char*)a, (const unsigned char*)b);
 
423
  return file->cmp_ref((const uchar*)a, (const uchar*)b);
423
424
}
424
425
 
425
426
/*
437
438
int mysql_multi_delete_prepare(THD *thd)
438
439
{
439
440
  LEX *lex= thd->lex;
440
 
  TableList *aux_tables= (TableList *)lex->auxiliary_table_list.first;
441
 
  TableList *target_tbl;
 
441
  TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxiliary_table_list.first;
 
442
  TABLE_LIST *target_tbl;
442
443
  
443
444
 
444
445
  /*
460
461
  */
461
462
  lex->select_lex.exclude_from_table_unique_test= true;
462
463
  /* Fix tables-to-be-deleted-from list to point at opened tables */
463
 
  for (target_tbl= (TableList*) aux_tables;
 
464
  for (target_tbl= (TABLE_LIST*) aux_tables;
464
465
       target_tbl;
465
466
       target_tbl= target_tbl->next_local)
466
467
  {
478
479
      inside subqueries/view.
479
480
    */
480
481
    {
481
 
      TableList *duplicate;
 
482
      TABLE_LIST *duplicate;
482
483
      if ((duplicate= unique_table(thd, target_tbl->correspondent_table,
483
484
                                   lex->query_tables, 0)))
484
485
      {
492
493
}
493
494
 
494
495
 
495
 
multi_delete::multi_delete(TableList *dt, uint32_t num_of_tables_arg)
 
496
multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
496
497
  : delete_tables(dt), deleted(0), found(0),
497
498
    num_of_tables(num_of_tables_arg), error(0),
498
499
    do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
516
517
bool
517
518
multi_delete::initialize_tables(JOIN *join)
518
519
{
519
 
  TableList *walk;
 
520
  TABLE_LIST *walk;
520
521
  Unique **tempfiles_ptr;
521
522
  
522
523
 
536
537
    if (tab->table->map & tables_to_delete_from)
537
538
    {
538
539
      /* We are going to delete from this table */
539
 
      Table *tbl=walk->table=tab->table;
 
540
      TABLE *tbl=walk->table=tab->table;
540
541
      walk= walk->next_local;
541
542
      /* Don't use KEYREAD optimization on this table */
542
543
      tbl->no_keyread=1;
570
571
  }
571
572
  for (;walk ;walk= walk->next_local)
572
573
  {
573
 
    Table *table=walk->table;
 
574
    TABLE *table=walk->table;
574
575
    *tempfiles_ptr++= new Unique (refpos_order_cmp,
575
576
                                  (void *) table->file,
576
577
                                  table->file->ref_length,
586
587
       table_being_deleted;
587
588
       table_being_deleted= table_being_deleted->next_local)
588
589
  {
589
 
    Table *table= table_being_deleted->table;
 
590
    TABLE *table= table_being_deleted->table;
590
591
    table->no_keyread=0;
591
592
  }
592
593
 
593
 
  for (uint32_t counter= 0; counter < num_of_tables; counter++)
 
594
  for (uint counter= 0; counter < num_of_tables; counter++)
594
595
  {
595
596
    if (tempfiles[counter])
596
597
      delete tempfiles[counter];
601
602
bool multi_delete::send_data(List<Item> &values __attribute__((unused)))
602
603
{
603
604
  int secure_counter= delete_while_scanning ? -1 : 0;
604
 
  TableList *del_table;
 
605
  TABLE_LIST *del_table;
605
606
  
606
607
 
607
608
  for (del_table= delete_tables;
608
609
       del_table;
609
610
       del_table= del_table->next_local, secure_counter++)
610
611
  {
611
 
    Table *table= del_table->table;
 
612
    TABLE *table= del_table->table;
612
613
 
613
614
    /* Check if we are using outer join and we didn't find the row */
614
615
    if (table->status & (STATUS_NULL_ROW | STATUS_DELETED))
648
649
}
649
650
 
650
651
 
651
 
void multi_delete::send_error(uint32_t errcode,const char *err)
 
652
void multi_delete::send_error(uint errcode,const char *err)
652
653
{
653
654
  
654
655
 
731
732
       table_being_deleted= table_being_deleted->next_local, counter++)
732
733
  { 
733
734
    ha_rows last_deleted= deleted;
734
 
    Table *table = table_being_deleted->table;
 
735
    TABLE *table = table_being_deleted->table;
735
736
    if (tempfiles[counter]->get(table))
736
737
    {
737
738
      local_error=1;
826
827
 
827
828
 
828
829
/***************************************************************************
829
 
  TRUNCATE Table
 
830
  TRUNCATE TABLE
830
831
****************************************************************************/
831
832
 
832
833
/*
841
842
  - If we want to have a name lock on the table on exit without errors.
842
843
*/
843
844
 
844
 
bool mysql_truncate(THD *thd, TableList *table_list, bool dont_send_ok)
 
845
bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
845
846
{
846
847
  HA_CREATE_INFO create_info;
847
848
  char path[FN_REFLEN];
848
 
  Table *table;
 
849
  TABLE *table;
849
850
  bool error;
850
 
  uint32_t path_length;
 
851
  uint path_length;
851
852
  
852
853
 
853
854
  memset(&create_info, 0, sizeof(create_info));
873
874
                                             OTM_OPEN))))
874
875
      (void) rm_temporary_table(table_type, path, frm_only);
875
876
    free_table_share(share);
876
 
    free((char*) table);
 
877
    my_free((char*) table,MYF(0));
877
878
    /*
878
879
      If we return here we will not have logged the truncation to the bin log
879
880
      and we will not my_ok() to the client.
885
886
                                    table_list->table_name, reg_ext, 0);
886
887
 
887
888
  if (!dont_send_ok)
888
 
    goto trunc_by_del;
 
889
  {
 
890
    enum legacy_db_type table_type;
 
891
    mysql_frm_type(thd, path, &table_type);
 
892
    if (table_type == DB_TYPE_UNKNOWN)
 
893
    {
 
894
      my_error(ER_NO_SUCH_TABLE, MYF(0),
 
895
               table_list->db, table_list->table_name);
 
896
      return(true);
 
897
    }
 
898
 
 
899
    if (!ha_check_storage_engine_flag(ha_resolve_by_legacy_type(thd, table_type),
 
900
                                      HTON_CAN_RECREATE))
 
901
      goto trunc_by_del;
 
902
 
 
903
    if (lock_and_wait_for_table_name(thd, table_list))
 
904
      return(true);
 
905
  }
889
906
 
890
907
  // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
891
908
  // crashes, replacement works.  *(path + path_length - reg_ext_length)=
892
909
  // '\0';
893
910
  path[path_length - reg_ext_length] = 0;
894
 
  pthread_mutex_lock(&LOCK_open);
 
911
  VOID(pthread_mutex_lock(&LOCK_open));
895
912
  error= ha_create_table(thd, path, table_list->db, table_list->table_name,
896
913
                         &create_info, 1);
897
 
  pthread_mutex_unlock(&LOCK_open);
 
914
  VOID(pthread_mutex_unlock(&LOCK_open));
898
915
 
899
916
end:
900
917
  if (!dont_send_ok)
908
925
      write_bin_log(thd, true, thd->query, thd->query_length);
909
926
      my_ok(thd);               // This should return record count
910
927
    }
911
 
    pthread_mutex_lock(&LOCK_open);
 
928
    VOID(pthread_mutex_lock(&LOCK_open));
912
929
    unlock_table_name(thd, table_list);
913
 
    pthread_mutex_unlock(&LOCK_open);
 
930
    VOID(pthread_mutex_unlock(&LOCK_open));
914
931
  }
915
932
  else if (error)
916
933
  {
917
 
    pthread_mutex_lock(&LOCK_open);
 
934
    VOID(pthread_mutex_lock(&LOCK_open));
918
935
    unlock_table_name(thd, table_list);
919
 
    pthread_mutex_unlock(&LOCK_open);
 
936
    VOID(pthread_mutex_unlock(&LOCK_open));
920
937
  }
921
938
  return(error);
922
939
 
930
947
  bool save_binlog_row_based= thd->current_stmt_binlog_row_based;
931
948
  thd->clear_current_stmt_binlog_row_based();
932
949
  error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
933
 
                      HA_POS_ERROR, 0L, true);
 
950
                      HA_POS_ERROR, 0LL, true);
934
951
  ha_enable_transaction(thd, true);
935
952
  /*
936
953
    Safety, in case the engine ignored ha_enable_transaction(false)