~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Stewart Smith
  • Date: 2009-02-10 07:06:51 UTC
  • mto: (869.1.8 nofrm)
  • mto: This revision was merged to the branch mainline in revision 870.
  • Revision ID: stewart@flamingspork.com-20090210070651-3m431t44s3j38l0z
move table proto parsing off into own function. Handle errors in reading and parsing table proto, returning correct error to user. fix tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
282
282
  return;
283
283
}
284
284
 
 
285
int parse_table_proto(Session *session, drizzle::Table &table, TABLE_SHARE *share)
 
286
{
 
287
  {
 
288
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
289
                              strlen(table.engine().name().c_str()) };
 
290
    share->db_plugin= ha_resolve_by_name(session, &engine_name);
 
291
  }
 
292
 
 
293
  // share->db_create_options FAIL
 
294
  // share->db_options_in_use FAIL
 
295
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
296
  share->null_field_first= 0;
 
297
 
 
298
  drizzle::Table::TableOptions table_options;
 
299
 
 
300
  if(table.has_options())
 
301
    table_options= table.options();
 
302
 
 
303
  share->avg_row_length= table_options.has_avg_row_length() ?
 
304
    table_options.avg_row_length() : 0;
 
305
 
 
306
  share->page_checksum= table_options.has_page_checksum() ?
 
307
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
308
    : HA_CHOICE_UNDEF;
 
309
 
 
310
  share->row_type= table_options.has_row_type() ?
 
311
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
312
 
 
313
  share->block_size= table_options.has_block_size() ?
 
314
    table_options.block_size() : 0;
 
315
 
 
316
  share->table_charset= get_charset(table_options.has_collation_id()?
 
317
                                    table_options.collation_id() : 0);
 
318
 
 
319
  if (!share->table_charset)
 
320
  {
 
321
    /* unknown charset in head[38] or pre-3.23 frm */
 
322
    if (use_mb(default_charset_info))
 
323
    {
 
324
      /* Warn that we may be changing the size of character columns */
 
325
      errmsg_printf(ERRMSG_LVL_WARN,
 
326
                    _("'%s' had no or invalid character set, "
 
327
                      "and default character set is multi-byte, "
 
328
                      "so character column sizes may have changed"),
 
329
                    share->path.str);
 
330
    }
 
331
    share->table_charset= default_charset_info;
 
332
  }
 
333
 
 
334
  share->null_field_first= 1;
 
335
 
 
336
  share->db_record_offset= 1;
 
337
 
 
338
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
339
 
 
340
  share->db_low_byte_first= true;
 
341
 
 
342
  share->max_rows= table_options.has_max_rows() ?
 
343
    table_options.max_rows() : 0;
 
344
 
 
345
  share->min_rows= table_options.has_min_rows() ?
 
346
    table_options.min_rows() : 0;
 
347
 
 
348
  share->keys= table.indexes_size();
 
349
 
 
350
  share->key_parts= 0;
 
351
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
352
    share->key_parts+= table.indexes(indx).index_part_size();
 
353
 
 
354
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
355
                                     table.indexes_size() * sizeof(KEY)
 
356
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
357
 
 
358
  KEY_PART_INFO *key_part;
 
359
 
 
360
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
361
    (share->key_info+table.indexes_size());
 
362
 
 
363
 
 
364
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
365
                                            sizeof(ulong*)*share->key_parts);
 
366
 
 
367
  share->keynames.count= table.indexes_size();
 
368
  share->keynames.name= NULL;
 
369
  share->keynames.type_names= (const char**)
 
370
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
371
 
 
372
  share->keynames.type_lengths= (unsigned int*)
 
373
    alloc_root(&share->mem_root,
 
374
               sizeof(unsigned int) * (table.indexes_size()+1));
 
375
 
 
376
  share->keynames.type_names[share->keynames.count]= NULL;
 
377
  share->keynames.type_lengths[share->keynames.count]= 0;
 
378
 
 
379
  KEY* keyinfo= share->key_info;
 
380
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
381
  {
 
382
    drizzle::Table::Index indx= table.indexes(keynr);
 
383
 
 
384
    keyinfo->table= 0;
 
385
    keyinfo->flags= 0;
 
386
 
 
387
    if(indx.is_unique())
 
388
      keyinfo->flags|= HA_NOSAME;
 
389
 
 
390
    if(indx.has_options())
 
391
    {
 
392
      drizzle::Table::Index::IndexOptions indx_options= indx.options();
 
393
      if(indx_options.pack_key())
 
394
        keyinfo->flags|= HA_PACK_KEY;
 
395
 
 
396
      if(indx_options.var_length_key())
 
397
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
398
 
 
399
      if(indx_options.null_part_key())
 
400
        keyinfo->flags|= HA_NULL_PART_KEY;
 
401
 
 
402
      if(indx_options.binary_pack_key())
 
403
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
404
 
 
405
      if(indx_options.has_partial_segments())
 
406
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
407
 
 
408
      if(indx_options.auto_generated_key())
 
409
        keyinfo->flags|= HA_GENERATED_KEY;
 
410
 
 
411
      if(indx_options.has_key_block_size())
 
412
      {
 
413
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
414
        keyinfo->block_size= indx_options.key_block_size();
 
415
      }
 
416
      else
 
417
      {
 
418
        keyinfo->block_size= 0;
 
419
      }
 
420
 
 
421
    }
 
422
 
 
423
    switch(indx.type())
 
424
    {
 
425
    case drizzle::Table::Index::UNKNOWN_INDEX:
 
426
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
427
      break;
 
428
    case drizzle::Table::Index::BTREE:
 
429
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
430
      break;
 
431
    case drizzle::Table::Index::RTREE:
 
432
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
433
      break;
 
434
    case drizzle::Table::Index::HASH:
 
435
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
436
      break;
 
437
    case drizzle::Table::Index::FULLTEXT:
 
438
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
439
 
 
440
    default:
 
441
      /* TODO: suitable warning ? */
 
442
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
443
      break;
 
444
    }
 
445
 
 
446
    keyinfo->key_length= indx.key_length();
 
447
 
 
448
    keyinfo->key_parts= indx.index_part_size();
 
449
 
 
450
    keyinfo->key_part= key_part;
 
451
    keyinfo->rec_per_key= rec_per_key;
 
452
 
 
453
    for(unsigned int partnr= 0;
 
454
        partnr < keyinfo->key_parts;
 
455
        partnr++, key_part++)
 
456
    {
 
457
      drizzle::Table::Index::IndexPart part;
 
458
      part= indx.index_part(partnr);
 
459
 
 
460
      *rec_per_key++=0;
 
461
 
 
462
      key_part->field= NULL;
 
463
      key_part->fieldnr= part.fieldnr();
 
464
      key_part->null_bit= 0;
 
465
      /* key_part->offset= ASS ASS ASS. Set later in the frm code */
 
466
      /* key_part->null_offset is only set if null_bit (see later) */
 
467
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
468
      /* key_part->type ???? */
 
469
      key_part->key_part_flag= 0;
 
470
      if(part.has_in_reverse_order())
 
471
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
472
 
 
473
      key_part->length= part.compare_length();
 
474
 
 
475
      key_part->store_length= key_part->length;
 
476
    }
 
477
 
 
478
    if(!indx.has_comment())
 
479
    {
 
480
      keyinfo->comment.length= 0;
 
481
      keyinfo->comment.str= NULL;
 
482
    }
 
483
    else
 
484
    {
 
485
      keyinfo->flags|= HA_USES_COMMENT;
 
486
      keyinfo->comment.length= indx.comment().length();
 
487
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
488
                                         indx.comment().c_str(),
 
489
                                         keyinfo->comment.length);
 
490
    }
 
491
 
 
492
    keyinfo->name= strmake_root(&share->mem_root,
 
493
                                indx.name().c_str(),
 
494
                                indx.name().length());
 
495
 
 
496
    share->keynames.type_names[keynr]= keyinfo->name;
 
497
    share->keynames.type_lengths[keynr]= indx.name().length();
 
498
  }
 
499
 
 
500
  share->keys_for_keyread.init(0);
 
501
  share->keys_in_use.init(share->keys);
 
502
 
 
503
  if(table_options.has_connect_string())
 
504
  {
 
505
    size_t len= table_options.connect_string().length();
 
506
    const char* str= table_options.connect_string().c_str();
 
507
 
 
508
    share->connect_string.length= len;
 
509
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
510
  }
 
511
 
 
512
  if(table_options.has_comment())
 
513
  {
 
514
    size_t len= table_options.comment().length();
 
515
    const char* str= table_options.comment().c_str();
 
516
 
 
517
    share->comment.length= len;
 
518
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
519
  }
 
520
 
 
521
  share->key_block_size= table_options.has_key_block_size() ?
 
522
    table_options.key_block_size() : 0;
 
523
 
 
524
  return 0;
 
525
}
 
526
 
285
527
/*
286
528
  Read table definition from a binary / text based .frm file
287
529
 
331
573
 
332
574
  drizzle::Table table;
333
575
 
334
 
  if(drizzle_read_table_proto(proto_path.c_str(), &table)==0)
 
576
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
335
577
  {
336
 
    {
337
 
      LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
338
 
                                strlen(table.engine().name().c_str()) };
339
 
      share->db_plugin= ha_resolve_by_name(session, &engine_name);
340
 
    }
341
 
 
342
 
    // share->db_create_options FAIL
343
 
    // share->db_options_in_use FAIL
344
 
    share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
345
 
    share->null_field_first= 0;
346
 
 
347
 
    drizzle::Table::TableOptions table_options;
348
 
    
349
 
    if(table.has_options())
350
 
      table_options= table.options();
351
 
 
352
 
    share->avg_row_length= table_options.has_avg_row_length() ?
353
 
      table_options.avg_row_length() : 0;
354
 
 
355
 
    share->page_checksum= table_options.has_page_checksum() ?
356
 
      (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
357
 
      : HA_CHOICE_UNDEF;
358
 
 
359
 
    share->row_type= table_options.has_row_type() ?
360
 
      (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
361
 
 
362
 
    share->block_size= table_options.has_block_size() ?
363
 
      table_options.block_size() : 0;
364
 
 
365
 
    share->table_charset= get_charset(table_options.has_collation_id()?
366
 
                                      table_options.collation_id() : 0);
367
 
 
368
 
    if (!share->table_charset)
369
 
    {
370
 
      /* unknown charset in head[38] or pre-3.23 frm */
371
 
      if (use_mb(default_charset_info))
372
 
      {
373
 
        /* Warn that we may be changing the size of character columns */
374
 
        errmsg_printf(ERRMSG_LVL_WARN,
375
 
                      _("'%s' had no or invalid character set, "
376
 
                        "and default character set is multi-byte, "
377
 
                        "so character column sizes may have changed"),
378
 
                      share->path.str);
379
 
      }
380
 
      share->table_charset= default_charset_info;
381
 
    }
382
 
 
383
 
    share->null_field_first= 1;
384
 
 
385
 
    share->db_record_offset= 1;
386
 
 
387
 
    share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
388
 
 
389
 
    share->db_low_byte_first= true;
390
 
 
391
 
    share->max_rows= table_options.has_max_rows() ?
392
 
      table_options.max_rows() : 0;
393
 
 
394
 
    share->min_rows= table_options.has_min_rows() ?
395
 
      table_options.min_rows() : 0;
396
 
 
397
 
    share->keys= table.indexes_size();
398
 
 
399
 
    share->key_parts= 0;
400
 
    for(int indx= 0; indx < table.indexes_size(); indx++)
401
 
      share->key_parts+= table.indexes(indx).index_part_size();
402
 
 
403
 
    share->key_info= (KEY*) alloc_root(&share->mem_root,
404
 
                                       table.indexes_size() * sizeof(KEY)
405
 
                                       +share->key_parts*sizeof(KEY_PART_INFO));
406
 
 
407
 
    KEY_PART_INFO *key_part;
408
 
 
409
 
    key_part= reinterpret_cast<KEY_PART_INFO*>
410
 
      (share->key_info+table.indexes_size());
411
 
 
412
 
 
413
 
    ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
414
 
                                            sizeof(ulong*)*share->key_parts);
415
 
 
416
 
    share->keynames.count= table.indexes_size();
417
 
    share->keynames.name= NULL;
418
 
    share->keynames.type_names= (const char**)
419
 
      alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
420
 
 
421
 
    share->keynames.type_lengths= (unsigned int*)
422
 
      alloc_root(&share->mem_root,
423
 
                 sizeof(unsigned int) * (table.indexes_size()+1));
424
 
 
425
 
    share->keynames.type_names[share->keynames.count]= NULL;
426
 
    share->keynames.type_lengths[share->keynames.count]= 0;
427
 
 
428
 
    KEY* keyinfo= share->key_info;
429
 
    for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
430
 
    {
431
 
      drizzle::Table::Index indx= table.indexes(keynr);
432
 
 
433
 
      keyinfo->table= 0;
434
 
      keyinfo->flags= 0;
435
 
 
436
 
      if(indx.is_unique())
437
 
        keyinfo->flags|= HA_NOSAME;
438
 
 
439
 
      if(indx.has_options())
440
 
      {
441
 
        drizzle::Table::Index::IndexOptions indx_options= indx.options();
442
 
        if(indx_options.pack_key())
443
 
          keyinfo->flags|= HA_PACK_KEY;
444
 
 
445
 
        if(indx_options.var_length_key())
446
 
          keyinfo->flags|= HA_VAR_LENGTH_PART;
447
 
 
448
 
        if(indx_options.null_part_key())
449
 
          keyinfo->flags|= HA_NULL_PART_KEY;
450
 
 
451
 
        if(indx_options.binary_pack_key())
452
 
          keyinfo->flags|= HA_BINARY_PACK_KEY;
453
 
 
454
 
        if(indx_options.has_partial_segments())
455
 
          keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
456
 
 
457
 
        if(indx_options.auto_generated_key())
458
 
          keyinfo->flags|= HA_GENERATED_KEY;
459
 
 
460
 
        if(indx_options.has_key_block_size())
461
 
        {
462
 
          keyinfo->flags|= HA_USES_BLOCK_SIZE;
463
 
          keyinfo->block_size= indx_options.key_block_size();
464
 
        }
465
 
        else
466
 
        {
467
 
          keyinfo->block_size= 0;
468
 
        }
469
 
 
470
 
      }
471
 
 
472
 
      switch(indx.type())
473
 
      {
474
 
      case drizzle::Table::Index::UNKNOWN_INDEX:
475
 
        keyinfo->algorithm= HA_KEY_ALG_UNDEF;
476
 
        break;
477
 
      case drizzle::Table::Index::BTREE:
478
 
        keyinfo->algorithm= HA_KEY_ALG_BTREE;
479
 
        break;
480
 
      case drizzle::Table::Index::RTREE:
481
 
        keyinfo->algorithm= HA_KEY_ALG_RTREE;
482
 
        break;
483
 
      case drizzle::Table::Index::HASH:
484
 
        keyinfo->algorithm= HA_KEY_ALG_HASH;
485
 
        break;
486
 
      case drizzle::Table::Index::FULLTEXT:
487
 
        keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
488
 
 
489
 
      default:
490
 
        /* TODO: suitable warning ? */
491
 
        keyinfo->algorithm= HA_KEY_ALG_UNDEF;
492
 
        break;
493
 
      }
494
 
      
495
 
      keyinfo->key_length= indx.key_length();
496
 
 
497
 
      keyinfo->key_parts= indx.index_part_size();
498
 
 
499
 
      keyinfo->key_part= key_part;
500
 
      keyinfo->rec_per_key= rec_per_key;
501
 
 
502
 
      for(unsigned int partnr= 0;
503
 
          partnr < keyinfo->key_parts;
504
 
          partnr++, key_part++)
505
 
      {
506
 
        drizzle::Table::Index::IndexPart part;
507
 
        part= indx.index_part(partnr);
508
 
 
509
 
        *rec_per_key++=0;
510
 
 
511
 
        key_part->field= NULL;
512
 
        key_part->fieldnr= part.fieldnr();
513
 
        key_part->null_bit= 0;
514
 
        /* key_part->offset= ASS ASS ASS. Set later in the frm code */
515
 
        /* key_part->null_offset is only set if null_bit (see later) */
516
 
        /* key_part->key_type= */ /* I *THINK* this may be okay.... */
517
 
        /* key_part->type ???? */
518
 
        key_part->key_part_flag= 0;
519
 
        if(part.has_in_reverse_order())
520
 
          key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
521
 
 
522
 
        key_part->length= part.compare_length();
523
 
 
524
 
        key_part->store_length= key_part->length;
525
 
      }
526
 
 
527
 
      if(!indx.has_comment())
528
 
      {
529
 
        keyinfo->comment.length= 0;
530
 
        keyinfo->comment.str= NULL;
531
 
      }
532
 
      else
533
 
      {
534
 
        keyinfo->flags|= HA_USES_COMMENT;
535
 
        keyinfo->comment.length= indx.comment().length();
536
 
        keyinfo->comment.str= strmake_root(&share->mem_root,
537
 
                                           indx.comment().c_str(),
538
 
                                           keyinfo->comment.length);
539
 
      }
540
 
 
541
 
      keyinfo->name= strmake_root(&share->mem_root,
542
 
                                  indx.name().c_str(),
543
 
                                  indx.name().length());
544
 
 
545
 
      share->keynames.type_names[keynr]= keyinfo->name;
546
 
      share->keynames.type_lengths[keynr]= indx.name().length();
547
 
    }
548
 
 
549
 
    share->keys_for_keyread.init(0);
550
 
    share->keys_in_use.init(share->keys);
551
 
 
552
 
    if(table_options.has_connect_string())
553
 
    {
554
 
      size_t len= table_options.connect_string().length();
555
 
      const char* str= table_options.connect_string().c_str();
556
 
 
557
 
      share->connect_string.length= len;
558
 
      share->connect_string.str= strmake_root(&share->mem_root, str, len);
559
 
    }
560
 
 
561
 
    if(table_options.has_comment())
562
 
    {
563
 
      size_t len= table_options.comment().length();
564
 
      const char* str= table_options.comment().c_str();
565
 
 
566
 
      share->comment.length= len;
567
 
      share->comment.str= strmake_root(&share->mem_root, str, len);
568
 
    }
569
 
 
570
 
    share->key_block_size= table_options.has_key_block_size() ?
571
 
      table_options.key_block_size() : 0;
572
 
 
573
 
 
574
 
 
575
 
//    return 0;
 
578
    if(error>0)
 
579
    {
 
580
      my_errno= error;
 
581
      error= 1;
 
582
    }
 
583
    else
 
584
    {
 
585
      if(!table.IsInitialized())
 
586
      {
 
587
        error= 4;
 
588
      }
 
589
    }
 
590
    goto err_not_open;
576
591
  }
577
592
 
 
593
  parse_table_proto(session, table, share);
 
594
 
 
595
  /* end of proto code... now to get some scraps from FRM */
 
596
 
578
597
  if ((file= open(path.c_str(), O_RDONLY)) < 0)
579
598
  {
580
599
    /*