~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_insert.cc

Merged in from trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
  Drizzle has a different form of DELAYED then MySQL. DELAYED is just
23
23
  a hint to the the sorage engine (which can then do whatever it likes.
24
24
*/
25
 
#include <drizzled/server_includes.h>
26
 
#include <drizzled/sql_select.h>
27
 
#include <drizzled/sql_show.h>
 
25
 
 
26
#include "mysql_priv.h"
 
27
#include "sql_select.h"
 
28
#include "sql_show.h"
 
29
#include "slave.h"
28
30
#include "rpl_mi.h"
29
 
#include <drizzled/drizzled_error_messages.h>
30
31
 
31
32
/* Define to force use of my_malloc() if the allocated memory block is big */
32
33
 
34
35
#define my_safe_alloca(size, min_length) my_alloca(size)
35
36
#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
36
37
#else
37
 
#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : malloc(size))
38
 
#define my_safe_afree(ptr, size, min_length) if (size > min_length) free(ptr)
 
38
#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
 
39
#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0))
39
40
#endif
40
41
 
41
42
 
61
62
    -1          Error
62
63
*/
63
64
 
64
 
static int check_insert_fields(THD *thd, TableList *table_list,
 
65
static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
65
66
                               List<Item> &fields, List<Item> &values,
66
67
                               bool check_unique,
67
 
                               table_map *map __attribute__((unused)))
 
68
                               table_map *map __attribute__((__unused__)))
68
69
{
69
 
  Table *table= table_list->table;
 
70
  TABLE *table= table_list->table;
70
71
 
71
72
  if (fields.elements == 0 && values.elements != 0)
72
73
  {
97
98
    }
98
99
 
99
100
    thd->dup_field= 0;
 
101
    select_lex->no_wrap_view_item= TRUE;
100
102
 
101
103
    /* Save the state of the current name resolution context. */
102
104
    ctx_state.save_state(context, table_list);
111
113
 
112
114
    /* Restore the current context. */
113
115
    ctx_state.restore_state(context, table_list);
 
116
    thd->lex->select_lex.no_wrap_view_item= FALSE;
114
117
 
115
118
    if (res)
116
119
      return -1;
157
160
    -1          Error
158
161
*/
159
162
 
160
 
static int check_update_fields(THD *thd, TableList *insert_table_list,
 
163
static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
161
164
                               List<Item> &update_fields,
162
 
                               table_map *map __attribute__((unused)))
 
165
                               table_map *map __attribute__((__unused__)))
163
166
{
164
 
  Table *table= insert_table_list->table;
165
 
  bool timestamp_mark= false;
 
167
  TABLE *table= insert_table_list->table;
 
168
  my_bool timestamp_mark= false;
166
169
 
167
170
  if (table->timestamp_field)
168
171
  {
202
205
*/
203
206
 
204
207
static
205
 
void upgrade_lock_type(THD *thd __attribute__((unused)),
 
208
void upgrade_lock_type(THD *thd __attribute__((__unused__)),
206
209
                       thr_lock_type *lock_type,
207
210
                       enum_duplicates duplic,
208
 
                       bool is_multi_insert __attribute__((unused)))
 
211
                       bool is_multi_insert __attribute__((__unused__)))
209
212
{
210
213
  if (duplic == DUP_UPDATE ||
211
214
      (duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT))
224
227
  end of dispatch_command().
225
228
*/
226
229
 
227
 
bool mysql_insert(THD *thd,TableList *table_list,
 
230
bool mysql_insert(THD *thd,TABLE_LIST *table_list,
228
231
                  List<Item> &fields,
229
232
                  List<List_item> &values_list,
230
233
                  List<Item> &update_fields,
233
236
                  bool ignore)
234
237
{
235
238
  int error;
236
 
  bool transactional_table, joins_freed= false;
 
239
  bool transactional_table, joins_freed= FALSE;
237
240
  bool changed;
238
241
  bool was_insert_delayed= (table_list->lock_type ==  TL_WRITE_DELAYED);
239
 
  uint32_t value_count;
 
242
  uint value_count;
240
243
  ulong counter = 1;
241
244
  uint64_t id;
242
245
  COPY_INFO info;
243
 
  Table *table= 0;
 
246
  TABLE *table= 0;
244
247
  List_iterator_fast<List_item> its(values_list);
245
248
  List_item *values;
246
249
  Name_resolution_context *context;
267
270
  {
268
271
    my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0),
269
272
             table_list->table_name);
270
 
    return(true);
 
273
    return(TRUE);
271
274
  }
272
275
 
273
276
  {
274
277
    if (open_and_lock_tables(thd, table_list))
275
 
      return(true);
 
278
      return(TRUE);
276
279
  }
277
280
  lock_type= table_list->lock_type;
278
281
 
283
286
 
284
287
  if (mysql_prepare_insert(thd, table_list, table, fields, values,
285
288
                           update_fields, update_values, duplic, &unused_conds,
286
 
                           false,
 
289
                           FALSE,
287
290
                           (fields.elements || !value_count ||
288
291
                            (0) != 0), !ignore))
289
292
    goto abort;
330
333
  /*
331
334
    Fill in the given fields and dump it to the table file
332
335
  */
333
 
  memset(&info, 0, sizeof(info));
 
336
  bzero((char*) &info,sizeof(info));
334
337
  info.ignore= ignore;
335
338
  info.handle_duplicates=duplic;
336
339
  info.update_fields= &update_fields;
348
351
  thd->cuted_fields = 0L;
349
352
  table->next_number_field=table->found_next_number_field;
350
353
 
 
354
#ifdef HAVE_REPLICATION
351
355
  if (thd->slave_thread &&
352
356
      (info.handle_duplicates == DUP_UPDATE) &&
353
357
      (table->next_number_field != NULL) &&
354
358
      rpl_master_has_bug(&active_mi->rli, 24432))
355
359
    goto abort;
 
360
#endif
356
361
 
357
362
  error=0;
358
363
  thd_proc_info(thd, "update");
424
429
  }
425
430
 
426
431
  free_underlaid_joins(thd, &thd->lex->select_lex);
427
 
  joins_freed= true;
 
432
  joins_freed= TRUE;
428
433
 
429
434
  /*
430
435
    Now all rows are inserted.  Time to update logs and sends response to
433
438
  {
434
439
    /*
435
440
      Do not do this release if this is a delayed insert, it would steal
436
 
      auto_inc values from the delayed_insert thread as they share Table.
 
441
      auto_inc values from the delayed_insert thread as they share TABLE.
437
442
    */
438
443
    table->file->ha_release_auto_increment();
439
444
    if (table->file->ha_end_bulk_insert() && !error)
487
492
        assert(thd->killed != THD::KILL_BAD_DATA || error > 0);
488
493
        if (thd->binlog_query(THD::ROW_QUERY_TYPE,
489
494
                              thd->query, thd->query_length,
490
 
                              transactional_table, false,
 
495
                              transactional_table, FALSE,
491
496
                              (error>0) ? thd->killed : THD::NOT_KILLED) &&
492
497
            transactional_table)
493
498
        {
495
500
        }
496
501
      }
497
502
      if (thd->transaction.stmt.modified_non_trans_table)
498
 
        thd->transaction.all.modified_non_trans_table= true;
 
503
        thd->transaction.all.modified_non_trans_table= TRUE;
499
504
    }
500
505
    assert(transactional_table || !changed || 
501
506
                thd->transaction.stmt.modified_non_trans_table);
520
525
     table->next_number_field->val_int() : 0));
521
526
  table->next_number_field=0;
522
527
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
523
 
  table->auto_increment_field_not_null= false;
 
528
  table->auto_increment_field_not_null= FALSE;
524
529
  if (duplic == DUP_REPLACE)
525
530
    table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
526
531
 
549
554
    ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
550
555
  }
551
556
  thd->abort_on_warning= 0;
552
 
  DRIZZLE_INSERT_END();
553
 
  return(false);
 
557
  MYSQL_INSERT_END();
 
558
  return(FALSE);
554
559
 
555
560
abort:
556
561
  if (table != NULL)
558
563
  if (!joins_freed)
559
564
    free_underlaid_joins(thd, &thd->lex->select_lex);
560
565
  thd->abort_on_warning= 0;
561
 
  DRIZZLE_INSERT_END();
562
 
  return(true);
 
566
  MYSQL_INSERT_END();
 
567
  return(TRUE);
563
568
}
564
569
 
565
570
 
575
580
     select_insert      Check is making for SELECT ... INSERT
576
581
 
577
582
   RETURN
578
 
     false ok
579
 
     true  ERROR
 
583
     FALSE ok
 
584
     TRUE  ERROR
580
585
*/
581
586
 
582
 
static bool mysql_prepare_insert_check_table(THD *thd, TableList *table_list,
583
 
                                             List<Item> &fields __attribute__((unused)),
 
587
static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
 
588
                                             List<Item> &fields __attribute__((__unused__)),
584
589
                                             bool select_insert)
585
590
{
586
591
  
597
602
                                    table_list,
598
603
                                    &thd->lex->select_lex.leaf_tables,
599
604
                                    select_insert))
600
 
    return(true);
 
605
    return(TRUE);
601
606
 
602
 
  return(false);
 
607
  return(FALSE);
603
608
}
604
609
 
605
610
 
613
618
    table               Table to insert into (can be NULL if table should
614
619
                        be taken from table_list->table)    
615
620
    where               Where clause (for insert ... select)
616
 
    select_insert       true if INSERT ... SELECT statement
617
 
    check_fields        true if need to check that all INSERT fields are 
 
621
    select_insert       TRUE if INSERT ... SELECT statement
 
622
    check_fields        TRUE if need to check that all INSERT fields are 
618
623
                        given values.
619
624
    abort_on_warning    whether to report if some INSERT field is not 
620
 
                        assigned as an error (true) or as a warning (false).
 
625
                        assigned as an error (TRUE) or as a warning (FALSE).
621
626
 
622
627
  TODO (in far future)
623
628
    In cases of:
630
635
    before releasing the table object.
631
636
  
632
637
  RETURN VALUE
633
 
    false OK
634
 
    true  error
 
638
    FALSE OK
 
639
    TRUE  error
635
640
*/
636
641
 
637
 
bool mysql_prepare_insert(THD *thd, TableList *table_list,
638
 
                          Table *table, List<Item> &fields, List_item *values,
 
642
bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
 
643
                          TABLE *table, List<Item> &fields, List_item *values,
639
644
                          List<Item> &update_fields, List<Item> &update_values,
640
645
                          enum_duplicates duplic,
641
 
                          COND **where __attribute__((unused)),
 
646
                          COND **where __attribute__((__unused__)),
642
647
                          bool select_insert,
643
648
                          bool check_fields, bool abort_on_warning)
644
649
{
676
681
  {
677
682
    /* it should be allocated before Item::fix_fields() */
678
683
    if (table_list->set_insert_values(thd->mem_root))
679
 
      return(true);
 
684
      return(TRUE);
680
685
  }
681
686
 
682
687
  if (mysql_prepare_insert_check_table(thd, table_list, fields, select_insert))
683
 
    return(true);
 
688
    return(TRUE);
684
689
 
685
690
 
686
691
  /* Prepare the fields in the statement. */
716
721
 
717
722
    if (!res && duplic == DUP_UPDATE)
718
723
    {
 
724
      select_lex->no_wrap_view_item= TRUE;
719
725
      res= check_update_fields(thd, context->table_list, update_fields, &map);
 
726
      select_lex->no_wrap_view_item= FALSE;
720
727
    }
721
728
 
722
729
    /* Restore the current context. */
734
741
 
735
742
  if (!select_insert)
736
743
  {
737
 
    TableList *duplicate;
 
744
    Item *fake_conds= 0;
 
745
    TABLE_LIST *duplicate;
738
746
    if ((duplicate= unique_table(thd, table_list, table_list->next_global, 1)))
739
747
    {
740
748
      update_non_unique_table_error(table_list, "INSERT", duplicate);
741
 
      return(true);
 
749
      return(TRUE);
742
750
    }
 
751
    select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
 
752
    select_lex->first_execution= 0;
743
753
  }
744
754
  if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
745
755
    table->prepare_for_position();
746
 
  return(false);
 
756
  return(FALSE);
747
757
}
748
758
 
749
759
 
750
760
        /* Check if there is more uniq keys after field */
751
761
 
752
 
static int last_uniq_key(Table *table,uint32_t keynr)
 
762
static int last_uniq_key(TABLE *table,uint keynr)
753
763
{
754
764
  while (++keynr < table->s->keys)
755
765
    if (table->key_info[keynr].flags & HA_NOSAME)
776
786
    then both on update triggers will work instead. Similarly both on
777
787
    delete triggers will be invoked if we will delete conflicting records.
778
788
 
779
 
    Sets thd->transaction.stmt.modified_non_trans_table to true if table which is updated didn't have
 
789
    Sets thd->transaction.stmt.modified_non_trans_table to TRUE if table which is updated didn't have
780
790
    transactions.
781
791
 
782
792
  RETURN VALUE
785
795
*/
786
796
 
787
797
 
788
 
int write_record(THD *thd, Table *table,COPY_INFO *info)
 
798
int write_record(THD *thd, TABLE *table,COPY_INFO *info)
789
799
{
790
800
  int error;
791
801
  char *key=0;
803
813
  {
804
814
    while ((error=table->file->ha_write_row(table->record[0])))
805
815
    {
806
 
      uint32_t key_nr;
 
816
      uint key_nr;
807
817
      /*
808
818
        If we do more than one iteration of this loop, from the second one the
809
819
        row will have an explicit value in the autoinc field, which was set at
869
879
            goto err;
870
880
          }
871
881
        }
872
 
        key_copy((unsigned char*) key,table->record[0],table->key_info+key_nr,0);
 
882
        key_copy((uchar*) key,table->record[0],table->key_info+key_nr,0);
873
883
        if ((error=(table->file->index_read_idx_map(table->record[1],key_nr,
874
 
                                                    (unsigned char*) key, HA_WHOLE_KEY,
 
884
                                                    (uchar*) key, HA_WHOLE_KEY,
875
885
                                                    HA_READ_KEY_EXACT))))
876
886
          goto err;
877
887
      }
899
909
        info->touched++;
900
910
        if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
901
911
             !bitmap_is_subset(table->write_set, table->read_set)) ||
902
 
            table->compare_record())
 
912
            compare_record(table))
903
913
        {
904
914
          if ((error=table->file->ha_update_row(table->record[1],
905
915
                                                table->record[0])) &&
977
987
            goto err;
978
988
          info->deleted++;
979
989
          if (!table->file->has_transactions())
980
 
            thd->transaction.stmt.modified_non_trans_table= true;
 
990
            thd->transaction.stmt.modified_non_trans_table= TRUE;
981
991
          /* Let us attempt do write_row() once more */
982
992
        }
983
993
      }
1008
1018
  if (key)
1009
1019
    my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH);
1010
1020
  if (!table->file->has_transactions())
1011
 
    thd->transaction.stmt.modified_non_trans_table= true;
 
1021
    thd->transaction.stmt.modified_non_trans_table= TRUE;
1012
1022
  return(0);
1013
1023
 
1014
1024
err:
1031
1041
  Check that all fields with arn't null_fields are used
1032
1042
******************************************************************************/
1033
1043
 
1034
 
int check_that_all_fields_are_given_values(THD *thd, Table *entry,
1035
 
                                           TableList *table_list)
 
1044
int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
 
1045
                                           TABLE_LIST *table_list)
1036
1046
{
1037
1047
  int err= 0;
1038
1048
  MY_BITMAP *write_set= entry->write_set;
1041
1051
  {
1042
1052
    if (!bitmap_is_set(write_set, (*field)->field_index) &&
1043
1053
        ((*field)->flags & NO_DEFAULT_VALUE_FLAG) &&
1044
 
        ((*field)->real_type() != DRIZZLE_TYPE_ENUM))
 
1054
        ((*field)->real_type() != MYSQL_TYPE_ENUM))
1045
1055
    {
1046
 
      bool view= false;
 
1056
      bool view= FALSE;
1047
1057
      if (table_list)
1048
1058
      {
1049
1059
        table_list= table_list->top_table();
1050
1060
        view= test(0);
1051
1061
      }
1052
1062
      {
1053
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
1063
        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1054
1064
                            ER_NO_DEFAULT_FOR_FIELD,
1055
1065
                            ER(ER_NO_DEFAULT_FOR_FIELD),
1056
1066
                            (*field)->field_name);
1074
1084
    thd         thread handler
1075
1085
 
1076
1086
  RETURN
1077
 
    false OK
1078
 
    true  Error
 
1087
    FALSE OK
 
1088
    TRUE  Error
1079
1089
*/
1080
1090
 
1081
1091
bool mysql_insert_select_prepare(THD *thd)
1082
1092
{
1083
1093
  LEX *lex= thd->lex;
1084
1094
  SELECT_LEX *select_lex= &lex->select_lex;
 
1095
  TABLE_LIST *first_select_leaf_table;
1085
1096
  
1086
1097
 
1087
1098
  /*
1106
1117
                           lex->query_tables->table, lex->field_list, 0,
1107
1118
                           lex->update_list, lex->value_list,
1108
1119
                           lex->duplicates,
1109
 
                           &select_lex->where, true, false, false))
1110
 
    return(true);
 
1120
                           &select_lex->where, TRUE, FALSE, FALSE))
 
1121
    return(TRUE);
1111
1122
 
1112
1123
  /*
1113
1124
    exclude first table from leaf tables list, because it belong to
1116
1127
  assert(select_lex->leaf_tables != 0);
1117
1128
  lex->leaf_tables_insert= select_lex->leaf_tables;
1118
1129
  /* skip all leaf tables belonged to view where we are insert */
1119
 
  select_lex->leaf_tables= select_lex->leaf_tables->next_leaf;
1120
 
  return(false);
 
1130
  for (first_select_leaf_table= select_lex->leaf_tables->next_leaf;
 
1131
       first_select_leaf_table &&
 
1132
       first_select_leaf_table->belong_to_view &&
 
1133
       first_select_leaf_table->belong_to_view ==
 
1134
       lex->leaf_tables_insert->belong_to_view;
 
1135
       first_select_leaf_table= first_select_leaf_table->next_leaf)
 
1136
  {}
 
1137
  select_lex->leaf_tables= first_select_leaf_table;
 
1138
  return(FALSE);
1121
1139
}
1122
1140
 
1123
1141
 
1124
 
select_insert::select_insert(TableList *table_list_par, Table *table_par,
 
1142
select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par,
1125
1143
                             List<Item> *fields_par,
1126
1144
                             List<Item> *update_fields,
1127
1145
                             List<Item> *update_values,
1131
1149
   autoinc_value_of_last_inserted_row(0),
1132
1150
   insert_into_view(table_list_par && 0 != 0)
1133
1151
{
1134
 
  memset(&info, 0, sizeof(info));
 
1152
  bzero((char*) &info,sizeof(info));
1135
1153
  info.handle_duplicates= duplic;
1136
1154
  info.ignore= ignore_check_option_errors;
1137
1155
  info.update_fields= update_fields;
1181
1199
    table_list->next_local= 0;
1182
1200
    context->resolve_in_table_list_only(table_list);
1183
1201
 
 
1202
    lex->select_lex.no_wrap_view_item= TRUE;
1184
1203
    res= res || check_update_fields(thd, context->table_list,
1185
1204
                                    *info.update_fields, &map);
 
1205
    lex->select_lex.no_wrap_view_item= FALSE;
1186
1206
    /*
1187
1207
      When we are not using GROUP BY and there are no ungrouped aggregate functions 
1188
1208
      we can refer to other tables in the ON DUPLICATE KEY part.
1215
1235
      while ((item= li++))
1216
1236
      {
1217
1237
        item->transform(&Item::update_value_transformer,
1218
 
                        (unsigned char*)lex->current_select);
 
1238
                        (uchar*)lex->current_select);
1219
1239
      }
1220
1240
    }
1221
1241
 
1258
1278
  restore_record(table,s->default_values);              // Get empty record
1259
1279
  table->next_number_field=table->found_next_number_field;
1260
1280
 
 
1281
#ifdef HAVE_REPLICATION
1261
1282
  if (thd->slave_thread &&
1262
1283
      (info.handle_duplicates == DUP_UPDATE) &&
1263
1284
      (table->next_number_field != NULL) &&
1264
1285
      rpl_master_has_bug(&active_mi->rli, 24432))
1265
1286
    return(1);
 
1287
#endif
1266
1288
 
1267
1289
  thd->cuted_fields=0;
1268
1290
  if (info.ignore || info.handle_duplicates != DUP_ERROR)
1316
1338
  if (table)
1317
1339
  {
1318
1340
    table->next_number_field=0;
1319
 
    table->auto_increment_field_not_null= false;
 
1341
    table->auto_increment_field_not_null= FALSE;
1320
1342
    table->file->ha_reset();
1321
1343
  }
1322
1344
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
1386
1408
    fill_record(thd, table->field, values, 1);
1387
1409
}
1388
1410
 
1389
 
void select_insert::send_error(uint32_t errcode,const char *err)
 
1411
void select_insert::send_error(uint errcode,const char *err)
1390
1412
{
1391
1413
  
1392
1414
 
1415
1437
      and ha_autocommit_or_rollback.
1416
1438
    */
1417
1439
    if (thd->transaction.stmt.modified_non_trans_table)
1418
 
      thd->transaction.all.modified_non_trans_table= true;
 
1440
      thd->transaction.all.modified_non_trans_table= TRUE;
1419
1441
  }
1420
1442
  assert(trans_table || !changed || 
1421
1443
              thd->transaction.stmt.modified_non_trans_table);
1432
1454
      thd->clear_error();
1433
1455
    thd->binlog_query(THD::ROW_QUERY_TYPE,
1434
1456
                      thd->query, thd->query_length,
1435
 
                      trans_table, false, killed_status);
 
1457
                      trans_table, FALSE, killed_status);
1436
1458
  }
1437
1459
  table->file->ha_release_auto_increment();
1438
1460
 
1496
1518
    {
1497
1519
        if (mysql_bin_log.is_open())
1498
1520
          thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
1499
 
                            transactional_table, false);
 
1521
                            transactional_table, FALSE);
1500
1522
        if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
1501
 
          thd->transaction.all.modified_non_trans_table= true;
 
1523
          thd->transaction.all.modified_non_trans_table= TRUE;
1502
1524
    }
1503
1525
    assert(transactional_table || !changed ||
1504
1526
                thd->transaction.stmt.modified_non_trans_table);
1514
1536
***************************************************************************/
1515
1537
 
1516
1538
/*
1517
 
  Create table from lists of fields and items (or just return Table
 
1539
  Create table from lists of fields and items (or just return TABLE
1518
1540
  object for pre-opened existing table).
1519
1541
 
1520
1542
  SYNOPSIS
1522
1544
      thd          in     Thread object
1523
1545
      create_info  in     Create information (like MAX_ROWS, ENGINE or
1524
1546
                          temporary table flag)
1525
 
      create_table in     Pointer to TableList object providing database
 
1547
      create_table in     Pointer to TABLE_LIST object providing database
1526
1548
                          and name for table to be created or to be open
1527
1549
      alter_info   in/out Initial list of columns and indexes for the table
1528
1550
                          to be created
1529
1551
      items        in     List of items which should be used to produce rest
1530
1552
                          of fields for the table (corresponding fields will
1531
1553
                          be added to the end of alter_info->create_list)
1532
 
      lock         out    Pointer to the DRIZZLE_LOCK object for table created
 
1554
      lock         out    Pointer to the MYSQL_LOCK object for table created
1533
1555
                          (or open temporary table) will be returned in this
1534
1556
                          parameter. Since this table is not included in
1535
1557
                          THD::lock caller is responsible for explicitly
1540
1562
    This function behaves differently for base and temporary tables:
1541
1563
    - For base table we assume that either table exists and was pre-opened
1542
1564
      and locked at open_and_lock_tables() stage (and in this case we just
1543
 
      emit error or warning and return pre-opened Table object) or special
 
1565
      emit error or warning and return pre-opened TABLE object) or special
1544
1566
      placeholder was put in table cache that guarantees that this table
1545
1567
      won't be created or opened until the placeholder will be removed
1546
1568
      (so there is an exclusive lock on this table).
1551
1573
    SELECT it should be changed before it can be used in other contexts.
1552
1574
 
1553
1575
  RETURN VALUES
1554
 
    non-zero  Pointer to Table object for table created or opened
 
1576
    non-zero  Pointer to TABLE object for table created or opened
1555
1577
    0         Error
1556
1578
*/
1557
1579
 
1558
 
static Table *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
1559
 
                                      TableList *create_table,
 
1580
static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
 
1581
                                      TABLE_LIST *create_table,
1560
1582
                                      Alter_info *alter_info,
1561
1583
                                      List<Item> *items,
1562
 
                                      DRIZZLE_LOCK **lock,
 
1584
                                      MYSQL_LOCK **lock,
1563
1585
                                      TABLEOP_HOOKS *hooks)
1564
1586
{
1565
 
  Table tmp_table;              // Used during 'Create_field()'
 
1587
  TABLE tmp_table;              // Used during 'Create_field()'
1566
1588
  TABLE_SHARE share;
1567
 
  Table *table= 0;
1568
 
  uint32_t select_field_count= items->elements;
 
1589
  TABLE *table= 0;
 
1590
  uint select_field_count= items->elements;
1569
1591
  /* Add selected items to field list */
1570
1592
  List_iterator_fast<Item> it(*items);
1571
1593
  Item *item;
1579
1601
    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
1580
1602
    {
1581
1603
      create_info->table_existed= 1;            // Mark that table existed
1582
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1604
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1583
1605
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1584
1606
                          create_table->table_name);
1585
1607
      return(create_table->table);
1599
1621
  tmp_table.s->db_low_byte_first= 
1600
1622
        test(create_info->db_type == myisam_hton ||
1601
1623
             create_info->db_type == heap_hton);
1602
 
  tmp_table.null_row= false;
1603
 
  tmp_table.maybe_null= false;
 
1624
  tmp_table.null_row=tmp_table.maybe_null=0;
1604
1625
 
1605
1626
  while ((item=it++))
1606
1627
  {
1638
1659
    binlog when a HEAP table is opened for the first time since startup, must
1639
1660
    not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
1640
1661
    don't want to delete from it) 2) it would be written before the CREATE
1641
 
    Table, which is a wrong order. So we keep binary logging disabled when we
 
1662
    TABLE, which is a wrong order. So we keep binary logging disabled when we
1642
1663
    open_table().
1643
1664
  */
1644
1665
  {
1662
1683
 
1663
1684
      if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
1664
1685
      {
1665
 
        pthread_mutex_lock(&LOCK_open);
1666
 
        if (reopen_name_locked_table(thd, create_table, false))
 
1686
        VOID(pthread_mutex_lock(&LOCK_open));
 
1687
        if (reopen_name_locked_table(thd, create_table, FALSE))
1667
1688
        {
1668
1689
          quick_rm_table(create_info->db_type, create_table->db,
1669
1690
                         table_case_name(create_info, create_table->table_name),
1671
1692
        }
1672
1693
        else
1673
1694
          table= create_table->table;
1674
 
        pthread_mutex_unlock(&LOCK_open);
 
1695
        VOID(pthread_mutex_unlock(&LOCK_open));
1675
1696
      }
1676
1697
      else
1677
1698
      {
1678
 
        if (!(table= open_table(thd, create_table, (bool*) 0,
1679
 
                                DRIZZLE_OPEN_TEMPORARY_ONLY)) &&
 
1699
        if (!(table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
 
1700
                                MYSQL_OPEN_TEMPORARY_ONLY)) &&
1680
1701
            !create_info->table_existed)
1681
1702
        {
1682
1703
          /*
1696
1717
  table->reginfo.lock_type=TL_WRITE;
1697
1718
  hooks->prelock(&table, 1);                    // Call prelock hooks
1698
1719
  if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
1699
 
                                    DRIZZLE_LOCK_IGNORE_FLUSH, &not_used)) ||
 
1720
                                    MYSQL_LOCK_IGNORE_FLUSH, &not_used)) ||
1700
1721
        hooks->postlock(&table, 1))
1701
1722
  {
1702
1723
    if (*lock)
1716
1737
int
1717
1738
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
1718
1739
{
1719
 
  DRIZZLE_LOCK *extra_lock= NULL;
 
1740
  MYSQL_LOCK *extra_lock= NULL;
1720
1741
  
1721
1742
 
1722
1743
  TABLEOP_HOOKS *hook_ptr= NULL;
1740
1761
   */
1741
1762
  class MY_HOOKS : public TABLEOP_HOOKS {
1742
1763
  public:
1743
 
    MY_HOOKS(select_create *x, TableList *create_table,
1744
 
             TableList *select_tables)
 
1764
    MY_HOOKS(select_create *x, TABLE_LIST *create_table,
 
1765
             TABLE_LIST *select_tables)
1745
1766
      : ptr(x), all_tables(*create_table)
1746
1767
      {
1747
1768
        all_tables.next_global= select_tables;
1748
1769
      }
1749
1770
 
1750
1771
  private:
1751
 
    virtual int do_postlock(Table **tables, uint32_t count)
 
1772
    virtual int do_postlock(TABLE **tables, uint count)
1752
1773
    {
1753
1774
      THD *thd= const_cast<THD*>(ptr->get_thd());
1754
1775
      if (int error= decide_logging_format(thd, &all_tables))
1755
1776
        return error;
1756
1777
 
1757
 
      Table const *const table = *tables;
 
1778
      TABLE const *const table = *tables;
1758
1779
      if (thd->current_stmt_binlog_row_based  &&
1759
1780
          !table->s->tmp_table &&
1760
1781
          !ptr->get_create_info()->table_existed)
1765
1786
    }
1766
1787
 
1767
1788
    select_create *ptr;
1768
 
    TableList all_tables;
 
1789
    TABLE_LIST all_tables;
1769
1790
  };
1770
1791
 
1771
1792
  MY_HOOKS hooks(this, create_table, select_tables);
1836
1857
}
1837
1858
 
1838
1859
void
1839
 
select_create::binlog_show_create_table(Table **tables, uint32_t count)
 
1860
select_create::binlog_show_create_table(TABLE **tables, uint count)
1840
1861
{
1841
1862
  /*
1842
1863
    Note 1: In RBR mode, we generate a CREATE TABLE statement for the
1861
1882
  char buf[2048];
1862
1883
  String query(buf, sizeof(buf), system_charset_info);
1863
1884
  int result;
1864
 
  TableList tmp_table_list;
 
1885
  TABLE_LIST tmp_table_list;
1865
1886
 
1866
1887
  memset(&tmp_table_list, 0, sizeof(tmp_table_list));
1867
1888
  tmp_table_list.table = *tables;
1872
1893
 
1873
1894
  thd->binlog_query(THD::STMT_QUERY_TYPE,
1874
1895
                    query.ptr(), query.length(),
1875
 
                    /* is_trans */ true,
1876
 
                    /* suppress_use */ false);
 
1896
                    /* is_trans */ TRUE,
 
1897
                    /* suppress_use */ FALSE);
1877
1898
}
1878
1899
 
1879
1900
void select_create::store_values(List<Item> &values)
1882
1903
}
1883
1904
 
1884
1905
 
1885
 
void select_create::send_error(uint32_t errcode,const char *err)
 
1906
void select_create::send_error(uint errcode,const char *err)
1886
1907
{
1887
1908
  
1888
1909
 
1957
1978
  */
1958
1979
  tmp_disable_binlog(thd);
1959
1980
  select_insert::abort();
1960
 
  thd->transaction.stmt.modified_non_trans_table= false;
 
1981
  thd->transaction.stmt.modified_non_trans_table= FALSE;
1961
1982
  reenable_binlog(thd);
1962
1983
 
1963
1984