~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/numhybrid.cc

  • Committer: Prafulla Tekawade
  • Date: 2010-07-13 16:07:35 UTC
  • mto: (1662.1.4 rollup)
  • mto: This revision was merged to the branch mainline in revision 1664.
  • Revision ID: prafulla_t@users.sourceforge.net-20100713160735-2fsdtrm3azayuyu1
This bug is simillar to mysql bug 36133
http://bugs.mysql.com/bug.php?id=36133

Taking changes from that fix.

  - The problem was that the range optimizer evaluated constant expressions, 
    and among them it would try to evaluate IN-subquery predicates slated for
    handling with materialization strategy. However, these predicates require
    that parent_join->setup_subquery_materialization() is invoked before one
    attempts to evaluate them.
  
  - Fixed by making the range optimizer not to evaluate expressions that have
    item->is_expensive() == TRUE (these are materialization subqueries and 
    stored function calls). This should also resolve the problem that EXPLAIN 
    may be too long. 
    This change cuts off some opportunities for range optimizer, but this is 
    the price we're willing to pay for separation of query optimization and
    execution. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
 
20
#include "config.h"
21
21
#include <math.h>
22
22
#include <drizzled/function/numhybrid.h>
23
23
 
38
38
  assert(fixed == 1);
39
39
  switch (hybrid_type) {
40
40
  case DECIMAL_RESULT:
41
 
    {
42
 
      type::Decimal decimal_value, *val;
43
 
      if (!(val= decimal_op(&decimal_value)))
44
 
        return 0;                                 // null is set
45
 
      class_decimal_round(E_DEC_FATAL_ERROR, val, decimals, false, val);
46
 
      class_decimal2string(val, 0, str);
47
 
      break;
48
 
    }
 
41
  {
 
42
    my_decimal decimal_value, *val;
 
43
    if (!(val= decimal_op(&decimal_value)))
 
44
      return 0;                                 // null is set
 
45
    my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, false, val);
 
46
    my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
 
47
    break;
 
48
  }
49
49
  case INT_RESULT:
50
 
    {
51
 
      int64_t nr= int_op();
52
 
      if (null_value)
53
 
        return 0;
54
 
      str->set_int(nr, unsigned_flag, &my_charset_bin);
55
 
      break;
56
 
    }
 
50
  {
 
51
    int64_t nr= int_op();
 
52
    if (null_value)
 
53
      return 0;
 
54
    str->set_int(nr, unsigned_flag, &my_charset_bin);
 
55
    break;
 
56
  }
57
57
  case REAL_RESULT:
58
 
    {
59
 
      double nr= real_op();
60
 
      if (null_value)
61
 
        return 0;
62
 
      str->set_real(nr,decimals,&my_charset_bin);
63
 
      break;
64
 
    }
 
58
  {
 
59
    double nr= real_op();
 
60
    if (null_value)
 
61
      return 0;
 
62
    str->set_real(nr,decimals,&my_charset_bin);
 
63
    break;
 
64
  }
65
65
  case STRING_RESULT:
66
66
    return str_op(&str_value);
67
 
  case ROW_RESULT:
 
67
  default:
68
68
    assert(0);
69
69
  }
70
70
  return str;
76
76
  assert(fixed == 1);
77
77
  switch (hybrid_type) {
78
78
  case DECIMAL_RESULT:
79
 
    {
80
 
      type::Decimal decimal_value, *val;
81
 
      double result;
82
 
      if (!(val= decimal_op(&decimal_value)))
83
 
        return 0.0;                               // null is set
84
 
      class_decimal2double(E_DEC_FATAL_ERROR, val, &result);
85
 
      return result;
86
 
    }
 
79
  {
 
80
    my_decimal decimal_value, *val;
 
81
    double result;
 
82
    if (!(val= decimal_op(&decimal_value)))
 
83
      return 0.0;                               // null is set
 
84
    my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
 
85
    return result;
 
86
  }
87
87
  case INT_RESULT:
88
 
    {
89
 
      int64_t result= int_op();
90
 
      return unsigned_flag ? (double) ((uint64_t) result) : (double) result;
91
 
    }
 
88
  {
 
89
    int64_t result= int_op();
 
90
    return unsigned_flag ? (double) ((uint64_t) result) : (double) result;
 
91
  }
92
92
  case REAL_RESULT:
93
93
    return real_op();
94
94
  case STRING_RESULT:
95
 
    {
96
 
      char *end_not_used;
97
 
      int err_not_used;
98
 
      String *res= str_op(&str_value);
99
 
      return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
100
 
                               &end_not_used, &err_not_used) : 0.0);
101
 
    }
102
 
  case ROW_RESULT:
 
95
  {
 
96
    char *end_not_used;
 
97
    int err_not_used;
 
98
    String *res= str_op(&str_value);
 
99
    return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
 
100
                             &end_not_used, &err_not_used) : 0.0);
 
101
  }
 
102
  default:
103
103
    assert(0);
104
104
  }
105
 
 
106
105
  return 0.0;
107
106
}
108
107
 
112
111
  assert(fixed == 1);
113
112
  switch (hybrid_type) {
114
113
  case DECIMAL_RESULT:
115
 
    {
116
 
      type::Decimal decimal_value, *val;
117
 
      if (!(val= decimal_op(&decimal_value)))
118
 
        return 0;                                 // null is set
119
 
      int64_t result;
120
 
      val->val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &result);
121
 
      return result;
122
 
    }
 
114
  {
 
115
    my_decimal decimal_value, *val;
 
116
    if (!(val= decimal_op(&decimal_value)))
 
117
      return 0;                                 // null is set
 
118
    int64_t result;
 
119
    my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
 
120
    return result;
 
121
  }
123
122
  case INT_RESULT:
124
123
    return int_op();
125
124
  case REAL_RESULT:
126
125
    return (int64_t) rint(real_op());
127
126
  case STRING_RESULT:
128
 
    {
129
 
      int err_not_used;
130
 
      String *res;
131
 
      if (!(res= str_op(&str_value)))
132
 
        return 0;
 
127
  {
 
128
    int err_not_used;
 
129
    String *res;
 
130
    if (!(res= str_op(&str_value)))
 
131
      return 0;
133
132
 
134
 
      char *end= (char*) res->ptr() + res->length();
135
 
      const CHARSET_INFO * const cs= str_value.charset();
136
 
      return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
137
 
    }
138
 
  case ROW_RESULT:
 
133
    char *end= (char*) res->ptr() + res->length();
 
134
    const CHARSET_INFO * const cs= str_value.charset();
 
135
    return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
 
136
  }
 
137
  default:
139
138
    assert(0);
140
139
  }
141
140
  return 0;
142
141
}
143
142
 
144
143
 
145
 
type::Decimal *Item_func_numhybrid::val_decimal(type::Decimal *decimal_value)
 
144
my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
146
145
{
147
 
  type::Decimal *val= decimal_value;
 
146
  my_decimal *val= decimal_value;
148
147
  assert(fixed == 1);
149
 
 
150
148
  switch (hybrid_type) {
151
149
  case DECIMAL_RESULT:
152
150
    val= decimal_op(decimal_value);
153
151
    break;
154
152
  case INT_RESULT:
155
 
    {
156
 
      int64_t result= int_op();
157
 
      int2_class_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
158
 
      break;
159
 
    }
 
153
  {
 
154
    int64_t result= int_op();
 
155
    int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
 
156
    break;
 
157
  }
160
158
  case REAL_RESULT:
161
 
    {
162
 
      double result= (double)real_op();
163
 
      double2_class_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
164
 
      break;
165
 
    }
 
159
  {
 
160
    double result= (double)real_op();
 
161
    double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
 
162
    break;
 
163
  }
166
164
  case STRING_RESULT:
167
 
    {
168
 
      String *res;
169
 
      if (!(res= str_op(&str_value)))
170
 
        return NULL;
 
165
  {
 
166
    String *res;
 
167
    if (!(res= str_op(&str_value)))
 
168
      return NULL;
171
169
 
172
 
      decimal_value->store(E_DEC_FATAL_ERROR, (char*) res->ptr(),
173
 
                           res->length(), res->charset());
174
 
      break;
175
 
    }
 
170
    str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
 
171
                   res->length(), res->charset(), decimal_value);
 
172
    break;
 
173
  }
176
174
  case ROW_RESULT:
 
175
  default:
177
176
    assert(0);
178
177
  }
179
 
 
180
178
  return val;
181
179
}
182
180