~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2008-11-13 02:56:15 UTC
  • mfrom: (575.4.10 devel)
  • Revision ID: brian@tangent.org-20081113025615-snhsi52yb2ivmx6f
Merging Monty's code.

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