~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/catalog.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
 
#include <config.h>
22
 
 
23
 
#include <drizzled/plugin/catalog.h>
24
 
#include <drizzled/catalog/cache.h>
25
 
#include <drizzled/catalog/local.h>
26
 
#include <drizzled/error.h>
27
 
 
28
 
#include <boost/foreach.hpp>
29
 
 
30
 
namespace drizzled
31
 
{
32
 
namespace plugin
33
 
{
34
 
 
35
 
// Private container we use for holding the instances of engines passed to
36
 
// use from the catalog plugins.
37
 
class Engines {
38
 
  catalog::Engine::vector _catalogs;
39
 
 
40
 
public:
41
 
  static Engines& singleton()
42
 
  {
43
 
    static Engines ptr;
44
 
    return ptr;
45
 
  }
46
 
 
47
 
  catalog::Engine::vector &catalogs()
48
 
  {
49
 
    return _catalogs;
50
 
  }
51
 
};
52
 
 
53
 
Catalog::~Catalog()
54
 
{
55
 
}
56
 
 
57
 
bool Catalog::create(identifier::Catalog::const_reference identifier)
58
 
{
59
 
  message::catalog::shared_ptr message= message::catalog::make_shared(identifier);
60
 
  return create(identifier, message);
61
 
}
62
 
 
63
 
bool Catalog::create(identifier::Catalog::const_reference identifier, message::catalog::shared_ptr &message)
64
 
{
65
 
  assert(message);
66
 
 
67
 
  catalog::lock::Create lock(identifier);
68
 
 
69
 
  if (not lock.locked())
70
 
  {
71
 
    my_error(ER_CATALOG_NO_LOCK, MYF(0), identifier.getName().c_str());
72
 
    return false;
73
 
  }
74
 
 
75
 
  size_t create_count= 0;
76
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
77
 
  {
78
 
    if (ref->create(identifier, message))
79
 
      create_count++;
80
 
  }
81
 
  assert(create_count < 2);
82
 
 
83
 
  if (not create_count)
84
 
  {
85
 
    my_error(ER_CATALOG_CANNOT_CREATE, MYF(0), identifier.getName().c_str());
86
 
    return false;
87
 
  }
88
 
 
89
 
  return true;
90
 
}
91
 
 
92
 
bool Catalog::drop(identifier::Catalog::const_reference identifier)
93
 
{
94
 
  if (identifier == drizzled::catalog::local_identifier())
95
 
  {
96
 
    my_error(drizzled::ER_CATALOG_NO_DROP_LOCAL, MYF(0));
97
 
    return false;
98
 
  }
99
 
 
100
 
  catalog::lock::Erase lock(identifier);
101
 
  if (not lock.locked())
102
 
  {
103
 
    my_error(ER_CATALOG_NO_LOCK, MYF(0), identifier.getName().c_str());
104
 
    return false; 
105
 
  }
106
 
 
107
 
  
108
 
  size_t drop_count= 0;
109
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
110
 
  {
111
 
    if (ref->drop(identifier))
112
 
      drop_count++;
113
 
  }
114
 
  assert(drop_count < 2);
115
 
 
116
 
  if (not drop_count)
117
 
  {
118
 
    my_error(ER_CATALOG_DOES_NOT_EXIST, MYF(0), identifier.getName().c_str());
119
 
    return false;
120
 
  }
121
 
 
122
 
  return true;
123
 
}
124
 
 
125
 
bool Catalog::lock(identifier::Catalog::const_reference identifier)
126
 
{
127
 
  drizzled::error_t error;
128
 
  
129
 
  // We insert a lock into the cache, if this fails we bail.
130
 
  if (not catalog::Cache::singleton().lock(identifier, error))
131
 
  {
132
 
    my_error(error, identifier);
133
 
 
134
 
    return false;
135
 
  }
136
 
 
137
 
  return true;
138
 
}
139
 
 
140
 
 
141
 
bool Catalog::unlock(identifier::Catalog::const_reference identifier)
142
 
{
143
 
  drizzled::error_t error;
144
 
  if (not catalog::Cache::singleton().unlock(identifier, error))
145
 
  {
146
 
    my_error(error, identifier);
147
 
  }
148
 
 
149
 
  return false;
150
 
}
151
 
 
152
 
bool plugin::Catalog::addPlugin(plugin::Catalog *arg)
153
 
{
154
 
  Engines::singleton().catalogs().push_back(arg->engine());
155
 
 
156
 
  return false;
157
 
}
158
 
 
159
 
bool plugin::Catalog::exist(identifier::Catalog::const_reference identifier)
160
 
{
161
 
  if (catalog::Cache::singleton().exist(identifier))
162
 
    return true;
163
 
 
164
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
165
 
  {
166
 
    if (ref->exist(identifier))
167
 
      return true;
168
 
  }
169
 
 
170
 
  return false;
171
 
}
172
 
 
173
 
void plugin::Catalog::getIdentifiers(identifier::Catalog::vector &identifiers)
174
 
{
175
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
176
 
  {
177
 
    ref->getIdentifiers(identifiers);
178
 
  }
179
 
}
180
 
 
181
 
void plugin::Catalog::getMessages(message::catalog::vector &messages)
182
 
{
183
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
184
 
  {
185
 
    ref->getMessages(messages);
186
 
  }
187
 
}
188
 
 
189
 
message::catalog::shared_ptr plugin::Catalog::getMessage(identifier::Catalog::const_reference identifier)
190
 
{
191
 
  drizzled::error_t error;
192
 
  catalog::Instance::shared_ptr instance= catalog::Cache::singleton().find(identifier, error);
193
 
  message::catalog::shared_ptr message;
194
 
 
195
 
  if (instance and instance->message())
196
 
  {
197
 
    return instance->message();
198
 
  }
199
 
 
200
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
201
 
  {
202
 
    if ((message= ref->getMessage(identifier)))
203
 
      return message;
204
 
  }
205
 
 
206
 
  return message;
207
 
}
208
 
 
209
 
catalog::Instance::shared_ptr plugin::Catalog::getInstance(identifier::Catalog::const_reference identifier)
210
 
{
211
 
  drizzled::error_t error;
212
 
  catalog::Instance::shared_ptr instance= catalog::Cache::singleton().find(identifier, error);
213
 
 
214
 
  if (instance)
215
 
    return instance;
216
 
 
217
 
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
218
 
  {
219
 
    message::catalog::shared_ptr message;
220
 
    if (message= ref->getMessage(identifier))
221
 
    {
222
 
      instance= catalog::Instance::make_shared(message);
223
 
      // If this should fail inserting into the cache, we are in a world of
224
 
      // pain.
225
 
      catalog::Cache::singleton().insert(identifier, instance, error);
226
 
 
227
 
      return instance;
228
 
    }
229
 
  }
230
 
 
231
 
  return catalog::Instance::shared_ptr();
232
 
}
233
 
 
234
 
 
235
 
void plugin::Catalog::removePlugin(plugin::Catalog *)
236
 
{
237
 
}
238
 
 
239
 
} /* namespace plugin */
240
 
} /* namespace drizzled */