~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table/instance/shared.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) 2011 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/table/instance/shared.h>
24
 
#include <drizzled/definition/cache.h>
25
 
#include <drizzled/plugin/event_observer.h>
26
 
 
27
 
namespace drizzled
28
 
{
29
 
 
30
 
namespace table
31
 
{
32
 
 
33
 
namespace instance
34
 
{
35
 
 
36
 
Shared::Shared(const identifier::Table::Type type_arg,
37
 
               const identifier::Table &identifier,
38
 
               char *path_arg, uint32_t path_length_arg) :
39
 
  TableShare(type_arg, identifier, path_arg, path_length_arg),
40
 
  event_observers(NULL)
41
 
{
42
 
}
43
 
 
44
 
Shared::Shared(const identifier::Table &identifier) :
45
 
  TableShare(identifier, identifier.getKey()),
46
 
  event_observers(NULL)
47
 
{
48
 
}
49
 
 
50
 
Shared::shared_ptr Shared::foundTableShare(Shared::shared_ptr share)
51
 
{
52
 
  /*
53
 
    We found an existing table definition. Return it if we didn't get
54
 
    an error when reading the table definition from file.
55
 
  */
56
 
  if (share->error)
57
 
  {
58
 
    /* Table definition contained an error */
59
 
    share->open_table_error(share->error, share->open_errno, share->errarg);
60
 
 
61
 
    return Shared::shared_ptr();
62
 
  }
63
 
 
64
 
  share->incrementTableCount();
65
 
 
66
 
  return share;
67
 
}
68
 
 
69
 
 
70
 
 
71
 
/*
72
 
  Get a shared instance for a table.
73
 
 
74
 
  get_table_share()
75
 
  session                       Thread handle
76
 
  table_list            Table that should be opened
77
 
  key                   Table cache key
78
 
  key_length            Length of key
79
 
  error                 out: Error code from open_table_def()
80
 
 
81
 
  IMPLEMENTATION
82
 
  Get a table definition from the table definition cache.
83
 
  If it doesn't exist, create a new from the table definition file.
84
 
 
85
 
  NOTES
86
 
  We must have wrlock on table::Cache::singleton().mutex() when we come here
87
 
  (To be changed later)
88
 
 
89
 
  RETURN
90
 
  0  Error
91
 
#  Share for table
92
 
*/
93
 
 
94
 
Shared::shared_ptr Shared::make_shared(Session *session, 
95
 
                                       const identifier::Table &identifier,
96
 
                                       int &in_error)
97
 
{
98
 
  Shared::shared_ptr share;
99
 
 
100
 
  in_error= 0;
101
 
 
102
 
  /* Read table definition from cache */
103
 
  if ((share= definition::Cache::singleton().find(identifier.getKey())))
104
 
    return foundTableShare(share);
105
 
 
106
 
  share.reset(new Shared(message::Table::STANDARD, identifier));
107
 
  
108
 
  if (share->open_table_def(*session, identifier))
109
 
  {
110
 
    in_error= share->error;
111
 
 
112
 
    return Shared::shared_ptr();
113
 
  }
114
 
  share->incrementTableCount();                         // Mark in use
115
 
  
116
 
  plugin::EventObserver::registerTableEvents(*share);
117
 
 
118
 
  bool ret= definition::Cache::singleton().insert(identifier.getKey(), share);
119
 
 
120
 
  if (not ret)
121
 
    return Shared::shared_ptr();
122
 
 
123
 
  return share;
124
 
}
125
 
 
126
 
Shared::~Shared()
127
 
{
128
 
  assert(getTableCount() == 0);
129
 
  plugin::EventObserver::deregisterTableEvents(*this);
130
 
}
131
 
 
132
 
 
133
 
/*****************************************************************************
134
 
  Functions to handle table definition cach (TableShare)
135
 
 *****************************************************************************/
136
 
 
137
 
/*
138
 
  Mark that we are not using table share anymore.
139
 
 
140
 
  SYNOPSIS
141
 
  release()
142
 
  share         Table share
143
 
 
144
 
  IMPLEMENTATION
145
 
  If ref_count goes to zero and (we have done a refresh or if we have
146
 
  already too many open table shares) then delete the definition.
147
 
*/
148
 
 
149
 
void release(TableShare *share)
150
 
{
151
 
  bool to_be_deleted= false;
152
 
  //safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
153
 
 
154
 
  share->lock();
155
 
  if (not share->decrementTableCount())
156
 
  {
157
 
    to_be_deleted= true;
158
 
  }
159
 
  share->unlock();
160
 
 
161
 
  if (to_be_deleted)
162
 
  {
163
 
    definition::Cache::singleton().erase(share->getCacheKey());
164
 
  }
165
 
}
166
 
 
167
 
void release(TableShare::shared_ptr &share)
168
 
{
169
 
  bool to_be_deleted= false;
170
 
#if 0
171
 
  safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
172
 
#endif
173
 
 
174
 
  share->lock();
175
 
  if (not share->decrementTableCount())
176
 
  {
177
 
    to_be_deleted= true;
178
 
  }
179
 
  share->unlock();
180
 
 
181
 
  if (to_be_deleted)
182
 
  {
183
 
    definition::Cache::singleton().erase(share->getCacheKey());
184
 
  }
185
 
}
186
 
 
187
 
void release(const identifier::Table &identifier)
188
 
{
189
 
  TableShare::shared_ptr share= definition::Cache::singleton().find(identifier.getKey());
190
 
  if (share)
191
 
  {
192
 
    share->resetVersion(); 
193
 
    if (share->getTableCount() == 0)
194
 
    {
195
 
      definition::Cache::singleton().erase(identifier.getKey());
196
 
    }
197
 
  }
198
 
}
199
 
 
200
 
 
201
 
} /* namespace instance */
202
 
} /* namespace table */
203
 
} /* namespace drizzled */