~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.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:
32
32
 
33
33
using namespace std;
34
34
 
35
 
/* INFORMATION_SCHEMA name */
36
 
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
37
 
 
38
35
/* Keyword for parsing virtual column functions */
39
36
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
40
37
 
93
90
  assert(db != NULL);
94
91
  assert(name != NULL);
95
92
 
96
 
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
 
93
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
97
94
      (my_strcasecmp(system_charset_info,
98
 
                    INFORMATION_SCHEMA_NAME.str,
 
95
                    INFORMATION_SCHEMA_NAME.c_str(),
99
96
                    db->str) == 0))
100
97
  {
101
98
    return TABLE_CATEGORY_INFORMATION;
3662
3659
  return new_field;
3663
3660
}
3664
3661
 
3665
 
/**
3666
 
  Create field for temporary table using type of given item.
3667
 
 
3668
 
  @param session                   Thread handler
3669
 
  @param item                  Item to create a field for
3670
 
  @param table                 Temporary table
3671
 
  @param copy_func             If set and item is a function, store copy of
3672
 
                               item in this array
3673
 
  @param modify_item           1 if item->result_field should point to new
3674
 
                               item. This is relevent for how fill_record()
3675
 
                               is going to work:
3676
 
                               If modify_item is 1 then fill_record() will
3677
 
                               update the record in the original table.
3678
 
                               If modify_item is 0 then fill_record() will
3679
 
                               update the temporary table
3680
 
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
3681
 
                               field instead of blob.
3682
 
 
3683
 
  @retval
3684
 
    0  on error
3685
 
  @retval
3686
 
    new_created field
3687
 
*/
3688
 
 
3689
 
static Field *create_tmp_field_from_item(Session *,
3690
 
                                         Item *item, Table *table,
3691
 
                                         Item ***copy_func, bool modify_item,
3692
 
                                         uint32_t convert_blob_length)
3693
 
{
3694
 
  bool maybe_null= item->maybe_null;
3695
 
  Field *new_field;
3696
 
 
3697
 
  switch (item->result_type()) {
3698
 
  case REAL_RESULT:
3699
 
    new_field= new Field_double(item->max_length, maybe_null,
3700
 
                                item->name, item->decimals, true);
3701
 
    break;
3702
 
  case INT_RESULT:
3703
 
    /* 
3704
 
      Select an integer type with the minimal fit precision.
3705
 
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
3706
 
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
3707
 
      Field_long : make them Field_int64_t.  
3708
 
    */
3709
 
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
3710
 
      new_field=new Field_int64_t(item->max_length, maybe_null,
3711
 
                                   item->name, item->unsigned_flag);
3712
 
    else
3713
 
      new_field=new Field_long(item->max_length, maybe_null,
3714
 
                               item->name, item->unsigned_flag);
3715
 
    break;
3716
 
  case STRING_RESULT:
3717
 
    assert(item->collation.collation);
3718
 
  
3719
 
    enum enum_field_types type;
3720
 
    /*
3721
 
      DATE/TIME fields have STRING_RESULT result type. 
3722
 
      To preserve type they needed to be handled separately.
3723
 
    */
3724
 
    if ((type= item->field_type()) == DRIZZLE_TYPE_DATETIME ||
3725
 
        type == DRIZZLE_TYPE_TIME || type == DRIZZLE_TYPE_NEWDATE ||
3726
 
        type == DRIZZLE_TYPE_TIMESTAMP)
3727
 
      new_field= item->tmp_table_field_from_field_type(table, 1);
3728
 
    /* 
3729
 
      Make sure that the blob fits into a Field_varstring which has 
3730
 
      2-byte lenght. 
3731
 
    */
3732
 
    else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
3733
 
             convert_blob_length <= Field_varstring::MAX_SIZE && 
3734
 
             convert_blob_length)
3735
 
      new_field= new Field_varstring(convert_blob_length, maybe_null,
3736
 
                                     item->name, table->s,
3737
 
                                     item->collation.collation);
3738
 
    else
3739
 
      new_field= item->make_string_field(table);
3740
 
    new_field->set_derivation(item->collation.derivation);
3741
 
    break;
3742
 
  case DECIMAL_RESULT:
3743
 
  {
3744
 
    uint8_t dec= item->decimals;
3745
 
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
3746
 
    uint32_t len= item->max_length;
3747
 
 
3748
 
    /*
3749
 
      Trying to put too many digits overall in a DECIMAL(prec,dec)
3750
 
      will always throw a warning. We must limit dec to
3751
 
      DECIMAL_MAX_SCALE however to prevent an assert() later.
3752
 
    */
3753
 
 
3754
 
    if (dec > 0)
3755
 
    {
3756
 
      signed int overflow;
3757
 
 
3758
 
      dec= cmin(dec, (uint8_t)DECIMAL_MAX_SCALE);
3759
 
 
3760
 
      /*
3761
 
        If the value still overflows the field with the corrected dec,
3762
 
        we'll throw out decimals rather than integers. This is still
3763
 
        bad and of course throws a truncation warning.
3764
 
        +1: for decimal point
3765
 
      */
3766
 
 
3767
 
      overflow= my_decimal_precision_to_length(intg + dec, dec,
3768
 
                                               item->unsigned_flag) - len;
3769
 
 
3770
 
      if (overflow > 0)
3771
 
        dec= cmax(0, dec - overflow);            // too long, discard fract
3772
 
      else
3773
 
        len -= item->decimals - dec;            // corrected value fits
3774
 
    }
3775
 
 
3776
 
    new_field= new Field_new_decimal(len, maybe_null, item->name,
3777
 
                                     dec, item->unsigned_flag);
3778
 
    break;
3779
 
  }
3780
 
  case ROW_RESULT:
3781
 
  default:
3782
 
    // This case should never be choosen
3783
 
    assert(0);
3784
 
    new_field= 0;
3785
 
    break;
3786
 
  }
3787
 
  if (new_field)
3788
 
    new_field->init(table);
3789
 
    
3790
 
  if (copy_func && item->is_result_field())
3791
 
    *((*copy_func)++) = item;                   // Save for copy_funcs
3792
 
  if (modify_item)
3793
 
    item->set_result_field(new_field);
3794
 
  if (item->type() == Item::NULL_ITEM)
3795
 
    new_field->is_created_from_null_item= true;
3796
 
  return new_field;
3797
 
}
3798
3662
 
3799
3663
 
3800
3664
/**
3831
3695
 
3832
3696
 
3833
3697
/**
3834
 
  Create field for temporary table.
3835
 
 
3836
 
  @param session                Thread handler
3837
 
  @param table          Temporary table
3838
 
  @param item           Item to create a field for
3839
 
  @param type           Type of item (normally item->type)
3840
 
  @param copy_func      If set and item is a function, store copy of item
3841
 
                       in this array
3842
 
  @param from_field    if field will be created using other field as example,
3843
 
                       pointer example field will be written here
3844
 
  @param default_field  If field has a default value field, store it here
3845
 
  @param group          1 if we are going to do a relative group by on result
3846
 
  @param modify_item    1 if item->result_field should point to new item.
3847
 
                       This is relevent for how fill_record() is going to
3848
 
                       work:
3849
 
                       If modify_item is 1 then fill_record() will update
3850
 
                       the record in the original table.
3851
 
                       If modify_item is 0 then fill_record() will update
3852
 
                       the temporary table
3853
 
  @param convert_blob_length If >0 create a varstring(convert_blob_length)
3854
 
                             field instead of blob.
3855
 
 
3856
 
  @retval
3857
 
    0                   on error
3858
 
  @retval
3859
 
    new_created field
3860
 
*/
3861
 
 
3862
 
Field *create_tmp_field(Session *session, Table *table,Item *item,
3863
 
                        Item::Type type, Item ***copy_func, Field **from_field,
3864
 
                        Field **default_field, bool group, bool modify_item,
3865
 
                        bool, bool make_copy_field,
3866
 
                        uint32_t convert_blob_length)
3867
 
{
3868
 
  Field *result;
3869
 
  Item::Type orig_type= type;
3870
 
  Item *orig_item= 0;
3871
 
 
3872
 
  if (type != Item::FIELD_ITEM &&
3873
 
      item->real_item()->type() == Item::FIELD_ITEM)
3874
 
  {
3875
 
    orig_item= item;
3876
 
    item= item->real_item();
3877
 
    type= Item::FIELD_ITEM;
3878
 
  }
3879
 
 
3880
 
  switch (type) {
3881
 
  case Item::SUM_FUNC_ITEM:
3882
 
  {
3883
 
    Item_sum *item_sum=(Item_sum*) item;
3884
 
    result= item_sum->create_tmp_field(group, table, convert_blob_length);
3885
 
    if (!result)
3886
 
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3887
 
    return result;
3888
 
  }
3889
 
  case Item::FIELD_ITEM:
3890
 
  case Item::DEFAULT_VALUE_ITEM:
3891
 
  {
3892
 
    Item_field *field= (Item_field*) item;
3893
 
    bool orig_modify= modify_item;
3894
 
    if (orig_type == Item::REF_ITEM)
3895
 
      modify_item= 0;
3896
 
    /*
3897
 
      If item have to be able to store NULLs but underlaid field can't do it,
3898
 
      create_tmp_field_from_field() can't be used for tmp field creation.
3899
 
    */
3900
 
    if (field->maybe_null && !field->field->maybe_null())
3901
 
    {
3902
 
      result= create_tmp_field_from_item(session, item, table, NULL,
3903
 
                                         modify_item, convert_blob_length);
3904
 
      *from_field= field->field;
3905
 
      if (result && modify_item)
3906
 
        field->result_field= result;
3907
 
    } 
3908
 
    else
3909
 
      result= create_tmp_field_from_field(session, (*from_field= field->field),
3910
 
                                          orig_item ? orig_item->name :
3911
 
                                          item->name,
3912
 
                                          table,
3913
 
                                          modify_item ? field :
3914
 
                                          NULL,
3915
 
                                          convert_blob_length);
3916
 
    if (orig_type == Item::REF_ITEM && orig_modify)
3917
 
      ((Item_ref*)orig_item)->set_result_field(result);
3918
 
    if (field->field->eq_def(result))
3919
 
      *default_field= field->field;
3920
 
    return result;
3921
 
  }
3922
 
  /* Fall through */
3923
 
  case Item::FUNC_ITEM:
3924
 
    /* Fall through */
3925
 
  case Item::COND_ITEM:
3926
 
  case Item::FIELD_AVG_ITEM:
3927
 
  case Item::FIELD_STD_ITEM:
3928
 
  case Item::SUBSELECT_ITEM:
3929
 
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
3930
 
  case Item::PROC_ITEM:
3931
 
  case Item::INT_ITEM:
3932
 
  case Item::REAL_ITEM:
3933
 
  case Item::DECIMAL_ITEM:
3934
 
  case Item::STRING_ITEM:
3935
 
  case Item::REF_ITEM:
3936
 
  case Item::NULL_ITEM:
3937
 
  case Item::VARBIN_ITEM:
3938
 
    if (make_copy_field)
3939
 
    {
3940
 
      assert(((Item_result_field*)item)->result_field);
3941
 
      *from_field= ((Item_result_field*)item)->result_field;
3942
 
    }
3943
 
    return create_tmp_field_from_item(session, item, table,
3944
 
                                      (make_copy_field ? 0 : copy_func),
3945
 
                                       modify_item, convert_blob_length);
3946
 
  case Item::TYPE_HOLDER:  
3947
 
    result= ((Item_type_holder *)item)->make_field_by_type(table);
3948
 
    result->set_derivation(item->collation.derivation);
3949
 
    return result;
3950
 
  default:                                      // Dosen't have to be stored
3951
 
    return 0;
3952
 
  }
3953
 
}
3954
 
 
3955
 
/**
3956
3698
  Create a temp table according to a field list.
3957
3699
 
3958
3700
  Given field pointers are changed to point at tmp_table for