~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/time/extract.cc

  • Committer: Stewart Smith
  • Date: 2010-08-12 16:48:46 UTC
  • mto: This revision was merged to the branch mainline in revision 1707.
  • Revision ID: stewart@flamingspork.com-20100812164846-s9bhy47g60bvqs41
bug lp:611379 Equivalent queries with Impossible where return different results

The following two equivalent queries return different results in maria 5.2 and 5.3 (and identical results in mysql 5.5.5) :

SELECT SUM( DISTINCT table1 .`pk` ) FROM B table1 STRAIGHT_JOIN ( BB table2 JOIN CC ON table2 .`col_varchar_key` ) ON table2 .`pk` ;

SELECT * FROM ( SELECT SUM( DISTINCT table1 .`pk` ) FROM B table1 STRAIGHT_JOIN ( BB table2 JOIN CC ON table2 .`col_varchar_key` ) ON table2 .`pk` );

MariaDB returns 0 on the second query and NULL on the first, whereas MySQL returns NULL on both. In MariaDB, both EXPLAIN plans agree that "Impossible WHERE noticed after reading const tables"



We have some slightly different output in drizzle:

main.bug_lp611379 [ fail ]
drizzletest: At line 9: query 'explain select * from (select sum(distinct t1.a) from t1,t2 where t1.a=t2.a)
as t' failed: 1048: Column 'sum(distinct t1.a)' cannot be null

but the fix gets us the correct query results, although with slightly different execution plans.



This fix is directly ported from MariaDB.

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
 
22
 
#include <drizzled/temporal.h>
23
 
#include <drizzled/error.h>
24
 
#include <drizzled/session.h>
25
 
#include <drizzled/calendar.h>
26
 
#include <drizzled/function/time/extract.h>
 
22
#include "drizzled/temporal.h"
 
23
#include "drizzled/error.h"
 
24
#include "drizzled/session.h"
 
25
#include "drizzled/calendar.h"
 
26
#include "drizzled/function/time/extract.h"
27
27
 
28
28
namespace drizzled
29
29
{
113
113
          char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
114
114
          String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
115
115
          String *res= args[0]->val_str(&tmp);
116
 
 
117
 
          if (res && (res != &tmp))
118
 
          {
119
 
            tmp.copy(*res);
120
 
          }
121
 
 
122
 
          if (! datetime_temporal.from_string(tmp.c_ptr(), tmp.length()))
 
116
          if (! datetime_temporal.from_string(res->c_ptr(), res->length()))
123
117
          {
124
118
            /* 
125
119
            * Could not interpret the function argument as a temporal value, 
126
120
            * so throw an error and return 0
127
121
            */
128
 
            my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
 
122
            my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
129
123
            return 0;
130
124
          }
131
125
        }
147
141
 
148
142
          res= args[0]->val_str(&tmp);
149
143
 
150
 
          if (res && (res != &tmp))
151
 
          {
152
 
            tmp.copy(*res);
153
 
          }
154
 
 
155
 
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
 
144
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
156
145
          return 0;
157
146
        }
158
147
    }
183
172
    char time_buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
184
173
    String tmp_time(time_buff,sizeof(time_buff), &my_charset_utf8_bin);
185
174
    String *time_res= args[0]->val_str(&tmp_time);
186
 
 
187
 
    if (time_res && (time_res != &tmp_time))
188
 
    {
189
 
      tmp_time.copy(*time_res);
190
 
    }
191
 
 
192
 
    if (! time_temporal.from_string(tmp_time.c_ptr(), tmp_time.length()))
 
175
    if (! time_temporal.from_string(time_res->c_ptr(), time_res->length()))
193
176
    {
194
177
      /* 
195
178
       * OK, we failed to match the first argument as a string
214
197
            char buff[DRIZZLE_MAX_LENGTH_DATETIME_AS_STRING];
215
198
            String tmp(buff,sizeof(buff), &my_charset_utf8_bin);
216
199
            String *res= args[0]->val_str(&tmp);
217
 
 
218
 
            if (res && (res != &tmp))
219
 
            {
220
 
              tmp.copy(*res);
221
 
            }
222
 
 
223
 
            if (! datetime_temporal.from_string(tmp.c_ptr(), tmp.length()))
 
200
            if (! datetime_temporal.from_string(res->c_ptr(), res->length()))
224
201
            {
225
202
              /* 
226
203
               * Could not interpret the function argument as a temporal value, 
227
204
               * so throw an error and return 0
228
205
               */
229
 
              my_error(ER_INVALID_DATETIME_VALUE, MYF(0), tmp.c_ptr());
 
206
              my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
230
207
              return 0;
231
208
            }
232
209
          }
275
252
    case INTERVAL_WEEK:
276
253
      return iso_week_number_from_gregorian_date(temporal->years()
277
254
                                               , temporal->months()
278
 
                                               , temporal->days());
 
255
                                               , temporal->days()
 
256
                                               , NULL); /* NULL is year_out parameter, which is not needed */
279
257
    case INTERVAL_DAY:
280
258
      return (int64_t) temporal->days();
281
259
    case INTERVAL_DAY_HOUR: