1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
1999.6.1
by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file |
4 |
* Copyright (C) 2009 Sun Microsystems, Inc.
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
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 |
||
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
21 |
#include <config.h> |
2154.2.17
by Brian Aker
Additional removal of session |
22 |
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
23 |
#include <drizzled/show.h> |
24 |
#include <drizzled/lock.h> |
|
25 |
#include <drizzled/session.h> |
|
26 |
#include <drizzled/statement/create_table.h> |
|
1802.12.1
by Brian Aker
This solves bug lp:654905 |
27 |
#include <drizzled/message.h> |
1660.1.1
by Brian Aker
Merge in move identifier work. |
28 |
#include <drizzled/identifier.h> |
2148.7.12
by Brian Aker
Merge in header fixes. |
29 |
#include <drizzled/plugin/storage_engine.h> |
2154.2.17
by Brian Aker
Additional removal of session |
30 |
#include <drizzled/select_create.h> |
2239.1.9
by Olaf van der Spek
Refactor includes |
31 |
#include <drizzled/table_ident.h> |
1245.3.3
by Stewart Smith
convert builtin table options to use key,value code in parser |
32 |
|
1340.1.4
by Brian Aker
A first pass through adding a timestamp to our proto. |
33 |
#include <iostream> |
34 |
||
1130.3.12
by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/ |
35 |
namespace drizzled |
36 |
{
|
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
37 |
|
2096.1.3
by Brian Aker
Have table name added in as early as possible. |
38 |
namespace statement { |
39 |
||
40 |
CreateTable::CreateTable(Session *in_session, Table_ident *ident, bool is_temporary) : |
|
41 |
Statement(in_session), |
|
42 |
change(NULL), |
|
43 |
default_value(NULL), |
|
44 |
on_update_value(NULL), |
|
45 |
is_engine_set(false), |
|
46 |
is_create_table_like(false), |
|
47 |
lex_identified_temp_table(false), |
|
48 |
link_to_local(false), |
|
49 |
create_table_list(NULL) |
|
50 |
{
|
|
2224.2.6
by Olaf van der Spek
Statement::set_command |
51 |
set_command(SQLCOM_CREATE_TABLE); |
2096.1.3
by Brian Aker
Have table name added in as early as possible. |
52 |
createTableMessage().set_name(ident->table.str, ident->table.length); |
53 |
#if 0
|
|
54 |
createTableMessage().set_schema(ident->db.str, ident->db.length);
|
|
55 |
#endif
|
|
56 |
||
57 |
if (is_temporary) |
|
58 |
{
|
|
59 |
createTableMessage().set_type(message::Table::TEMPORARY); |
|
60 |
}
|
|
61 |
else
|
|
62 |
{
|
|
63 |
createTableMessage().set_type(message::Table::STANDARD); |
|
64 |
}
|
|
65 |
}
|
|
66 |
||
67 |
CreateTable::CreateTable(Session *in_session) : |
|
68 |
Statement(in_session), |
|
69 |
change(NULL), |
|
70 |
default_value(NULL), |
|
71 |
on_update_value(NULL), |
|
72 |
is_engine_set(false), |
|
73 |
is_create_table_like(false), |
|
74 |
lex_identified_temp_table(false), |
|
75 |
link_to_local(false), |
|
76 |
create_table_list(NULL) |
|
77 |
{
|
|
2224.2.6
by Olaf van der Spek
Statement::set_command |
78 |
set_command(SQLCOM_CREATE_TABLE); |
2096.1.3
by Brian Aker
Have table name added in as early as possible. |
79 |
}
|
80 |
||
81 |
} // namespace statement |
|
82 |
||
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
83 |
bool statement::CreateTable::execute() |
84 |
{
|
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
85 |
TableList *first_table= (TableList *) lex().select_lex.table_list.first; |
86 |
TableList *all_tables= lex().query_tables; |
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
87 |
assert(first_table == all_tables && first_table != 0); |
88 |
bool need_start_waiting= false; |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
89 |
lex_identified_temp_table= createTableMessage().type() == message::Table::TEMPORARY; |
90 |
||
91 |
is_engine_set= not createTableMessage().engine().name().empty(); |
|
1245.3.7
by Stewart Smith
error out on invalid table options |
92 |
|
1222.1.3
by Brian Aker
Remove used flag for engine. |
93 |
if (is_engine_set) |
1160.1.5
by Brian Aker
Final parser SE removal. |
94 |
{
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
95 |
create_info().db_type= |
2227.4.2
by Olaf van der Spek
Statement::session() |
96 |
plugin::StorageEngine::findByName(session(), createTableMessage().engine().name()); |
1160.1.5
by Brian Aker
Final parser SE removal. |
97 |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
98 |
if (create_info().db_type == NULL) |
1160.1.5
by Brian Aker
Final parser SE removal. |
99 |
{
|
100 |
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
101 |
createTableMessage().engine().name().c_str()); |
1160.1.5
by Brian Aker
Final parser SE removal. |
102 |
|
103 |
return true; |
|
104 |
}
|
|
105 |
}
|
|
106 |
else /* We now get the default, place it in create_info, and put the engine name in table proto */ |
|
107 |
{
|
|
2227.4.1
by Olaf van der Spek
Statement::session() |
108 |
create_info().db_type= session().getDefaultStorageEngine(); |
1160.1.5
by Brian Aker
Final parser SE removal. |
109 |
}
|
110 |
||
1502.1.30
by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a |
111 |
if (not validateCreateTableOption()) |
112 |
{
|
|
113 |
return true; |
|
114 |
}
|
|
1172.1.1
by Brian Aker
Add in support for ENGINE= in create table like. |
115 |
|
1320.1.8
by Brian Aker
Temporary fix for allowing engines to say "don't do this". |
116 |
if (not lex_identified_temp_table) |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
117 |
{
|
2227.4.1
by Olaf van der Spek
Statement::session() |
118 |
if (session().inTransaction()) |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
119 |
{
|
1890.2.1
by Stewart Smith
add error message for Transactional DDL not being supported. Throw it in CREATE TABLE instead of implicit commit. |
120 |
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0)); |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
121 |
return true; |
122 |
}
|
|
123 |
}
|
|
124 |
/* Skip first table, which is the table we are creating */
|
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
125 |
create_table_list= lex().unlink_first_table(&link_to_local); |
1128.2.3
by Brian Aker
Remove create_info from global |
126 |
|
2067.3.1
by Brian Aker
Merge with trunk. |
127 |
drizzled::message::table::init(createTableMessage(), createTableMessage().name(), create_table_list->getSchemaName(), create_info().db_type->getName()); |
1337.2.2
by Stewart Smith
Add Schema to table message. modify alter table to correctly set a schema when running ALTER TABLE. Also update show_table_message test results to reflect the new field. |
128 |
|
2087.4.2
by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers. |
129 |
identifier::Table new_table_identifier(create_table_list->getSchemaName(), |
2026.2.1
by Monty Taylor
Renamed things prefixed mysql_ or mysqld_ |
130 |
create_table_list->getTableName(), |
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
131 |
createTableMessage().type()); |
1223.4.1
by Brian Aker
Table Identifier patch. |
132 |
|
1992.4.1
by Brian Aker
Update code for testing identifiers/table/schema name correctness. |
133 |
if (not check(new_table_identifier)) |
1100.3.67
by Padraig O'Sullivan
Various small style cleanups. |
134 |
{
|
135 |
/* put tables back for PS rexecuting */
|
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
136 |
lex().link_first_table_back(create_table_list, link_to_local); |
1100.3.67
by Padraig O'Sullivan
Various small style cleanups. |
137 |
return true; |
138 |
}
|
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
139 |
|
140 |
/* Might have been updated in create_table_precheck */
|
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
141 |
create_info().alias= create_table_list->alias; |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
142 |
|
143 |
/*
|
|
144 |
The create-select command will open and read-lock the select table
|
|
145 |
and then create, open and write-lock the new table. If a global
|
|
146 |
read lock steps in, we get a deadlock. The write lock waits for
|
|
147 |
the global read lock, while the global read lock waits for the
|
|
148 |
select table to be closed. So we wait until the global readlock is
|
|
149 |
gone before starting both steps. Note that
|
|
150 |
wait_if_global_read_lock() sets a protection against a new global
|
|
151 |
read lock when it succeeds. This needs to be released by
|
|
152 |
start_waiting_global_read_lock(). We protect the normal CREATE
|
|
153 |
TABLE in the same way. That way we avoid that a new table is
|
|
154 |
created during a gobal read lock.
|
|
155 |
*/
|
|
2227.4.1
by Olaf van der Spek
Statement::session() |
156 |
if (! (need_start_waiting= not session().wait_if_global_read_lock(0, 1))) |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
157 |
{
|
1100.3.67
by Padraig O'Sullivan
Various small style cleanups. |
158 |
/* put tables back for PS rexecuting */
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
159 |
lex().link_first_table_back(create_table_list, link_to_local); |
1100.3.67
by Padraig O'Sullivan
Various small style cleanups. |
160 |
return true; |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
161 |
}
|
1172.1.1
by Brian Aker
Add in support for ENGINE= in create table like. |
162 |
|
2029.1.1
by Brian Aker
Merge in first pass. |
163 |
bool res= executeInner(new_table_identifier); |
164 |
||
165 |
/*
|
|
166 |
Release the protection against the global read lock and wake
|
|
167 |
everyone, who might want to set a global read lock.
|
|
168 |
*/
|
|
2227.4.1
by Olaf van der Spek
Statement::session() |
169 |
session().startWaitingGlobalReadLock(); |
2029.1.1
by Brian Aker
Merge in first pass. |
170 |
|
171 |
return res; |
|
172 |
}
|
|
173 |
||
2087.4.2
by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers. |
174 |
bool statement::CreateTable::executeInner(identifier::Table::const_reference new_table_identifier) |
2029.1.1
by Brian Aker
Merge in first pass. |
175 |
{
|
176 |
bool res= false; |
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
177 |
Select_Lex *select_lex= &lex().select_lex; |
178 |
TableList *select_tables= lex().query_tables; |
|
2029.1.1
by Brian Aker
Merge in first pass. |
179 |
|
2079.3.1
by Brian Aker
Rework the CREATE TABLE LIKE call. |
180 |
do
|
181 |
{
|
|
2183.2.20
by Olaf van der Spek
Use List::size() |
182 |
if (select_lex->item_list.size()) // With select |
2029.1.1
by Brian Aker
Merge in first pass. |
183 |
{
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
184 |
Select_Lex_Unit *unit= &lex().unit; |
2029.1.1
by Brian Aker
Merge in first pass. |
185 |
select_result *result; |
186 |
||
187 |
select_lex->options|= SELECT_NO_UNLOCK; |
|
188 |
unit->set_limit(select_lex); |
|
189 |
||
1340.1.1
by Brian Aker
Length usage of identifier down the tree. |
190 |
if (not lex_identified_temp_table) |
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
191 |
{
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
192 |
lex().link_first_table_back(create_table_list, link_to_local); |
2029.1.1
by Brian Aker
Merge in first pass. |
193 |
create_table_list->setCreate(true); |
194 |
}
|
|
195 |
||
2227.4.1
by Olaf van der Spek
Statement::session() |
196 |
if (not (res= session().openTablesLock(lex().query_tables))) |
2029.1.1
by Brian Aker
Merge in first pass. |
197 |
{
|
198 |
/*
|
|
199 |
Is table which we are changing used somewhere in other parts
|
|
200 |
of query
|
|
201 |
*/
|
|
202 |
if (not lex_identified_temp_table) |
|
203 |
{
|
|
204 |
TableList *duplicate= NULL; |
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
205 |
create_table_list= lex().unlink_first_table(&link_to_local); |
2029.1.1
by Brian Aker
Merge in first pass. |
206 |
|
207 |
if ((duplicate= unique_table(create_table_list, select_tables))) |
|
208 |
{
|
|
209 |
my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table_list->alias); |
|
210 |
/* put tables back for PS rexecuting */
|
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
211 |
lex().link_first_table_back(create_table_list, link_to_local); |
2029.1.1
by Brian Aker
Merge in first pass. |
212 |
|
213 |
res= true; |
|
214 |
break; |
|
215 |
}
|
|
216 |
}
|
|
217 |
||
218 |
/*
|
|
219 |
select_create is currently not re-execution friendly and
|
|
220 |
needs to be created for every execution of a PS/SP.
|
|
221 |
*/
|
|
222 |
if ((result= new select_create(create_table_list, |
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
223 |
lex().exists(), |
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
224 |
&create_info(), |
225 |
createTableMessage(), |
|
2029.1.1
by Brian Aker
Merge in first pass. |
226 |
&alter_info, |
227 |
select_lex->item_list, |
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
228 |
lex().duplicates, |
229 |
lex().ignore, |
|
2029.1.1
by Brian Aker
Merge in first pass. |
230 |
select_tables, |
231 |
new_table_identifier))) |
|
232 |
{
|
|
233 |
/*
|
|
234 |
CREATE from SELECT give its Select_Lex for SELECT,
|
|
235 |
and item_list belong to SELECT
|
|
236 |
*/
|
|
2227.4.2
by Olaf van der Spek
Statement::session() |
237 |
res= handle_select(&session(), &lex(), result, 0); |
2029.1.1
by Brian Aker
Merge in first pass. |
238 |
delete result; |
239 |
}
|
|
240 |
}
|
|
241 |
else if (not lex_identified_temp_table) |
|
242 |
{
|
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
243 |
create_table_list= lex().unlink_first_table(&link_to_local); |
2029.1.1
by Brian Aker
Merge in first pass. |
244 |
}
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
245 |
}
|
246 |
else
|
|
247 |
{
|
|
2029.1.1
by Brian Aker
Merge in first pass. |
248 |
/* regular create */
|
249 |
if (is_create_table_like) |
|
250 |
{
|
|
2227.4.2
by Olaf van der Spek
Statement::session() |
251 |
res= create_like_table(&session(), |
2029.1.1
by Brian Aker
Merge in first pass. |
252 |
new_table_identifier, |
2093
by Brian Aker
Merge in update so that test-run.pl runs all of test/suite and fix for |
253 |
identifier::Table(select_tables->getSchemaName(), |
254 |
select_tables->getTableName()), |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
255 |
createTableMessage(), |
2224.2.8
by Olaf van der Spek
Statement::lex() |
256 |
lex().exists(), |
2029.1.1
by Brian Aker
Merge in first pass. |
257 |
is_engine_set); |
258 |
}
|
|
259 |
else
|
|
260 |
{
|
|
261 |
||
262 |
for (int32_t x= 0; x < alter_info.alter_proto.added_field_size(); x++) |
|
263 |
{
|
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
264 |
message::Table::Field *field= createTableMessage().add_field(); |
2029.1.1
by Brian Aker
Merge in first pass. |
265 |
|
266 |
*field= alter_info.alter_proto.added_field(x); |
|
267 |
}
|
|
268 |
||
2227.4.2
by Olaf van der Spek
Statement::session() |
269 |
res= create_table(&session(), |
2029.1.1
by Brian Aker
Merge in first pass. |
270 |
new_table_identifier, |
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
271 |
&create_info(), |
272 |
createTableMessage(), |
|
2029.1.1
by Brian Aker
Merge in first pass. |
273 |
&alter_info, |
274 |
false, |
|
275 |
0, |
|
2224.2.8
by Olaf van der Spek
Statement::lex() |
276 |
lex().exists()); |
2029.1.1
by Brian Aker
Merge in first pass. |
277 |
}
|
278 |
||
279 |
if (not res) |
|
280 |
{
|
|
2227.4.1
by Olaf van der Spek
Statement::session() |
281 |
session().my_ok(); |
2029.1.1
by Brian Aker
Merge in first pass. |
282 |
}
|
283 |
}
|
|
284 |
} while (0); |
|
1100.3.67
by Padraig O'Sullivan
Various small style cleanups. |
285 |
|
1100.3.65
by Padraig O'Sullivan
Extracted the CREATE TABLE command into its own class and implementation |
286 |
return res; |
287 |
}
|
|
1130.3.12
by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/ |
288 |
|
2087.4.2
by Brian Aker
Modify TableIdentifier to fit with the rest of the identifiers. |
289 |
bool statement::CreateTable::check(const identifier::Table &identifier) |
1992.4.1
by Brian Aker
Update code for testing identifiers/table/schema name correctness. |
290 |
{
|
291 |
// Check table name for validity
|
|
292 |
if (not identifier.isValid()) |
|
293 |
return false; |
|
294 |
||
295 |
// See if any storage engine objects to the name of the file
|
|
296 |
if (not plugin::StorageEngine::canCreateTable(identifier)) |
|
297 |
{
|
|
2159.2.8
by Brian Aker
Merge in fixes for error messages with privs. |
298 |
identifier::Schema schema_identifier= identifier; |
2227.4.1
by Olaf van der Spek
Statement::session() |
299 |
error::access(*session().user(), schema_identifier); |
1992.4.1
by Brian Aker
Update code for testing identifiers/table/schema name correctness. |
300 |
|
301 |
return false; |
|
302 |
}
|
|
303 |
||
304 |
// Make sure the schema exists, we will do this again during the actual
|
|
305 |
// create for the table.
|
|
306 |
if (not plugin::StorageEngine::doesSchemaExist(identifier)) |
|
307 |
{
|
|
2159.2.8
by Brian Aker
Merge in fixes for error messages with privs. |
308 |
identifier::Schema schema_identifier= identifier; |
309 |
my_error(ER_BAD_DB_ERROR, schema_identifier); |
|
1992.4.1
by Brian Aker
Update code for testing identifiers/table/schema name correctness. |
310 |
|
311 |
return false; |
|
312 |
}
|
|
313 |
||
314 |
return true; |
|
315 |
}
|
|
316 |
||
1502.1.30
by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a |
317 |
bool statement::CreateTable::validateCreateTableOption() |
318 |
{
|
|
319 |
bool rc= true; |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
320 |
size_t num_engine_options= createTableMessage().engine().options_size(); |
1502.1.30
by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a |
321 |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
322 |
assert(create_info().db_type); |
1502.1.30
by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a |
323 |
|
324 |
for (size_t y= 0; y < num_engine_options; ++y) |
|
325 |
{
|
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
326 |
bool valid= create_info().db_type->validateCreateTableOption(createTableMessage().engine().options(y).name(), |
327 |
createTableMessage().engine().options(y).state()); |
|
1502.1.30
by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a |
328 |
|
329 |
if (not valid) |
|
330 |
{
|
|
331 |
my_error(ER_UNKNOWN_ENGINE_OPTION, MYF(0), |
|
2029.1.2
by Brian Aker
Merge in refactor of LIKE up to its own calling pointer in the parser. |
332 |
createTableMessage().engine().options(y).name().c_str(), |
333 |
createTableMessage().engine().options(y).state().c_str()); |
|
1502.1.30
by Brian Aker
First pass on cleanup of Stewart's patch, plus re-engineer to make it work a |
334 |
|
335 |
rc= false; |
|
336 |
}
|
|
337 |
}
|
|
338 |
||
339 |
return rc; |
|
340 |
}
|
|
341 |
||
1130.3.12
by Monty Taylor
using namespace drizzled; to namespace drizzled { in statement/ |
342 |
} /* namespace drizzled */ |
343 |