~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-11-12 16:13:04 UTC
  • mfrom: (1211.1.7 staging)
  • Revision ID: brian@gaz-20091112161304-opamiauv36fg0n6u
Rollup of Brian, Padraig, and Stewart patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
using namespace std;
50
50
using namespace drizzled;
51
51
 
52
 
/* Functions defined in this file */
 
52
/* Functions defined in this cursor */
53
53
 
54
54
void open_table_error(TableShare *share, int error, int db_errno,
55
55
                      myf errortype, int errarg);
161
161
    field_type= DRIZZLE_TYPE_VARCHAR;
162
162
    break;
163
163
  case message::Table::Field::DECIMAL:
164
 
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
164
    field_type= DRIZZLE_TYPE_DECIMAL;
165
165
    break;
166
166
  case message::Table::Field::ENUM:
167
167
    field_type= DRIZZLE_TYPE_ENUM;
231
231
                                    system_charset_info);
232
232
    }
233
233
    break;
234
 
  case DRIZZLE_TYPE_NEWDECIMAL:
 
234
  case DRIZZLE_TYPE_DECIMAL:
235
235
    default_item= new Item_decimal(default_value->c_str(),
236
236
                                   default_value->length(),
237
237
                                   system_charset_info);
525
525
        interval_parts+= field_options.field_value_size();
526
526
      }
527
527
      break;
528
 
    case DRIZZLE_TYPE_NEWDECIMAL:
 
528
    case DRIZZLE_TYPE_DECIMAL:
529
529
      {
530
530
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
531
531
 
775
775
    }
776
776
 
777
777
    uint8_t decimals= 0;
778
 
    if (field_type == DRIZZLE_TYPE_NEWDECIMAL
 
778
    if (field_type == DRIZZLE_TYPE_DECIMAL
779
779
        || field_type == DRIZZLE_TYPE_DOUBLE)
780
780
    {
781
781
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
820
820
    temp_table.s->db_low_byte_first= 1; //Cursor->low_byte_first();
821
821
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
822
822
 
 
823
    uint32_t field_length;
 
824
 
 
825
    switch (field_type)
 
826
    {
 
827
    case DRIZZLE_TYPE_DOUBLE:
 
828
    {
 
829
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
830
      if (!fo.has_precision() && !fo.has_scale())
 
831
      {
 
832
        field_length= DBL_DIG+7;
 
833
      }
 
834
      else
 
835
      {
 
836
        field_length= fo.precision();
 
837
      }
 
838
      if (field_length < decimals &&
 
839
          decimals != NOT_FIXED_DEC)
 
840
      {
 
841
        my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
 
842
        error= 1;
 
843
        goto err;
 
844
      }
 
845
      break;
 
846
    }
 
847
    case DRIZZLE_TYPE_DECIMAL:
 
848
    {
 
849
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
850
 
 
851
      field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
 
852
                                                   false);
 
853
      break;
 
854
    }
 
855
    default:
 
856
      field_length= pfield.options().length();
 
857
      break;
 
858
    }
 
859
 
823
860
    Field* f= make_field(share,
824
861
                         &share->mem_root,
825
862
                         record + field_offsets[fieldnr] + data_offset,
826
 
                         pfield.options().length(),
 
863
                         field_length,
827
864
                         pfield.has_constraints() && pfield.constraints().is_nullable() ? true : false,
828
865
                         null_pos,
829
866
                         null_bit_pos,
929
966
  free(field_offsets);
930
967
  free(field_pack_length);
931
968
 
932
 
  if (! (handler_file= share->db_type()->getCursor(share, session.mem_root)))
 
969
  if (! (handler_file= share->db_type()->getCursor(*share, session.mem_root)))
933
970
    abort(); // FIXME
934
971
 
935
972
  /* Fix key stuff */
1138
1175
}
1139
1176
 
1140
1177
/*
1141
 
  Read table definition from a binary / text based .frm file
 
1178
  Read table definition from a binary / text based .frm cursor
1142
1179
 
1143
1180
  SYNOPSIS
1144
1181
  open_table_def()
1155
1192
   0    ok
1156
1193
   1    Error (see open_table_error)
1157
1194
   2    Error (see open_table_error)
1158
 
   3    Wrong data in .frm file
 
1195
   3    Wrong data in .frm cursor
1159
1196
   4    Error (see open_table_error)
1160
1197
   5    Error (see open_table_error: charset unavailable)
1161
1198
   6    Unknown .frm version
1234
1271
   0    ok
1235
1272
   1    Error (see open_table_error)
1236
1273
   2    Error (see open_table_error)
1237
 
   3    Wrong data in .frm file
 
1274
   3    Wrong data in .frm cursor
1238
1275
   4    Error (see open_table_error)
1239
1276
   5    Error (see open_table_error: charset unavailable)
1240
1277
   7    Table definition has changed in engine
1263
1300
  /* Allocate Cursor */
1264
1301
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
1265
1302
  {
1266
 
    if (!(outparam->file= share->db_type()->getCursor(share, &outparam->mem_root)))
 
1303
    if (!(outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1267
1304
      goto err;
1268
1305
  }
1269
1306
  else
1398
1435
  if (db_stat && open_mode != OTM_ALTER)
1399
1436
  {
1400
1437
    int ha_err;
1401
 
    if ((ha_err= (outparam->file->
 
1438
    if ((ha_err= (outparam->cursor->
1402
1439
                  ha_open(outparam, share->normalized_path.str,
1403
1440
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1404
1441
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1409
1446
    {
1410
1447
      /* Set a flag if the table is crashed and it can be auto. repaired */
1411
1448
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1412
 
                       outparam->file->auto_repair() &&
 
1449
                       outparam->cursor->auto_repair() &&
1413
1450
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
1414
1451
 
1415
1452
      switch (ha_err)
1417
1454
        case HA_ERR_NO_SUCH_TABLE:
1418
1455
          /*
1419
1456
            The table did not exists in storage engine, use same error message
1420
 
            as if the .frm file didn't exist
 
1457
            as if the .frm cursor didn't exist
1421
1458
          */
1422
1459
          error= 1;
1423
1460
          my_errno= ENOENT;
1425
1462
        case EMFILE:
1426
1463
          /*
1427
1464
            Too many files opened, use same error message as if the .frm
1428
 
            file can't open
 
1465
            cursor can't open
1429
1466
           */
1430
1467
          error= 1;
1431
1468
          my_errno= EMFILE;
1432
1469
          break;
1433
1470
        default:
1434
 
          outparam->file->print_error(ha_err, MYF(0));
 
1471
          outparam->cursor->print_error(ha_err, MYF(0));
1435
1472
          error_reported= true;
1436
1473
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1437
1474
            error= 7;
1452
1489
 err:
1453
1490
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1454
1491
    share->open_table_error(error, my_errno, 0);
1455
 
  delete outparam->file;
1456
 
  outparam->file= 0;                            // For easier error checking
 
1492
  delete outparam->cursor;
 
1493
  outparam->cursor= 0;                          // For easier error checking
1457
1494
  outparam->db_stat= 0;
1458
1495
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1459
1496
  free((char*) outparam->alias);
1480
1517
  int error= 0;
1481
1518
 
1482
1519
  if (db_stat)
1483
 
    error= file->close();
 
1520
    error= cursor->close();
1484
1521
  free((char*) alias);
1485
1522
  alias= NULL;
1486
1523
  if (field)
1489
1526
      delete *ptr;
1490
1527
    field= 0;
1491
1528
  }
1492
 
  delete file;
1493
 
  file= 0;                              /* For easier errorchecking */
 
1529
  delete cursor;
 
1530
  cursor= 0;                            /* For easier errorchecking */
1494
1531
  if (free_share)
1495
1532
  {
1496
1533
    if (s->tmp_table == NO_TMP_TABLE)
1516
1553
}
1517
1554
 
1518
1555
 
1519
 
        /* error message when opening a form file */
 
1556
        /* error message when opening a form cursor */
1520
1557
 
1521
1558
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1522
1559
{
1538
1575
    break;
1539
1576
  case 2:
1540
1577
  {
1541
 
    Cursor *file= 0;
 
1578
    Cursor *cursor= 0;
1542
1579
    const char *datext= "";
1543
1580
 
1544
1581
    if (db_type() != NULL)
1545
1582
    {
1546
 
      if ((file= db_type()->getCursor(this, current_session->mem_root)))
 
1583
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
1547
1584
      {
1548
1585
        if (!(datext= *db_type()->bas_ext()))
1549
1586
          datext= "";
1553
1590
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1554
1591
    sprintf(buff,"%s%s", normalized_path.str,datext);
1555
1592
    my_error(err_no,errortype, buff, db_errno);
1556
 
    delete file;
 
1593
    delete cursor;
1557
1594
    break;
1558
1595
  }
1559
1596
  case 5:
1889
1926
void Table::prepare_for_position()
1890
1927
{
1891
1928
 
1892
 
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
1929
  if ((cursor->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1893
1930
      s->primary_key < MAX_KEY)
1894
1931
  {
1895
1932
    mark_columns_used_by_index_no_reset(s->primary_key);
1912
1949
{
1913
1950
  MyBitmap *bitmap= &tmp_set;
1914
1951
 
1915
 
  (void) file->extra(HA_EXTRA_KEYREAD);
 
1952
  (void) cursor->extra(HA_EXTRA_KEYREAD);
1916
1953
  bitmap->clearAll();
1917
1954
  mark_columns_used_by_index_no_reset(index, bitmap);
1918
1955
  column_bitmaps_set(bitmap, bitmap);
1935
1972
{
1936
1973
 
1937
1974
  key_read= 0;
1938
 
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
 
1975
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
1939
1976
  default_column_bitmaps();
1940
1977
  return;
1941
1978
}
2020
2057
    mark_columns_used_by_index_no_reset(s->primary_key);
2021
2058
 
2022
2059
  /* If we the engine wants all predicates we mark all keys */
2023
 
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
 
2060
  if (cursor->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2024
2061
  {
2025
2062
    Field **reg_field;
2026
2063
    for (reg_field= field ; *reg_field ; reg_field++)
2067
2104
  else
2068
2105
    mark_columns_used_by_index_no_reset(s->primary_key);
2069
2106
 
2070
 
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
 
2107
  if (cursor->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2071
2108
  {
2072
2109
    /* Mark all used key columns for read */
2073
2110
    Field **reg_field;
2551
2588
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2552
2589
  {
2553
2590
    share->storage_engine= myisam_engine;
2554
 
    table->file= share->db_type()->getCursor(share, &table->mem_root);
 
2591
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
2555
2592
    if (group &&
2556
 
        (param->group_parts > table->file->max_key_parts() ||
2557
 
         param->group_length > table->file->max_key_length()))
 
2593
        (param->group_parts > table->cursor->max_key_parts() ||
 
2594
         param->group_length > table->cursor->max_key_length()))
2558
2595
      using_unique_constraint=1;
2559
2596
  }
2560
2597
  else
2561
2598
  {
2562
2599
    share->storage_engine= heap_engine;
2563
 
    table->file= share->db_type()->getCursor(share, &table->mem_root);
 
2600
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
2564
2601
  }
2565
 
  if (!table->file)
 
2602
  if (!table->cursor)
2566
2603
    goto err;
2567
2604
 
2568
2605
 
3041
3078
bool Table::open_tmp_table()
3042
3079
{
3043
3080
  int error;
3044
 
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
3081
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
3045
3082
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3046
3083
  {
3047
 
    file->print_error(error,MYF(0));
 
3084
    cursor->print_error(error,MYF(0));
3048
3085
    db_stat= 0;
3049
3086
    return true;
3050
3087
  }
3051
 
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
3088
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
3052
3089
  return false;
3053
3090
}
3054
3091
 
3101
3138
      goto err;
3102
3139
 
3103
3140
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3104
 
    if (keyinfo->key_length >= file->max_key_length() ||
3105
 
        keyinfo->key_parts > file->max_key_parts() ||
 
3141
    if (keyinfo->key_length >= cursor->max_key_length() ||
 
3142
        keyinfo->key_parts > cursor->max_key_parts() ||
3106
3143
        share->uniques)
3107
3144
    {
3108
3145
      /* Can't create a key; Make a unique constraint instead of a key */
3177
3214
                       &create_info,
3178
3215
                       HA_CREATE_TMP_TABLE)))
3179
3216
  {
3180
 
    file->print_error(error,MYF(0));
 
3217
    cursor->print_error(error,MYF(0));
3181
3218
    db_stat= 0;
3182
3219
    goto err;
3183
3220
  }
3200
3237
  // Release latches since this can take a long time
3201
3238
  plugin::StorageEngine::releaseTemporaryLatches(session);
3202
3239
 
3203
 
  if (file)
 
3240
  if (cursor)
3204
3241
  {
3205
3242
    if (db_stat)
3206
 
      file->closeMarkForDelete(s->table_name.str);
 
3243
      cursor->closeMarkForDelete(s->table_name.str);
3207
3244
 
3208
3245
    s->db_type()->doDropTable(*session, s->table_name.str);
3209
3246
 
3210
 
    delete file;
 
3247
    delete cursor;
3211
3248
  }
3212
3249
 
3213
3250
  /* free blobs */
3237
3274
  if (table->s->db_type() != heap_engine ||
3238
3275
      error != HA_ERR_RECORD_FILE_FULL)
3239
3276
  {
3240
 
    table->file->print_error(error,MYF(0));
 
3277
    table->cursor->print_error(error,MYF(0));
3241
3278
    return true;
3242
3279
  }
3243
3280
 
3248
3285
  share= *table->s;
3249
3286
  new_table.s= &share;
3250
3287
  new_table.s->storage_engine= myisam_engine;
3251
 
  if (!(new_table.file= new_table.s->db_type()->getCursor(&share, &new_table.mem_root)))
 
3288
  if (!(new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
3252
3289
    return true;                                // End of memory
3253
3290
 
3254
3291
  save_proc_info=session->get_proc_info();
3260
3297
    goto err2;
3261
3298
  if (new_table.open_tmp_table())
3262
3299
    goto err1;
3263
 
  if (table->file->indexes_are_disabled())
3264
 
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3265
 
  table->file->ha_index_or_rnd_end();
3266
 
  table->file->ha_rnd_init(1);
 
3300
  if (table->cursor->indexes_are_disabled())
 
3301
    new_table.cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
3302
  table->cursor->ha_index_or_rnd_end();
 
3303
  table->cursor->ha_rnd_init(1);
3267
3304
  if (table->no_rows)
3268
3305
  {
3269
 
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
3306
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
3270
3307
    new_table.no_rows=1;
3271
3308
  }
3272
3309
 
3273
3310
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3274
 
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
3311
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
3275
3312
 
3276
3313
  /*
3277
3314
    copy all old rows from heap table to MyISAM table
3278
3315
    This is the only code that uses record[1] to read/write but this
3279
3316
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3280
3317
  */
3281
 
  while (!table->file->rnd_next(new_table.record[1]))
 
3318
  while (!table->cursor->rnd_next(new_table.record[1]))
3282
3319
  {
3283
 
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
3320
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
3284
3321
    if (write_err)
3285
3322
      goto err;
3286
3323
  }
3287
3324
  /* copy row that filled HEAP table */
3288
 
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
3325
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
3289
3326
  {
3290
 
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
3327
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
3291
3328
        !ignore_last_dupp_key_error)
3292
3329
      goto err;
3293
3330
  }
3294
3331
 
3295
3332
  /* remove heap table and change to use myisam table */
3296
 
  (void) table->file->ha_rnd_end();
3297
 
  (void) table->file->close();                  // This deletes the table !
3298
 
  delete table->file;
3299
 
  table->file= NULL;
 
3333
  (void) table->cursor->ha_rnd_end();
 
3334
  (void) table->cursor->close();                  // This deletes the table !
 
3335
  delete table->cursor;
 
3336
  table->cursor= NULL;
3300
3337
  new_table.s= table->s;                       // Keep old share
3301
3338
  *table= new_table;
3302
3339
  *table->s= share;
3303
3340
 
3304
 
  table->file->change_table_ptr(table, table->s);
 
3341
  table->cursor->change_table_ptr(table, table->s);
3305
3342
  table->use_all_columns();
3306
3343
  if (save_proc_info)
3307
3344
  {
3313
3350
  return false;
3314
3351
 
3315
3352
 err:
3316
 
  table->file->print_error(write_err, MYF(0));
3317
 
  (void) table->file->ha_rnd_end();
3318
 
  (void) new_table.file->close();
 
3353
  table->cursor->print_error(write_err, MYF(0));
 
3354
  (void) table->cursor->ha_rnd_end();
 
3355
  (void) new_table.cursor->close();
3319
3356
 err1:
3320
3357
  new_table.s->db_type()->doDropTable(*session, new_table.s->table_name.str);
3321
3358
 err2:
3322
 
  delete new_table.file;
 
3359
  delete new_table.cursor;
3323
3360
  session->set_proc_info(save_proc_info);
3324
3361
  table->mem_root= new_table.mem_root;
3325
3362
  return true;
3473
3510
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3474
3511
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
3475
3512
                    error, s->path.str);
3476
 
  file->print_error(error,MYF(0));
 
3513
  cursor->print_error(error,MYF(0));
3477
3514
 
3478
3515
  return 1;
3479
3516
}