~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/uuid.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
 
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2010 Brian Aker
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
21
 
 
22
 
#include <config.h>
23
 
 
24
 
#include <algorithm>
25
 
 
26
 
#include <uuid/uuid.h>
27
 
 
28
 
#include <drizzled/field/uuid.h>
29
 
 
30
 
#include <drizzled/error.h>
31
 
#include <drizzled/internal/my_sys.h>
32
 
#include <drizzled/session.h>
33
 
#include <drizzled/table.h>
34
 
 
35
 
namespace drizzled
36
 
{
37
 
namespace field
38
 
{
39
 
 
40
 
Uuid::Uuid(unsigned char *ptr_arg,
41
 
           uint32_t len_arg,
42
 
           unsigned char *null_ptr_arg,
43
 
           unsigned char null_bit_arg,
44
 
           const char *field_name_arg) :
45
 
  Field(ptr_arg, len_arg,
46
 
        null_ptr_arg,
47
 
        null_bit_arg,
48
 
        Field::NONE,
49
 
        field_name_arg),
50
 
  is_set(false)
51
 
{
52
 
}
53
 
 
54
 
int Uuid::cmp(const unsigned char *a, const unsigned char *b)
55
 
56
 
  return memcmp(a, b, sizeof(uuid_t));
57
 
}
58
 
 
59
 
int Uuid::store(const char *from, uint32_t length, const CHARSET_INFO * const )
60
 
{
61
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
62
 
  type::Uuid uu;
63
 
 
64
 
  if (is_set)
65
 
  {
66
 
    is_set= false;
67
 
    return 0;
68
 
  }
69
 
 
70
 
  if (length != type::Uuid::DISPLAY_LENGTH)
71
 
  {
72
 
    my_error(ER_INVALID_UUID_VALUE, MYF(ME_FATALERROR));
73
 
    return 1;
74
 
  }
75
 
 
76
 
  if (uu.parse(from))
77
 
  {
78
 
    my_error(ER_INVALID_UUID_VALUE, MYF(ME_FATALERROR));
79
 
    return 1;
80
 
  }
81
 
 
82
 
  uu.pack(ptr);
83
 
 
84
 
  return 0;
85
 
}
86
 
 
87
 
int Uuid::store(int64_t , bool )
88
 
{
89
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
90
 
  my_error(ER_INVALID_UUID_VALUE, MYF(ME_FATALERROR));
91
 
  return 1;
92
 
}
93
 
 
94
 
int Uuid::store_decimal(const drizzled::type::Decimal*)
95
 
{
96
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
97
 
  my_error(ER_INVALID_UUID_VALUE, MYF(ME_FATALERROR));
98
 
  return 1;
99
 
}
100
 
 
101
 
void Uuid::sql_type(String &res) const
102
 
{
103
 
  res.set_ascii(STRING_WITH_LEN("uuid"));
104
 
}
105
 
 
106
 
double Uuid::val_real() const
107
 
{
108
 
  ASSERT_COLUMN_MARKED_FOR_READ;
109
 
  my_error(ER_INVALID_UUID_VALUE, MYF(ME_FATALERROR));
110
 
  return 0;
111
 
}
112
 
 
113
 
int64_t Uuid::val_int() const
114
 
{
115
 
  ASSERT_COLUMN_MARKED_FOR_READ;
116
 
  my_error(ER_INVALID_UUID_VALUE, MYF(ME_FATALERROR));
117
 
  return 0;
118
 
}
119
 
 
120
 
#ifdef NOT_YET
121
 
void Uuid::generate()
122
 
{
123
 
  uuid_t uu;
124
 
  uuid_generate_time(uu);
125
 
  memcpy(ptr, uu, sizeof(uuid_t));
126
 
  is_set= true;
127
 
}
128
 
 
129
 
void Uuid::set(const unsigned char *arg)
130
 
{
131
 
  memcpy(ptr, arg, sizeof(uuid_t));
132
 
  is_set= true;
133
 
}
134
 
#endif
135
 
 
136
 
String *Uuid::val_str(String *val_buffer, String *) const
137
 
{
138
 
  const CHARSET_INFO * const cs= &my_charset_bin;
139
 
  uint32_t mlength= (type::Uuid::DISPLAY_BUFFER_LENGTH) * cs->mbmaxlen;
140
 
  type::Uuid uu;
141
 
 
142
 
  val_buffer->alloc(mlength);
143
 
  char *buffer=(char*) val_buffer->ptr();
144
 
 
145
 
  ASSERT_COLUMN_MARKED_FOR_READ;
146
 
 
147
 
  uu.unpack(ptr);
148
 
  uu.unparse(buffer);
149
 
 
150
 
  val_buffer->length(type::Uuid::DISPLAY_LENGTH);
151
 
 
152
 
  return val_buffer;
153
 
}
154
 
 
155
 
void Uuid::sort_string(unsigned char *to, uint32_t length_arg)
156
 
{
157
 
  assert(length_arg == type::Uuid::LENGTH);
158
 
  memcpy(to, ptr, length_arg);
159
 
}
160
 
 
161
 
bool Uuid::get_date(type::Time &ltime, uint32_t ) const
162
 
{
163
 
  type::Uuid uu;
164
 
 
165
 
  uu.unpack(ptr);
166
 
 
167
 
  if (uu.isTimeType())
168
 
  {
169
 
    struct timeval ret_tv;
170
 
 
171
 
    memset(&ret_tv, 0, sizeof(struct timeval));
172
 
 
173
 
    uu.time(ret_tv);
174
 
 
175
 
    ltime.store(ret_tv);
176
 
 
177
 
    return false;
178
 
  }
179
 
  ltime.reset();
180
 
 
181
 
  return true;
182
 
}
183
 
 
184
 
bool Uuid::get_time(type::Time &ltime) const
185
 
{
186
 
  return get_date(ltime, 0);
187
 
}
188
 
 
189
 
} /* namespace field */
190
 
} /* namespace drizzled */