~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item.cc

  • Committer: Monty Taylor
  • Date: 2008-11-12 17:42:40 UTC
  • mto: This revision was merged to the branch mainline in revision 584.
  • Revision ID: monty@inaugust.com-20081112174240-l2vg9lnzbmjc3uyk
More header cleanup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
#include <drizzled/server_includes.h>
 
18
#include CMATH_H
 
19
 
18
20
#include <drizzled/sql_select.h>
19
21
#include <drizzled/error.h>
20
 
#include CMATH_H
 
22
#include <drizzled/show.h>
21
23
 
22
24
#if defined(CMATH_NAMESPACE)
23
25
using namespace CMATH_NAMESPACE;
6464
6466
{}
6465
6467
 
6466
6468
/**
 
6469
  Create field for temporary table using type of given item.
 
6470
 
 
6471
  @param session                   Thread handler
 
6472
  @param item                  Item to create a field for
 
6473
  @param table                 Temporary table
 
6474
  @param copy_func             If set and item is a function, store copy of
 
6475
                               item in this array
 
6476
  @param modify_item           1 if item->result_field should point to new
 
6477
                               item. This is relevent for how fill_record()
 
6478
                               is going to work:
 
6479
                               If modify_item is 1 then fill_record() will
 
6480
                               update the record in the original table.
 
6481
                               If modify_item is 0 then fill_record() will
 
6482
                               update the temporary table
 
6483
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
 
6484
                               field instead of blob.
 
6485
 
 
6486
  @retval
 
6487
    0  on error
 
6488
  @retval
 
6489
    new_created field
 
6490
*/
 
6491
 
 
6492
static Field *create_tmp_field_from_item(Session *,
 
6493
                                         Item *item, Table *table,
 
6494
                                         Item ***copy_func, bool modify_item,
 
6495
                                         uint32_t convert_blob_length)
 
6496
{
 
6497
  bool maybe_null= item->maybe_null;
 
6498
  Field *new_field;
 
6499
 
 
6500
  switch (item->result_type()) {
 
6501
  case REAL_RESULT:
 
6502
    new_field= new Field_double(item->max_length, maybe_null,
 
6503
                                item->name, item->decimals, true);
 
6504
    break;
 
6505
  case INT_RESULT:
 
6506
    /* 
 
6507
      Select an integer type with the minimal fit precision.
 
6508
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
 
6509
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
 
6510
      Field_long : make them Field_int64_t.  
 
6511
    */
 
6512
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
 
6513
      new_field=new Field_int64_t(item->max_length, maybe_null,
 
6514
                                   item->name, item->unsigned_flag);
 
6515
    else
 
6516
      new_field=new Field_long(item->max_length, maybe_null,
 
6517
                               item->name, item->unsigned_flag);
 
6518
    break;
 
6519
  case STRING_RESULT:
 
6520
    assert(item->collation.collation);
 
6521
  
 
6522
    enum enum_field_types type;
 
6523
    /*
 
6524
      DATE/TIME fields have STRING_RESULT result type. 
 
6525
      To preserve type they needed to be handled separately.
 
6526
    */
 
6527
    if ((type= item->field_type()) == DRIZZLE_TYPE_DATETIME ||
 
6528
        type == DRIZZLE_TYPE_TIME || type == DRIZZLE_TYPE_NEWDATE ||
 
6529
        type == DRIZZLE_TYPE_TIMESTAMP)
 
6530
      new_field= item->tmp_table_field_from_field_type(table, 1);
 
6531
    /* 
 
6532
      Make sure that the blob fits into a Field_varstring which has 
 
6533
      2-byte lenght. 
 
6534
    */
 
6535
    else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
 
6536
             convert_blob_length <= Field_varstring::MAX_SIZE && 
 
6537
             convert_blob_length)
 
6538
      new_field= new Field_varstring(convert_blob_length, maybe_null,
 
6539
                                     item->name, table->s,
 
6540
                                     item->collation.collation);
 
6541
    else
 
6542
      new_field= item->make_string_field(table);
 
6543
    new_field->set_derivation(item->collation.derivation);
 
6544
    break;
 
6545
  case DECIMAL_RESULT:
 
6546
  {
 
6547
    uint8_t dec= item->decimals;
 
6548
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
 
6549
    uint32_t len= item->max_length;
 
6550
 
 
6551
    /*
 
6552
      Trying to put too many digits overall in a DECIMAL(prec,dec)
 
6553
      will always throw a warning. We must limit dec to
 
6554
      DECIMAL_MAX_SCALE however to prevent an assert() later.
 
6555
    */
 
6556
 
 
6557
    if (dec > 0)
 
6558
    {
 
6559
      signed int overflow;
 
6560
 
 
6561
      dec= cmin(dec, (uint8_t)DECIMAL_MAX_SCALE);
 
6562
 
 
6563
      /*
 
6564
        If the value still overflows the field with the corrected dec,
 
6565
        we'll throw out decimals rather than integers. This is still
 
6566
        bad and of course throws a truncation warning.
 
6567
        +1: for decimal point
 
6568
      */
 
6569
 
 
6570
      overflow= my_decimal_precision_to_length(intg + dec, dec,
 
6571
                                               item->unsigned_flag) - len;
 
6572
 
 
6573
      if (overflow > 0)
 
6574
        dec= cmax(0, dec - overflow);            // too long, discard fract
 
6575
      else
 
6576
        len -= item->decimals - dec;            // corrected value fits
 
6577
    }
 
6578
 
 
6579
    new_field= new Field_new_decimal(len, maybe_null, item->name,
 
6580
                                     dec, item->unsigned_flag);
 
6581
    break;
 
6582
  }
 
6583
  case ROW_RESULT:
 
6584
  default:
 
6585
    // This case should never be choosen
 
6586
    assert(0);
 
6587
    new_field= 0;
 
6588
    break;
 
6589
  }
 
6590
  if (new_field)
 
6591
    new_field->init(table);
 
6592
    
 
6593
  if (copy_func && item->is_result_field())
 
6594
    *((*copy_func)++) = item;                   // Save for copy_funcs
 
6595
  if (modify_item)
 
6596
    item->set_result_field(new_field);
 
6597
  if (item->type() == Item::NULL_ITEM)
 
6598
    new_field->is_created_from_null_item= true;
 
6599
  return new_field;
 
6600
}
 
6601
 
 
6602
Field *create_tmp_field(Session *session, Table *table,Item *item,
 
6603
                        Item::Type type, Item ***copy_func, Field **from_field,
 
6604
                        Field **default_field, bool group, bool modify_item,
 
6605
                        bool, bool make_copy_field,
 
6606
                        uint32_t convert_blob_length)
 
6607
{
 
6608
  Field *result;
 
6609
  Item::Type orig_type= type;
 
6610
  Item *orig_item= 0;
 
6611
 
 
6612
  if (type != Item::FIELD_ITEM &&
 
6613
      item->real_item()->type() == Item::FIELD_ITEM)
 
6614
  {
 
6615
    orig_item= item;
 
6616
    item= item->real_item();
 
6617
    type= Item::FIELD_ITEM;
 
6618
  }
 
6619
 
 
6620
  switch (type) {
 
6621
  case Item::SUM_FUNC_ITEM:
 
6622
  {
 
6623
    Item_sum *item_sum=(Item_sum*) item;
 
6624
    result= item_sum->create_tmp_field(group, table, convert_blob_length);
 
6625
    if (!result)
 
6626
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
 
6627
    return result;
 
6628
  }
 
6629
  case Item::FIELD_ITEM:
 
6630
  case Item::DEFAULT_VALUE_ITEM:
 
6631
  {
 
6632
    Item_field *field= (Item_field*) item;
 
6633
    bool orig_modify= modify_item;
 
6634
    if (orig_type == Item::REF_ITEM)
 
6635
      modify_item= 0;
 
6636
    /*
 
6637
      If item have to be able to store NULLs but underlaid field can't do it,
 
6638
      create_tmp_field_from_field() can't be used for tmp field creation.
 
6639
    */
 
6640
    if (field->maybe_null && !field->field->maybe_null())
 
6641
    {
 
6642
      result= create_tmp_field_from_item(session, item, table, NULL,
 
6643
                                         modify_item, convert_blob_length);
 
6644
      *from_field= field->field;
 
6645
      if (result && modify_item)
 
6646
        field->result_field= result;
 
6647
    } 
 
6648
    else
 
6649
      result= create_tmp_field_from_field(session, (*from_field= field->field),
 
6650
                                          orig_item ? orig_item->name :
 
6651
                                          item->name,
 
6652
                                          table,
 
6653
                                          modify_item ? field :
 
6654
                                          NULL,
 
6655
                                          convert_blob_length);
 
6656
    if (orig_type == Item::REF_ITEM && orig_modify)
 
6657
      ((Item_ref*)orig_item)->set_result_field(result);
 
6658
    if (field->field->eq_def(result))
 
6659
      *default_field= field->field;
 
6660
    return result;
 
6661
  }
 
6662
  /* Fall through */
 
6663
  case Item::FUNC_ITEM:
 
6664
    /* Fall through */
 
6665
  case Item::COND_ITEM:
 
6666
  case Item::FIELD_AVG_ITEM:
 
6667
  case Item::FIELD_STD_ITEM:
 
6668
  case Item::SUBSELECT_ITEM:
 
6669
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
 
6670
  case Item::PROC_ITEM:
 
6671
  case Item::INT_ITEM:
 
6672
  case Item::REAL_ITEM:
 
6673
  case Item::DECIMAL_ITEM:
 
6674
  case Item::STRING_ITEM:
 
6675
  case Item::REF_ITEM:
 
6676
  case Item::NULL_ITEM:
 
6677
  case Item::VARBIN_ITEM:
 
6678
    if (make_copy_field)
 
6679
    {
 
6680
      assert(((Item_result_field*)item)->result_field);
 
6681
      *from_field= ((Item_result_field*)item)->result_field;
 
6682
    }
 
6683
    return create_tmp_field_from_item(session, item, table,
 
6684
                                      (make_copy_field ? 0 : copy_func),
 
6685
                                       modify_item, convert_blob_length);
 
6686
  case Item::TYPE_HOLDER:  
 
6687
    result= ((Item_type_holder *)item)->make_field_by_type(table);
 
6688
    result->set_derivation(item->collation.derivation);
 
6689
    return result;
 
6690
  default:                                      // Dosen't have to be stored
 
6691
    return 0;
 
6692
  }
 
6693
}
 
6694
 
 
6695
 
 
6696
/**
6467
6697
  Wrapper of hide_view_error call for Name_resolution_context error
6468
6698
  processor.
6469
6699