~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field.cc

  • Committer: Lee
  • Date: 2008-10-03 23:31:06 UTC
  • mfrom: (413.2.3 drizzle)
  • mto: This revision was merged to the branch mainline in revision 459.
  • Revision ID: lbieber@lbieber-desktop-20081003233106-tgvzu0fh25gb3xeg
breaking out enum field classes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1604
1604
}
1605
1605
 
1606
1606
 
1607
 
/****************************************************************************
1608
 
** enum type.
1609
 
** This is a string which only can have a selection of different values.
1610
 
** If one uses this string in a number context one gets the type number.
1611
 
****************************************************************************/
1612
 
 
1613
 
enum ha_base_keytype Field_enum::key_type() const
1614
 
{
1615
 
  switch (packlength) {
1616
 
  default: return HA_KEYTYPE_BINARY;
1617
 
  case 2: assert(1);
1618
 
  case 3: assert(1);
1619
 
  case 4: return HA_KEYTYPE_ULONG_INT;
1620
 
  case 8: return HA_KEYTYPE_ULONGLONG;
1621
 
  }
1622
 
}
1623
 
 
1624
 
void Field_enum::store_type(uint64_t value)
1625
 
{
1626
 
  switch (packlength) {
1627
 
  case 1: ptr[0]= (uchar) value;  break;
1628
 
  case 2:
1629
 
#ifdef WORDS_BIGENDIAN
1630
 
  if (table->s->db_low_byte_first)
1631
 
  {
1632
 
    int2store(ptr,(unsigned short) value);
1633
 
  }
1634
 
  else
1635
 
#endif
1636
 
    shortstore(ptr,(unsigned short) value);
1637
 
  break;
1638
 
  case 3: int3store(ptr,(long) value); break;
1639
 
  case 4:
1640
 
#ifdef WORDS_BIGENDIAN
1641
 
  if (table->s->db_low_byte_first)
1642
 
  {
1643
 
    int4store(ptr,value);
1644
 
  }
1645
 
  else
1646
 
#endif
1647
 
    longstore(ptr,(long) value);
1648
 
  break;
1649
 
  case 8:
1650
 
#ifdef WORDS_BIGENDIAN
1651
 
  if (table->s->db_low_byte_first)
1652
 
  {
1653
 
    int8store(ptr,value);
1654
 
  }
1655
 
  else
1656
 
#endif
1657
 
    int64_tstore(ptr,value); break;
1658
 
  }
1659
 
}
1660
 
 
1661
 
 
1662
 
/**
1663
 
  @note
1664
 
    Storing a empty string in a enum field gives a warning
1665
 
    (if there isn't a empty value in the enum)
1666
 
*/
1667
 
 
1668
 
int Field_enum::store(const char *from, uint length, const CHARSET_INFO * const cs)
1669
 
{
1670
 
  int err= 0;
1671
 
  uint32_t not_used;
1672
 
  char buff[STRING_BUFFER_USUAL_SIZE];
1673
 
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
1674
 
 
1675
 
  /* Convert character set if necessary */
1676
 
  if (String::needs_conversion(length, cs, field_charset, &not_used))
1677
 
  { 
1678
 
    uint dummy_errors;
1679
 
    tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
1680
 
    from= tmpstr.ptr();
1681
 
    length=  tmpstr.length();
1682
 
  }
1683
 
 
1684
 
  /* Remove end space */
1685
 
  length= field_charset->cset->lengthsp(field_charset, from, length);
1686
 
  uint tmp=find_type2(typelib, from, length, field_charset);
1687
 
  if (!tmp)
1688
 
  {
1689
 
    if (length < 6) // Can't be more than 99999 enums
1690
 
    {
1691
 
      /* This is for reading numbers with LOAD DATA INFILE */
1692
 
      char *end;
1693
 
      tmp=(uint) my_strntoul(cs,from,length,10,&end,&err);
1694
 
      if (err || end != from+length || tmp > typelib->count)
1695
 
      {
1696
 
        tmp=0;
1697
 
        set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
1698
 
      }
1699
 
      if (!table->in_use->count_cuted_fields)
1700
 
        err= 0;
1701
 
    }
1702
 
    else
1703
 
      set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
1704
 
  }
1705
 
  store_type((uint64_t) tmp);
1706
 
  return err;
1707
 
}
1708
 
 
1709
 
 
1710
 
int Field_enum::store(double nr)
1711
 
{
1712
 
  return Field_enum::store((int64_t) nr, false);
1713
 
}
1714
 
 
1715
 
 
1716
 
int Field_enum::store(int64_t nr,
1717
 
                      bool unsigned_val __attribute__((unused)))
1718
 
{
1719
 
  int error= 0;
1720
 
  if ((uint64_t) nr > typelib->count || nr == 0)
1721
 
  {
1722
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
1723
 
    if (nr != 0 || table->in_use->count_cuted_fields)
1724
 
    {
1725
 
      nr= 0;
1726
 
      error= 1;
1727
 
    }
1728
 
  }
1729
 
  store_type((uint64_t) (uint) nr);
1730
 
  return error;
1731
 
}
1732
 
 
1733
 
 
1734
 
double Field_enum::val_real(void)
1735
 
{
1736
 
  return (double) Field_enum::val_int();
1737
 
}
1738
 
 
1739
 
 
1740
 
int64_t Field_enum::val_int(void)
1741
 
{
1742
 
  switch (packlength) {
1743
 
  case 1:
1744
 
    return (int64_t) ptr[0];
1745
 
  case 2:
1746
 
  {
1747
 
    uint16_t tmp;
1748
 
#ifdef WORDS_BIGENDIAN
1749
 
    if (table->s->db_low_byte_first)
1750
 
      tmp=sint2korr(ptr);
1751
 
    else
1752
 
#endif
1753
 
      shortget(tmp,ptr);
1754
 
    return (int64_t) tmp;
1755
 
  }
1756
 
  case 3:
1757
 
    return (int64_t) uint3korr(ptr);
1758
 
  case 4:
1759
 
  {
1760
 
    uint32_t tmp;
1761
 
#ifdef WORDS_BIGENDIAN
1762
 
    if (table->s->db_low_byte_first)
1763
 
      tmp=uint4korr(ptr);
1764
 
    else
1765
 
#endif
1766
 
      longget(tmp,ptr);
1767
 
    return (int64_t) tmp;
1768
 
  }
1769
 
  case 8:
1770
 
  {
1771
 
    int64_t tmp;
1772
 
#ifdef WORDS_BIGENDIAN
1773
 
    if (table->s->db_low_byte_first)
1774
 
      tmp=sint8korr(ptr);
1775
 
    else
1776
 
#endif
1777
 
      int64_tget(tmp,ptr);
1778
 
    return tmp;
1779
 
  }
1780
 
  }
1781
 
  return 0;                                     // impossible
1782
 
}
1783
 
 
1784
 
 
1785
 
/**
1786
 
   Save the field metadata for enum fields.
1787
 
 
1788
 
   Saves the real type in the first byte and the pack length in the 
1789
 
   second byte of the field metadata array at index of *metadata_ptr and
1790
 
   *(metadata_ptr + 1).
1791
 
 
1792
 
   @param   metadata_ptr   First byte of field metadata
1793
 
 
1794
 
   @returns number of bytes written to metadata_ptr
1795
 
*/
1796
 
int Field_enum::do_save_field_metadata(uchar *metadata_ptr)
1797
 
{
1798
 
  *metadata_ptr= real_type();
1799
 
  *(metadata_ptr + 1)= pack_length();
1800
 
  return 2;
1801
 
}
1802
 
 
1803
 
 
1804
 
String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
1805
 
                            String *val_ptr)
1806
 
{
1807
 
  uint tmp=(uint) Field_enum::val_int();
1808
 
  if (!tmp || tmp > typelib->count)
1809
 
    val_ptr->set("", 0, field_charset);
1810
 
  else
1811
 
    val_ptr->set((const char*) typelib->type_names[tmp-1],
1812
 
                 typelib->type_lengths[tmp-1],
1813
 
                 field_charset);
1814
 
  return val_ptr;
1815
 
}
1816
 
 
1817
 
int Field_enum::cmp(const uchar *a_ptr, const uchar *b_ptr)
1818
 
{
1819
 
  uchar *old= ptr;
1820
 
  ptr= (uchar*) a_ptr;
1821
 
  uint64_t a=Field_enum::val_int();
1822
 
  ptr= (uchar*) b_ptr;
1823
 
  uint64_t b=Field_enum::val_int();
1824
 
  ptr= old;
1825
 
  return (a < b) ? -1 : (a > b) ? 1 : 0;
1826
 
}
1827
 
 
1828
 
void Field_enum::sort_string(uchar *to,uint length __attribute__((unused)))
1829
 
{
1830
 
  uint64_t value=Field_enum::val_int();
1831
 
  to+=packlength-1;
1832
 
  for (uint i=0 ; i < packlength ; i++)
1833
 
  {
1834
 
    *to-- = (uchar) (value & 255);
1835
 
    value>>=8;
1836
 
  }
1837
 
}
1838
 
 
1839
 
 
1840
 
void Field_enum::sql_type(String &res) const
1841
 
{
1842
 
  char buffer[255];
1843
 
  String enum_item(buffer, sizeof(buffer), res.charset());
1844
 
 
1845
 
  res.length(0);
1846
 
  res.append(STRING_WITH_LEN("enum("));
1847
 
 
1848
 
  bool flag=0;
1849
 
  uint *len= typelib->type_lengths;
1850
 
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
1851
 
  {
1852
 
    uint dummy_errors;
1853
 
    if (flag)
1854
 
      res.append(',');
1855
 
    /* convert to res.charset() == utf8, then quote */
1856
 
    enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
1857
 
    append_unescaped(&res, enum_item.ptr(), enum_item.length());
1858
 
    flag= 1;
1859
 
  }
1860
 
  res.append(')');
1861
 
}
1862
 
 
1863
 
 
1864
 
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
1865
 
                             bool keep_type)
1866
 
{
1867
 
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
1868
 
  if (res)
1869
 
    res->typelib= copy_typelib(root, typelib);
1870
 
  return res;
1871
 
}
1872
 
 
1873
 
 
1874
1607
/**
1875
1608
  @retval
1876
1609
    1  if the fields are equally defined