~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item.cc

  • Committer: Monty Taylor
  • Date: 2008-11-16 05:36:13 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116053613-bld4rqxhlkb49c02
Split out cache_row and type_holder.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
15
19
 
16
20
 
17
21
#include <drizzled/server_includes.h>
20
24
#include <drizzled/sql_select.h>
21
25
#include <drizzled/error.h>
22
26
#include <drizzled/show.h>
 
27
#include <drizzled/item/cache_row.h>
 
28
#include <drizzled/item/type_holder.h>
23
29
 
24
30
#if defined(CMATH_NAMESPACE)
25
31
using namespace CMATH_NAMESPACE;
5581
5587
}
5582
5588
 
5583
5589
 
5584
 
bool Item_cache_row::allocate(uint32_t num)
5585
 
{
5586
 
  item_count= num;
5587
 
  Session *session= current_session;
5588
 
  return (!(values= 
5589
 
            (Item_cache **) session->calloc(sizeof(Item_cache *)*item_count)));
5590
 
}
5591
 
 
5592
 
 
5593
 
bool Item_cache_row::setup(Item * item)
5594
 
{
5595
 
  example= item;
5596
 
  if (!values && allocate(item->cols()))
5597
 
    return 1;
5598
 
  for (uint32_t i= 0; i < item_count; i++)
5599
 
  {
5600
 
    Item *el= item->element_index(i);
5601
 
    Item_cache *tmp;
5602
 
    if (!(tmp= values[i]= Item_cache::get_cache(el)))
5603
 
      return 1;
5604
 
    tmp->setup(el);
5605
 
  }
5606
 
  return 0;
5607
 
}
5608
 
 
5609
 
 
5610
 
void Item_cache_row::store(Item * item)
5611
 
{
5612
 
  null_value= 0;
5613
 
  item->bring_value();
5614
 
  for (uint32_t i= 0; i < item_count; i++)
5615
 
  {
5616
 
    values[i]->store(item->element_index(i));
5617
 
    null_value|= values[i]->null_value;
5618
 
  }
5619
 
}
5620
 
 
5621
 
 
5622
 
void Item_cache_row::illegal_method_call(const char *)
5623
 
{
5624
 
  assert(0);
5625
 
  my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
5626
 
  return;
5627
 
}
5628
 
 
5629
 
 
5630
 
bool Item_cache_row::check_cols(uint32_t c)
5631
 
{
5632
 
  if (c != item_count)
5633
 
  {
5634
 
    my_error(ER_OPERAND_COLUMNS, MYF(0), c);
5635
 
    return 1;
5636
 
  }
5637
 
  return 0;
5638
 
}
5639
 
 
5640
 
 
5641
 
bool Item_cache_row::null_inside()
5642
 
{
5643
 
  for (uint32_t i= 0; i < item_count; i++)
5644
 
  {
5645
 
    if (values[i]->cols() > 1)
5646
 
    {
5647
 
      if (values[i]->null_inside())
5648
 
        return 1;
5649
 
    }
5650
 
    else
5651
 
    {
5652
 
      values[i]->update_null_value();
5653
 
      if (values[i]->null_value)
5654
 
        return 1;
5655
 
    }
5656
 
  }
5657
 
  return 0;
5658
 
}
5659
 
 
5660
 
 
5661
 
void Item_cache_row::bring_value()
5662
 
{
5663
 
  for (uint32_t i= 0; i < item_count; i++)
5664
 
    values[i]->bring_value();
5665
 
  return;
5666
 
}
5667
 
 
5668
 
 
5669
 
Item_type_holder::Item_type_holder(Session *session, Item *item)
5670
 
  :Item(session, item), enum_set_typelib(0), fld_type(get_real_type(item))
5671
 
{
5672
 
  assert(item->fixed);
5673
 
  maybe_null= item->maybe_null;
5674
 
  collation.set(item->collation);
5675
 
  get_full_info(item);
5676
 
  /* fix variable decimals which always is NOT_FIXED_DEC */
5677
 
  if (Field::result_merge_type(fld_type) == INT_RESULT)
5678
 
    decimals= 0;
5679
 
  prev_decimal_int_part= item->decimal_int_part();
5680
 
}
5681
 
 
5682
 
 
5683
 
/**
5684
 
  Return expression type of Item_type_holder.
5685
 
 
5686
 
  @return
5687
 
    Item_result (type of internal MySQL expression result)
5688
 
*/
5689
 
 
5690
 
Item_result Item_type_holder::result_type() const
5691
 
{
5692
 
  return Field::result_merge_type(fld_type);
5693
 
}
5694
 
 
5695
 
 
5696
 
/**
5697
 
  Find real field type of item.
5698
 
 
5699
 
  @return
5700
 
    type of field which should be created to store item value
5701
 
*/
5702
 
 
5703
 
enum_field_types Item_type_holder::get_real_type(Item *item)
5704
 
{
5705
 
  switch(item->type())
5706
 
  {
5707
 
  case FIELD_ITEM:
5708
 
  {
5709
 
    /*
5710
 
      Item_fields::field_type ask Field_type() but sometimes field return
5711
 
      a different type, like for enum/set, so we need to ask real type.
5712
 
    */
5713
 
    Field *field= ((Item_field *) item)->field;
5714
 
    enum_field_types type= field->real_type();
5715
 
    if (field->is_created_from_null_item)
5716
 
      return DRIZZLE_TYPE_NULL;
5717
 
    return type;
5718
 
  }
5719
 
  case SUM_FUNC_ITEM:
5720
 
  {
5721
 
    /*
5722
 
      Argument of aggregate function sometimes should be asked about field
5723
 
      type
5724
 
    */
5725
 
    Item_sum *item_sum= (Item_sum *) item;
5726
 
    if (item_sum->keep_field_type())
5727
 
      return get_real_type(item_sum->args[0]);
5728
 
    break;
5729
 
  }
5730
 
  case FUNC_ITEM:
5731
 
    if (((Item_func *) item)->functype() == Item_func::GUSERVAR_FUNC)
5732
 
    {
5733
 
      /*
5734
 
        There are work around of problem with changing variable type on the
5735
 
        fly and variable always report "string" as field type to get
5736
 
        acceptable information for client in send_field, so we make field
5737
 
        type from expression type.
5738
 
      */
5739
 
      switch (item->result_type()) {
5740
 
      case STRING_RESULT:
5741
 
        return DRIZZLE_TYPE_VARCHAR;
5742
 
      case INT_RESULT:
5743
 
        return DRIZZLE_TYPE_LONGLONG;
5744
 
      case REAL_RESULT:
5745
 
        return DRIZZLE_TYPE_DOUBLE;
5746
 
      case DECIMAL_RESULT:
5747
 
        return DRIZZLE_TYPE_NEWDECIMAL;
5748
 
      case ROW_RESULT:
5749
 
      default:
5750
 
        assert(0);
5751
 
        return DRIZZLE_TYPE_VARCHAR;
5752
 
      }
5753
 
    }
5754
 
    break;
5755
 
  default:
5756
 
    break;
5757
 
  }
5758
 
  return item->field_type();
5759
 
}
5760
 
 
5761
 
/**
5762
 
  Find field type which can carry current Item_type_holder type and
5763
 
  type of given Item.
5764
 
 
5765
 
  @param session     thread handler
5766
 
  @param item    given item to join its parameters with this item ones
5767
 
 
5768
 
  @retval
5769
 
    true   error - types are incompatible
5770
 
  @retval
5771
 
    false  OK
5772
 
*/
5773
 
 
5774
 
bool Item_type_holder::join_types(Session *, Item *item)
5775
 
{
5776
 
  uint32_t max_length_orig= max_length;
5777
 
  uint32_t decimals_orig= decimals;
5778
 
  fld_type= Field::field_type_merge(fld_type, get_real_type(item));
5779
 
  {
5780
 
    int item_decimals= item->decimals;
5781
 
    /* fix variable decimals which always is NOT_FIXED_DEC */
5782
 
    if (Field::result_merge_type(fld_type) == INT_RESULT)
5783
 
      item_decimals= 0;
5784
 
    decimals= cmax((int)decimals, item_decimals);
5785
 
  }
5786
 
  if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
5787
 
  {
5788
 
    decimals= cmin((int)cmax(decimals, item->decimals), DECIMAL_MAX_SCALE);
5789
 
    int precision= cmin(cmax(prev_decimal_int_part, item->decimal_int_part())
5790
 
                       + decimals, DECIMAL_MAX_PRECISION);
5791
 
    unsigned_flag&= item->unsigned_flag;
5792
 
    max_length= my_decimal_precision_to_length(precision, decimals,
5793
 
                                               unsigned_flag);
5794
 
  }
5795
 
 
5796
 
  switch (Field::result_merge_type(fld_type))
5797
 
  {
5798
 
  case STRING_RESULT:
5799
 
  {
5800
 
    const char *old_cs, *old_derivation;
5801
 
    uint32_t old_max_chars= max_length / collation.collation->mbmaxlen;
5802
 
    old_cs= collation.collation->name;
5803
 
    old_derivation= collation.derivation_name();
5804
 
    if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV))
5805
 
    {
5806
 
      my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
5807
 
               old_cs, old_derivation,
5808
 
               item->collation.collation->name,
5809
 
               item->collation.derivation_name(),
5810
 
               "UNION");
5811
 
      return(true);
5812
 
    }
5813
 
    /*
5814
 
      To figure out max_length, we have to take into account possible
5815
 
      expansion of the size of the values because of character set
5816
 
      conversions.
5817
 
     */
5818
 
    if (collation.collation != &my_charset_bin)
5819
 
    {
5820
 
      max_length= cmax(old_max_chars * collation.collation->mbmaxlen,
5821
 
                      display_length(item) /
5822
 
                      item->collation.collation->mbmaxlen *
5823
 
                      collation.collation->mbmaxlen);
5824
 
    }
5825
 
    else
5826
 
      set_if_bigger(max_length, display_length(item));
5827
 
    break;
5828
 
  }
5829
 
  case REAL_RESULT:
5830
 
  {
5831
 
    if (decimals != NOT_FIXED_DEC)
5832
 
    {
5833
 
      int delta1= max_length_orig - decimals_orig;
5834
 
      int delta2= item->max_length - item->decimals;
5835
 
      max_length= cmax(delta1, delta2) + decimals;
5836
 
      if (fld_type == DRIZZLE_TYPE_DOUBLE && max_length > DBL_DIG + 2) 
5837
 
      {
5838
 
        max_length= DBL_DIG + 7;
5839
 
        decimals= NOT_FIXED_DEC;
5840
 
      }
5841
 
    }
5842
 
    else
5843
 
      max_length= DBL_DIG+7;
5844
 
    break;
5845
 
  }
5846
 
  default:
5847
 
    max_length= cmax(max_length, display_length(item));
5848
 
  };
5849
 
  maybe_null|= item->maybe_null;
5850
 
  get_full_info(item);
5851
 
 
5852
 
  /* Remember decimal integer part to be used in DECIMAL_RESULT handleng */
5853
 
  prev_decimal_int_part= decimal_int_part();
5854
 
  return(false);
5855
 
}
5856
 
 
5857
 
/**
5858
 
  Calculate lenth for merging result for given Item type.
5859
 
 
5860
 
  @param item  Item for length detection
5861
 
 
5862
 
  @return
5863
 
    length
5864
 
*/
5865
 
 
5866
 
uint32_t Item_type_holder::display_length(Item *item)
5867
 
{
5868
 
  if (item->type() == Item::FIELD_ITEM)
5869
 
    return ((Item_field *)item)->max_disp_length();
5870
 
 
5871
 
  switch (item->field_type())
5872
 
  {
5873
 
  case DRIZZLE_TYPE_TIMESTAMP:
5874
 
  case DRIZZLE_TYPE_TIME:
5875
 
  case DRIZZLE_TYPE_DATETIME:
5876
 
  case DRIZZLE_TYPE_NEWDATE:
5877
 
  case DRIZZLE_TYPE_VARCHAR:
5878
 
  case DRIZZLE_TYPE_NEWDECIMAL:
5879
 
  case DRIZZLE_TYPE_ENUM:
5880
 
  case DRIZZLE_TYPE_BLOB:
5881
 
    return 4;
5882
 
  case DRIZZLE_TYPE_LONG:
5883
 
    return MY_INT32_NUM_DECIMAL_DIGITS;
5884
 
  case DRIZZLE_TYPE_DOUBLE:
5885
 
    return 53;
5886
 
  case DRIZZLE_TYPE_NULL:
5887
 
    return 0;
5888
 
  case DRIZZLE_TYPE_LONGLONG:
5889
 
    return 20;
5890
 
  default:
5891
 
    assert(0); // we should never go there
5892
 
    return 0;
5893
 
  }
5894
 
}
5895
 
 
5896
 
 
5897
 
/**
5898
 
  Make temporary table field according collected information about type
5899
 
  of UNION result.
5900
 
 
5901
 
  @param table  temporary table for which we create fields
5902
 
 
5903
 
  @return
5904
 
    created field
5905
 
*/
5906
 
 
5907
 
Field *Item_type_holder::make_field_by_type(Table *table)
5908
 
{
5909
 
  /*
5910
 
    The field functions defines a field to be not null if null_ptr is not 0
5911
 
  */
5912
 
  unsigned char *null_ptr= maybe_null ? (unsigned char*) "" : 0;
5913
 
  Field *field;
5914
 
 
5915
 
  switch (fld_type) {
5916
 
  case DRIZZLE_TYPE_ENUM:
5917
 
    assert(enum_set_typelib);
5918
 
    field= new Field_enum((unsigned char *) 0, max_length, null_ptr, 0,
5919
 
                          Field::NONE, name,
5920
 
                          get_enum_pack_length(enum_set_typelib->count),
5921
 
                          enum_set_typelib, collation.collation);
5922
 
    if (field)
5923
 
      field->init(table);
5924
 
    return field;
5925
 
  case DRIZZLE_TYPE_NULL:
5926
 
    return make_string_field(table);
5927
 
  default:
5928
 
    break;
5929
 
  }
5930
 
  return tmp_table_field_from_field_type(table, 0);
5931
 
}
5932
 
 
5933
 
 
5934
 
/**
5935
 
  Get full information from Item about enum/set fields to be able to create
5936
 
  them later.
5937
 
 
5938
 
  @param item    Item for information collection
5939
 
*/
5940
 
void Item_type_holder::get_full_info(Item *item)
5941
 
{
5942
 
  if (fld_type == DRIZZLE_TYPE_ENUM)
5943
 
  {
5944
 
    if (item->type() == Item::SUM_FUNC_ITEM &&
5945
 
        (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC ||
5946
 
         ((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC))
5947
 
      item = ((Item_sum*)item)->args[0];
5948
 
    /*
5949
 
      We can have enum/set type after merging only if we have one enum|set
5950
 
      field (or MIN|MAX(enum|set field)) and number of NULL fields
5951
 
    */
5952
 
    assert((enum_set_typelib &&
5953
 
                 get_real_type(item) == DRIZZLE_TYPE_NULL) ||
5954
 
                (!enum_set_typelib &&
5955
 
                 item->type() == Item::FIELD_ITEM &&
5956
 
                 (get_real_type(item) == DRIZZLE_TYPE_ENUM) &&
5957
 
                 ((Field_enum*)((Item_field *) item)->field)->typelib));
5958
 
    if (!enum_set_typelib)
5959
 
    {
5960
 
      enum_set_typelib= ((Field_enum*)((Item_field *) item)->field)->typelib;
5961
 
    }
5962
 
  }
5963
 
}
5964
 
 
5965
 
 
5966
 
double Item_type_holder::val_real()
5967
 
{
5968
 
  assert(0); // should never be called
5969
 
  return 0.0;
5970
 
}
5971
 
 
5972
 
 
5973
 
int64_t Item_type_holder::val_int()
5974
 
{
5975
 
  assert(0); // should never be called
5976
 
  return 0;
5977
 
}
5978
 
 
5979
 
my_decimal *Item_type_holder::val_decimal(my_decimal *)
5980
 
{
5981
 
  assert(0); // should never be called
5982
 
  return 0;
5983
 
}
5984
 
 
5985
 
String *Item_type_holder::val_str(String*)
5986
 
{
5987
 
  assert(0); // should never be called
5988
 
  return 0;
5989
 
}
5990
 
 
5991
 
void Item_result_field::cleanup()
5992
 
{
5993
 
  Item::cleanup();
5994
 
  result_field= 0;
5995
 
  return;
5996
 
}
5997
 
 
5998
5590
/**
5999
5591
  Dummy error processor used by default by Name_resolution_context.
6000
5592