~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item.cc

  • Committer: Brian Aker
  • Date: 2010-12-18 02:06:13 UTC
  • Revision ID: brian@tangent.org-20101218020613-8lxhcvsy812bu960
Formatting + remove default from switch/case.

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
  {
93
93
    case INT_RESULT:
94
94
      return val_int() != 0;
 
95
 
95
96
    case DECIMAL_RESULT:
96
97
    {
97
98
      my_decimal decimal_value;
100
101
        return !my_decimal_is_zero(val);
101
102
      return false;
102
103
    }
 
104
 
103
105
    case REAL_RESULT:
104
106
    case STRING_RESULT:
105
107
      return val_real() != 0.0;
 
108
 
106
109
    case ROW_RESULT:
107
 
    default:
108
110
      assert(0);
109
111
      abort();
110
112
  }
 
113
 
 
114
  assert(0);
 
115
  abort();
111
116
}
112
117
 
113
118
String *Item::val_string_from_real(String *str)
1044
1049
  case REAL_RESULT:    
1045
1050
    return DRIZZLE_TYPE_DOUBLE;
1046
1051
  case ROW_RESULT:
1047
 
  default:
1048
1052
    assert(0);
1049
 
    abort();
1050
1053
  }
 
1054
 
 
1055
  abort();
1051
1056
}
1052
1057
 
1053
1058
bool Item::is_datetime()
1397
1402
{
1398
1403
  if (a == STRING_RESULT && b == STRING_RESULT)
1399
1404
    return STRING_RESULT;
 
1405
 
1400
1406
  if (a == INT_RESULT && b == INT_RESULT)
1401
1407
    return INT_RESULT;
1402
1408
  else if (a == ROW_RESULT || b == ROW_RESULT)
1403
1409
    return ROW_RESULT;
 
1410
 
1404
1411
  if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
1405
1412
      (b == INT_RESULT || b == DECIMAL_RESULT))
1406
1413
    return DECIMAL_RESULT;
 
1414
 
1407
1415
  return REAL_RESULT;
1408
1416
}
1409
1417
 
1419
1427
 
1420
1428
  switch (res_type) {
1421
1429
  case STRING_RESULT:
1422
 
  {
1423
 
    char buff[MAX_FIELD_WIDTH];
1424
 
    String tmp(buff,sizeof(buff),&my_charset_bin),*result;
1425
 
    result=item->val_str(&tmp);
1426
 
    if (item->null_value)
1427
 
      new_item= new Item_null(name);
1428
 
    else
1429
1430
    {
1430
 
      uint32_t length= result->length();
1431
 
      char *tmp_str= memory::sql_strmake(result->ptr(), length);
1432
 
      new_item= new Item_string(name, tmp_str, length, result->charset());
 
1431
      char buff[MAX_FIELD_WIDTH];
 
1432
      String tmp(buff,sizeof(buff),&my_charset_bin),*result;
 
1433
      result=item->val_str(&tmp);
 
1434
      if (item->null_value)
 
1435
        new_item= new Item_null(name);
 
1436
      else
 
1437
      {
 
1438
        uint32_t length= result->length();
 
1439
        char *tmp_str= memory::sql_strmake(result->ptr(), length);
 
1440
        new_item= new Item_string(name, tmp_str, length, result->charset());
 
1441
      }
 
1442
      break;
1433
1443
    }
1434
 
    break;
1435
 
  }
1436
1444
  case INT_RESULT:
1437
 
  {
1438
 
    int64_t result=item->val_int();
1439
 
    uint32_t length=item->max_length;
1440
 
    bool null_value=item->null_value;
1441
 
    new_item= (null_value ? (Item*) new Item_null(name) :
1442
 
               (Item*) new Item_int(name, result, length));
1443
 
    break;
1444
 
  }
 
1445
    {
 
1446
      int64_t result=item->val_int();
 
1447
      uint32_t length=item->max_length;
 
1448
      bool null_value=item->null_value;
 
1449
      new_item= (null_value ? (Item*) new Item_null(name) :
 
1450
                 (Item*) new Item_int(name, result, length));
 
1451
      break;
 
1452
    }
1445
1453
  case ROW_RESULT:
1446
 
  if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM)
1447
 
  {
1448
 
    /*
1449
 
      Substitute constants only in Item_rows. Don't affect other Items
1450
 
      with ROW_RESULT (eg Item_singlerow_subselect).
 
1454
    if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM)
 
1455
    {
 
1456
      /*
 
1457
        Substitute constants only in Item_rows. Don't affect other Items
 
1458
        with ROW_RESULT (eg Item_singlerow_subselect).
1451
1459
 
1452
 
      For such Items more optimal is to detect if it is constant and replace
1453
 
      it with Item_row. This would optimize queries like this:
1454
 
      SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
1455
 
    */
1456
 
    Item_row *item_row= (Item_row*) item;
1457
 
    Item_row *comp_item_row= (Item_row*) comp_item;
1458
 
    uint32_t col;
1459
 
    new_item= 0;
1460
 
    /*
1461
 
      If item and comp_item are both Item_rows and have same number of cols
1462
 
      then process items in Item_row one by one.
1463
 
      We can't ignore NULL values here as this item may be used with <=>, in
1464
 
      which case NULL's are significant.
1465
 
    */
1466
 
    assert(item->result_type() == comp_item->result_type());
1467
 
    assert(item_row->cols() == comp_item_row->cols());
1468
 
    col= item_row->cols();
1469
 
    while (col-- > 0)
1470
 
      resolve_const_item(session, item_row->addr(col),
1471
 
                         comp_item_row->element_index(col));
1472
 
    break;
1473
 
  }
1474
 
  /* Fallthrough */
 
1460
        For such Items more optimal is to detect if it is constant and replace
 
1461
        it with Item_row. This would optimize queries like this:
 
1462
        SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
 
1463
      */
 
1464
      Item_row *item_row= (Item_row*) item;
 
1465
      Item_row *comp_item_row= (Item_row*) comp_item;
 
1466
      uint32_t col;
 
1467
      new_item= 0;
 
1468
      /*
 
1469
        If item and comp_item are both Item_rows and have same number of cols
 
1470
        then process items in Item_row one by one.
 
1471
        We can't ignore NULL values here as this item may be used with <=>, in
 
1472
        which case NULL's are significant.
 
1473
      */
 
1474
      assert(item->result_type() == comp_item->result_type());
 
1475
      assert(item_row->cols() == comp_item_row->cols());
 
1476
      col= item_row->cols();
 
1477
      while (col-- > 0)
 
1478
        resolve_const_item(session, item_row->addr(col),
 
1479
                           comp_item_row->element_index(col));
 
1480
      break;
 
1481
    }
 
1482
    /* Fallthrough */
1475
1483
  case REAL_RESULT:
1476
 
  {                                             // It must REAL_RESULT
1477
 
    double result= item->val_real();
1478
 
    uint32_t length=item->max_length,decimals=item->decimals;
1479
 
    bool null_value=item->null_value;
1480
 
    new_item= (null_value ? (Item*) new Item_null(name) : (Item*)
1481
 
               new Item_float(name, result, decimals, length));
1482
 
    break;
1483
 
  }
 
1484
    {                                           // It must REAL_RESULT
 
1485
      double result= item->val_real();
 
1486
      uint32_t length=item->max_length,decimals=item->decimals;
 
1487
      bool null_value=item->null_value;
 
1488
      new_item= (null_value ? (Item*) new Item_null(name) : (Item*)
 
1489
                 new Item_float(name, result, decimals, length));
 
1490
      break;
 
1491
    }
1484
1492
  case DECIMAL_RESULT:
1485
 
  {
1486
 
    my_decimal decimal_value;
1487
 
    my_decimal *result= item->val_decimal(&decimal_value);
1488
 
    uint32_t length= item->max_length, decimals= item->decimals;
1489
 
    bool null_value= item->null_value;
1490
 
    new_item= (null_value ?
1491
 
               (Item*) new Item_null(name) :
1492
 
               (Item*) new Item_decimal(name, result, length, decimals));
1493
 
    break;
1494
 
  }
1495
 
  default:
1496
 
    assert(0);
1497
 
  }
 
1493
    {
 
1494
      my_decimal decimal_value;
 
1495
      my_decimal *result= item->val_decimal(&decimal_value);
 
1496
      uint32_t length= item->max_length, decimals= item->decimals;
 
1497
      bool null_value= item->null_value;
 
1498
      new_item= (null_value ?
 
1499
                 (Item*) new Item_null(name) :
 
1500
                 (Item*) new Item_decimal(name, result, length, decimals));
 
1501
      break;
 
1502
    }
 
1503
  }
 
1504
 
1498
1505
  if (new_item)
1499
1506
    session->change_item_tree(ref, new_item);
1500
1507
}
1516
1523
    field->val_str_internal(&field_tmp);
1517
1524
    return not stringcmp(&field_tmp,item_result);
1518
1525
  }
 
1526
 
1519
1527
  if (res_type == INT_RESULT)
1520
1528
    return 1;                                   // Both where of type int
 
1529
 
1521
1530
  if (res_type == DECIMAL_RESULT)
1522
1531
  {
1523
1532
    my_decimal item_buf, *item_val,
1528
1537
    field_val= field->val_decimal(&field_buf);
1529
1538
    return !my_decimal_cmp(item_val, field_val);
1530
1539
  }
 
1540
 
1531
1541
  double result= item->val_real();
1532
1542
  if (item->null_value)
1533
1543
    return 1;
 
1544
 
1534
1545
  return result == field->val_real();
1535
1546
}
1536
1547
 
1566
1577
                                         uint32_t convert_blob_length)
1567
1578
{
1568
1579
  bool maybe_null= item->maybe_null;
1569
 
  Field *new_field;
 
1580
  Field *new_field= NULL;
1570
1581
 
1571
1582
  switch (item->result_type()) {
1572
1583
  case REAL_RESULT:
1573
1584
    new_field= new Field_double(item->max_length, maybe_null,
1574
1585
                                item->name, item->decimals, true);
1575
1586
    break;
 
1587
 
1576
1588
  case INT_RESULT:
1577
1589
    /*
1578
1590
      Select an integer type with the minimal fit precision.
1579
1591
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
1580
1592
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
1581
 
      Int32 : make them field::Int64.
 
1593
      Int32 -> make them field::Int64.
1582
1594
    */
1583
1595
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
1584
1596
      new_field=new field::Int64(item->max_length, maybe_null,
1587
1599
      new_field=new field::Int32(item->max_length, maybe_null,
1588
1600
                                 item->name, item->unsigned_flag);
1589
1601
    break;
 
1602
 
1590
1603
  case STRING_RESULT:
1591
1604
    assert(item->collation.collation);
1592
1605
 
1619
1632
    }
1620
1633
    new_field->set_derivation(item->collation.derivation);
1621
1634
    break;
 
1635
 
1622
1636
  case DECIMAL_RESULT:
1623
 
  {
1624
 
    uint8_t dec= item->decimals;
1625
 
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
1626
 
    uint32_t len= item->max_length;
1627
 
 
1628
 
    /*
1629
 
      Trying to put too many digits overall in a DECIMAL(prec,dec)
1630
 
      will always throw a warning. We must limit dec to
1631
 
      DECIMAL_MAX_SCALE however to prevent an assert() later.
1632
 
    */
1633
 
 
1634
 
    if (dec > 0)
1635
1637
    {
1636
 
      signed int overflow;
1637
 
 
1638
 
      dec= min(dec, (uint8_t)DECIMAL_MAX_SCALE);
 
1638
      uint8_t dec= item->decimals;
 
1639
      uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
 
1640
      uint32_t len= item->max_length;
1639
1641
 
1640
1642
      /*
1641
 
        If the value still overflows the field with the corrected dec,
1642
 
        we'll throw out decimals rather than integers. This is still
1643
 
        bad and of course throws a truncation warning.
1644
 
        +1: for decimal point
 
1643
        Trying to put too many digits overall in a DECIMAL(prec,dec)
 
1644
        will always throw a warning. We must limit dec to
 
1645
        DECIMAL_MAX_SCALE however to prevent an assert() later.
1645
1646
      */
1646
1647
 
1647
 
      overflow= my_decimal_precision_to_length(intg + dec, dec,
1648
 
                                               item->unsigned_flag) - len;
1649
 
 
1650
 
      if (overflow > 0)
1651
 
        dec= max(0, dec - overflow);            // too long, discard fract
1652
 
      else
1653
 
        len-= item->decimals - dec;             // corrected value fits
 
1648
      if (dec > 0)
 
1649
      {
 
1650
        signed int overflow;
 
1651
 
 
1652
        dec= min(dec, (uint8_t)DECIMAL_MAX_SCALE);
 
1653
 
 
1654
        /*
 
1655
          If the value still overflows the field with the corrected dec,
 
1656
          we'll throw out decimals rather than integers. This is still
 
1657
          bad and of course throws a truncation warning.
 
1658
          +1: for decimal point
 
1659
        */
 
1660
 
 
1661
        overflow= my_decimal_precision_to_length(intg + dec, dec,
 
1662
                                                 item->unsigned_flag) - len;
 
1663
 
 
1664
        if (overflow > 0)
 
1665
          dec= max(0, dec - overflow);            // too long, discard fract
 
1666
        else
 
1667
          len-= item->decimals - dec;             // corrected value fits
 
1668
      }
 
1669
 
 
1670
      new_field= new Field_decimal(len,
 
1671
                                   maybe_null,
 
1672
                                   item->name,
 
1673
                                   dec,
 
1674
                                   item->unsigned_flag);
 
1675
      break;
1654
1676
    }
1655
1677
 
1656
 
    new_field= new Field_decimal(len,
1657
 
                                 maybe_null,
1658
 
                                 item->name,
1659
 
                                 dec,
1660
 
                                 item->unsigned_flag);
1661
 
    break;
1662
 
  }
1663
1678
  case ROW_RESULT:
1664
 
  default:
1665
1679
    // This case should never be choosen
1666
1680
    assert(0);
1667
1681
    abort();
1668
1682
  }
 
1683
 
1669
1684
  if (new_field)
1670
1685
    new_field->init(table);
1671
1686
 
1672
1687
  if (copy_func && item->is_result_field())
1673
1688
    *((*copy_func)++) = item;                   // Save for copy_funcs
 
1689
 
1674
1690
  if (modify_item)
1675
1691
    item->set_result_field(new_field);
 
1692
 
1676
1693
  if (item->type() == Item::NULL_ITEM)
1677
1694
    new_field->is_created_from_null_item= true;
 
1695
 
1678
1696
  return new_field;
1679
1697
}
1680
1698