~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item.cc

  • Committer: Brian Aker
  • Date: 2010-12-18 00:43:02 UTC
  • Revision ID: brian@tangent.org-20101218004302-4ivzuuzdkblyqe18
Refactor naming for integers.

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
 
 
96
95
    case DECIMAL_RESULT:
97
96
    {
98
97
      my_decimal decimal_value;
101
100
        return !my_decimal_is_zero(val);
102
101
      return false;
103
102
    }
104
 
 
105
103
    case REAL_RESULT:
106
104
    case STRING_RESULT:
107
105
      return val_real() != 0.0;
108
 
 
109
106
    case ROW_RESULT:
 
107
    default:
110
108
      assert(0);
111
109
      abort();
112
110
  }
113
 
 
114
 
  assert(0);
115
 
  abort();
116
111
}
117
112
 
118
113
String *Item::val_string_from_real(String *str)
1049
1044
  case REAL_RESULT:    
1050
1045
    return DRIZZLE_TYPE_DOUBLE;
1051
1046
  case ROW_RESULT:
 
1047
  default:
1052
1048
    assert(0);
 
1049
    abort();
1053
1050
  }
1054
 
 
1055
 
  abort();
1056
1051
}
1057
1052
 
1058
1053
bool Item::is_datetime()
1402
1397
{
1403
1398
  if (a == STRING_RESULT && b == STRING_RESULT)
1404
1399
    return STRING_RESULT;
1405
 
 
1406
1400
  if (a == INT_RESULT && b == INT_RESULT)
1407
1401
    return INT_RESULT;
1408
1402
  else if (a == ROW_RESULT || b == ROW_RESULT)
1409
1403
    return ROW_RESULT;
1410
 
 
1411
1404
  if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
1412
1405
      (b == INT_RESULT || b == DECIMAL_RESULT))
1413
1406
    return DECIMAL_RESULT;
1414
 
 
1415
1407
  return REAL_RESULT;
1416
1408
}
1417
1409
 
1427
1419
 
1428
1420
  switch (res_type) {
1429
1421
  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
1430
1429
    {
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;
 
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());
1443
1433
    }
 
1434
    break;
 
1435
  }
1444
1436
  case INT_RESULT:
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
 
    }
 
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
  }
1453
1445
  case ROW_RESULT:
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).
 
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).
1459
1451
 
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 */
 
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 */
1483
1475
  case REAL_RESULT:
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
 
    }
 
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
  }
1492
1484
  case DECIMAL_RESULT:
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
 
 
 
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
  }
1505
1498
  if (new_item)
1506
1499
    session->change_item_tree(ref, new_item);
1507
1500
}
1523
1516
    field->val_str_internal(&field_tmp);
1524
1517
    return not stringcmp(&field_tmp,item_result);
1525
1518
  }
1526
 
 
1527
1519
  if (res_type == INT_RESULT)
1528
1520
    return 1;                                   // Both where of type int
1529
 
 
1530
1521
  if (res_type == DECIMAL_RESULT)
1531
1522
  {
1532
1523
    my_decimal item_buf, *item_val,
1537
1528
    field_val= field->val_decimal(&field_buf);
1538
1529
    return !my_decimal_cmp(item_val, field_val);
1539
1530
  }
1540
 
 
1541
1531
  double result= item->val_real();
1542
1532
  if (item->null_value)
1543
1533
    return 1;
1544
 
 
1545
1534
  return result == field->val_real();
1546
1535
}
1547
1536
 
1577
1566
                                         uint32_t convert_blob_length)
1578
1567
{
1579
1568
  bool maybe_null= item->maybe_null;
1580
 
  Field *new_field= NULL;
 
1569
  Field *new_field;
1581
1570
 
1582
1571
  switch (item->result_type()) {
1583
1572
  case REAL_RESULT:
1584
1573
    new_field= new Field_double(item->max_length, maybe_null,
1585
1574
                                item->name, item->decimals, true);
1586
1575
    break;
1587
 
 
1588
1576
  case INT_RESULT:
1589
1577
    /*
1590
1578
      Select an integer type with the minimal fit precision.
1591
1579
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
1592
1580
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
1593
 
      Int32 -> make them field::Int64.
 
1581
      Int32 : make them field::Int64.
1594
1582
    */
1595
1583
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
1596
1584
      new_field=new field::Int64(item->max_length, maybe_null,
1599
1587
      new_field=new field::Int32(item->max_length, maybe_null,
1600
1588
                                 item->name, item->unsigned_flag);
1601
1589
    break;
1602
 
 
1603
1590
  case STRING_RESULT:
1604
1591
    assert(item->collation.collation);
1605
1592
 
1632
1619
    }
1633
1620
    new_field->set_derivation(item->collation.derivation);
1634
1621
    break;
1635
 
 
1636
1622
  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)
1637
1635
    {
1638
 
      uint8_t dec= item->decimals;
1639
 
      uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
1640
 
      uint32_t len= item->max_length;
 
1636
      signed int overflow;
 
1637
 
 
1638
      dec= min(dec, (uint8_t)DECIMAL_MAX_SCALE);
1641
1639
 
1642
1640
      /*
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.
 
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
1646
1645
      */
1647
1646
 
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;
 
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
1676
1654
    }
1677
1655
 
 
1656
    new_field= new Field_decimal(len,
 
1657
                                 maybe_null,
 
1658
                                 item->name,
 
1659
                                 dec,
 
1660
                                 item->unsigned_flag);
 
1661
    break;
 
1662
  }
1678
1663
  case ROW_RESULT:
 
1664
  default:
1679
1665
    // This case should never be choosen
1680
1666
    assert(0);
1681
1667
    abort();
1682
1668
  }
1683
 
 
1684
1669
  if (new_field)
1685
1670
    new_field->init(table);
1686
1671
 
1687
1672
  if (copy_func && item->is_result_field())
1688
1673
    *((*copy_func)++) = item;                   // Save for copy_funcs
1689
 
 
1690
1674
  if (modify_item)
1691
1675
    item->set_result_field(new_field);
1692
 
 
1693
1676
  if (item->type() == Item::NULL_ITEM)
1694
1677
    new_field->is_created_from_null_item= true;
1695
 
 
1696
1678
  return new_field;
1697
1679
}
1698
1680