Merge lp:~posulliv/drizzle/simple-tc-engine into lp:~drizzle-trunk/drizzle/development

Proposed by Padraig O'Sullivan
Status: Rejected
Rejected by: Padraig O'Sullivan
Proposed branch: lp:~posulliv/drizzle/simple-tc-engine
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: 1515 lines
14 files modified
plugin/tokyo_cabinet_engine/open_tables.cc (+76/-0)
plugin/tokyo_cabinet_engine/open_tables.h (+92/-0)
plugin/tokyo_cabinet_engine/plugin.ac (+8/-0)
plugin/tokyo_cabinet_engine/plugin.ini (+12/-0)
plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.cc (+71/-0)
plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.h (+73/-0)
plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.cc (+221/-0)
plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.h (+140/-0)
plugin/tokyo_cabinet_engine/tokyo_cabinet_share.cc (+240/-0)
plugin/tokyo_cabinet_engine/tokyo_cabinet_share.h (+219/-0)
tests/suite/tc_engine/r/auto_increment.result (+32/-0)
tests/suite/tc_engine/r/basic.result (+138/-0)
tests/suite/tc_engine/t/auto_increment.test (+13/-0)
tests/suite/tc_engine/t/basic.test (+107/-0)
To merge this branch: bzr merge lp:~posulliv/drizzle/simple-tc-engine
Reviewer Review Type Date Requested Status
Stewart Smith (community) Needs Information
Review via email: mp+12323@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Padraig O'Sullivan (posulliv) wrote :

This merge proposal consists of a simple in-memory storage engine that uses the Tokyo Cabinet in-memory hash API. It also includes a very lacking test suite with 2 small test files for the storage engine. Since this proposal is a little bit out of nowhere and you are probably wondering why the heck I did this, let me explain why I did it...

I'm taking a distributed systems class this semester for fun which will involve a project. I've managed to get a project involving Drizzle approved. What I plan on doing is investigating how to use cloud storage services (such as S3) as the storage backend for a SQL engine (which will be drizzle) and how to implement various consistency protocols over an eventually consistent data store such as S3. Since S3 is basically a key/value store (as described in the Dynamo paper), I wanted to get some practice creating a storage engine using a key/value store interface. Thus, I found Brian's posting on a Tokyo Cabinet based storage engine from a while back and went with that. I ported it to Drizzle and modified it to use the in-memory API calls from Tokyo Cabinet for the heck of it. This will help me in getting my basic S3 storage engine working in the next few weeks as I now have a good idea of how to create a storage engine using a key/value store interface.

I wasn't sure what to do with this engine, so I figured I'd propose it for merging. I also remember Brian's post about a new memory engine so I thought this might make a good start. I'm open to giving this over to someone. I was also under the impression this doesn't really conflict with BlitzDB. From what I understand about BlitzDB, its aimed at being a more general purpose storage engine but then again, maybe I should give this to Toru and he can do what he likes with it.

Anyway, any comments are more than welcome. If no-one is interested in this, or it doesn't prove very useful, well then this proposal can be ignored :) It was good practice for working with a key/value store for me! Alternatively, if there is interest, I can work on it more in my spare time to make it a better in-memory engine if that is desirable.

-Padraig

Revision history for this message
Brian Aker (brianaker) wrote :

Hi!

Yep, we need a new in-memory engine. I can't really judge whether TC would work well for in-memory or not (we need to study up the analytics around this... aka benchmark).

My personal thought? No harm in doing it, and I suspect it will be no worse then the current engine (might even be an improvement...). Is it the final engine? I have my doubts mainly because of concurrency issues. You can certainly learn the interface this way, and... most likely this would be useful for others.

Cheers,
   -Brian

Revision history for this message
Stewart Smith (stewart) wrote :

On Fri, Sep 25, 2009 at 04:45:48AM -0000, Brian Aker wrote:
> Hi!
>
> Yep, we need a new in-memory engine. I can't really judge whether TC
> would work well for in-memory or not (we need to study up the analytics
> around this... aka benchmark).
>
> My personal thought? No harm in doing it, and I suspect it will be no
> worse then the current engine (might even be an improvement...). Is it
> the final engine? I have my doubts mainly because of concurrency issues.
> You can certainly learn the interface this way, and... most likely this
> would be useful for others.

I also really like the idea of maintaining an engine with a clear
boundary between engine API and storage engine code as all of our
existing engines are a bit muddy there and/or rather complex.

--
Stewart Smith

Revision history for this message
Stewart Smith (stewart) wrote :

the delete table paths seem to be a bit strange. it looks like you're deleting it on the close of the last tableshare, although the proper way would be to do it when explicitly called to remove the table (and check exists/not exists).

If you wanted to be fancy and demo the data dictionary APIs, you could have a (on disk) tc db of table names with the data being the table proto.

review: Needs Information

Unmerged revisions

1155. By Padraig O'Sullivan

Merge from trunk.

1154. By Padraig O'Sullivan

Added some more doxygen comments.

1153. By Padraig O'Sullivan

Updated plugin main file to have the authors reflected accurately. Included
Brian and Stewart since I based this engine off the tokyo cabinet engine
they did.

1152. By Padraig O'Sullivan

Converted the engine to an in-memory engine. It would be quite trivial to
create an option which lets the engine operate in memory or on disk. We
could even support having tables of both types at the same time. However, I
don't see why you would need a disk-based storage engine when you have
InnoDB?

1151. By Padraig O'Sullivan

Added some doxygen comments and updated the plugin.ini file to indicate that
a test suite is available for this plugin. Thus, the test suite will get run
when 'make test' issued.

1150. By Padraig O'Sullivan

Tiny modification based on valgrind output.

1149. By Padraig O'Sullivan

Updating the flags based to the tokyo cabinet based storage engine so that
altering of tables is supported.

1148. By Padraig O'Sullivan

Corrected the way tables are updated. Update statements now work correctly.

1147. By Padraig O'Sullivan

Added support for deleting a row in the storage engine.

1146. By Padraig O'Sullivan

Added support for storing rows of non-fixed length to the storage engine.
Updates to rows which store blobs still don't work correctly but we are
making some progress.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'plugin/tokyo_cabinet_engine'
=== added file 'plugin/tokyo_cabinet_engine/open_tables.cc'
--- plugin/tokyo_cabinet_engine/open_tables.cc 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/open_tables.cc 2009-09-24 03:50:23 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <drizzled/server_includes.h>
20#include "tokyo_cabinet_handler.h"
21#include "open_tables.h"
22
23#include <string>
24#include <map>
25
26using namespace std;
27using namespace drizzled;
28
29TokyoCabinetShare *OpenTables::getShare(const string &name)
30{
31 map<const string, TokyoCabinetShare *>::iterator it;
32 pthread_mutex_lock(&mutex);
33
34 it= open_tables.find(name);
35 if (it != open_tables.end())
36 {
37 share= (*it).second;
38 }
39 else
40 {
41 share= NULL;
42 }
43
44 if (! share)
45 {
46 share= new(std::nothrow) TokyoCabinetShare(name);
47 if (! share)
48 {
49 pthread_mutex_unlock(&mutex);
50 return NULL;
51 }
52 if (! share->openTable())
53 {
54 delete share;
55 return NULL;
56 }
57 open_tables[name]= share;
58 share->initThreadLock();
59 }
60 share->incUseCount();
61 pthread_mutex_unlock(&mutex);
62
63 return share;
64}
65
66void OpenTables::freeShare()
67{
68 pthread_mutex_lock(&mutex);
69 share->decUseCount();
70 if (share->getUseCount() == 0)
71 {
72 share->freeDatabaseHandler();
73 open_tables.erase(share->getName());
74 }
75 pthread_mutex_unlock(&mutex);
76}
077
=== added file 'plugin/tokyo_cabinet_engine/open_tables.h'
--- plugin/tokyo_cabinet_engine/open_tables.h 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/open_tables.h 2009-09-24 03:50:23 +0000
@@ -0,0 +1,92 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18/**
19 * @file
20 *
21 * Defines a class for how open tables will be tracked for this storage
22 * engine.
23 */
24
25#ifndef DRIZZLE_PLUGIN_TOKYO_ENGINE_OPEN_TABLES_H
26#define DRIZZLE_PLUGIN_TOKYO_ENGINE_OPEN_TABLES_H
27
28#include "tokyo_cabinet_handler.h"
29
30#include <string>
31#include <vector>
32#include <map>
33
34/**
35 * @class OpenTables
36 *
37 * Class which tracks all the open tables for the storage engine.
38 * Encapsulating this functionality in a class will make it easier for us to
39 * change things such as whether a std::map or HASH is used to lookup the
40 * open tables.
41 */
42class OpenTables
43{
44public:
45
46 static OpenTables &singleton()
47 {
48 static OpenTables open_tabs;
49 return open_tabs;
50 }
51
52 /**
53 * Retrieve a share from the structure used to main the list of open
54 * shares. We do a lookup by name.
55 *
56 * @param[in] name name to lookup
57 * @return pointer to the appropriate table share
58 */
59 TokyoCabinetShare *getShare(const std::string &name);
60
61 /**
62 * Erase a share from the structure used to maintain the list of shares.
63 */
64 void freeShare();
65
66private:
67
68 pthread_mutex_t mutex;
69
70 std::map<const std::string, TokyoCabinetShare *>
71 open_tables;
72
73 TokyoCabinetShare *share;
74
75 OpenTables()
76 :
77 mutex(),
78 open_tables(),
79 share(NULL)
80 {
81 pthread_mutex_init(&mutex, MY_MUTEX_INIT_FAST);
82 }
83
84 ~OpenTables()
85 {
86 pthread_mutex_destroy(&mutex);
87 }
88
89 OpenTables(const OpenTables&);
90};
91
92#endif /* DRIZZLE_PLUGIN_TOKYO_ENGINE_OPEN_TABLES_H */
093
=== added file 'plugin/tokyo_cabinet_engine/plugin.ac'
--- plugin/tokyo_cabinet_engine/plugin.ac 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/plugin.ac 2009-09-24 03:50:23 +0000
@@ -0,0 +1,8 @@
1AC_LIB_HAVE_LINKFLAGS(tokyocabinet,,
2 [#include <tchdb.h>],
3 [
4 TCHDB hdb;
5 ])
6 AS_IF([test "x$ac_cv_libtokyocabinet" = "xno"],
7 AC_MSG_WARN([tokyocabinet not found: not building TokyoCabinet engine.]))
8DRIZZLED_PLUGIN_DEP_LIBS="${DRIZZLED_PLUGIN_DEP_LIBS} ${LTLIBTOKYOCABINET}"
09
=== added file 'plugin/tokyo_cabinet_engine/plugin.ini'
--- plugin/tokyo_cabinet_engine/plugin.ini 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/plugin.ini 2009-09-24 03:50:23 +0000
@@ -0,0 +1,12 @@
1[plugin]
2name=tokyo_cabinet_engine
3title=Tokyo Cabinet Storage Engine
4description=A Tokyo Cabinet Based Storage Engine
5load_by_default= yes
6sources=tokyo_cabinet_engine.cc tokyo_cabinet_handler.cc open_tables.cc
7 tokyo_cabinet_share.cc
8headers=tokyo_cabinet_engine.h tokyo_cabinet_handler.h open_tables.h
9 tokyo_cabinet_share.h
10build_conditional="${ac_cv_libtokyocabinet}" = "yes"
11ldflags=${LTLIBTOKYOCABINET}
12testsuite=tc_engine
013
=== added file 'plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.cc'
--- plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.cc 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.cc 2009-09-24 03:50:23 +0000
@@ -0,0 +1,71 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <drizzled/server_includes.h>
20#include <drizzled/show.h>
21#include "tokyo_cabinet_engine.h"
22#include "tokyo_cabinet_handler.h"
23#include "open_tables.h"
24
25#include <string>
26#include <map>
27
28using namespace std;
29using namespace drizzled;
30
31static const string engine_name("Tokyo");
32static StorageEngine *tokyo_cabinet_engine= NULL;
33
34static int init(plugin::Registry &registry)
35{
36 tokyo_cabinet_engine= new(std::nothrow) TokyoCabinetEngine(engine_name);
37 if (! tokyo_cabinet_engine)
38 {
39 return true;
40 }
41
42 /* we are good to go */
43 registry.add(tokyo_cabinet_engine);
44
45 return false;
46}
47
48static int deinit(plugin::Registry &registry)
49{
50 if (tokyo_cabinet_engine)
51 {
52 registry.remove(tokyo_cabinet_engine);
53 delete tokyo_cabinet_engine;
54 }
55 return false;
56}
57
58drizzle_declare_plugin(tokyo_cabinet_engine)
59{
60 "tokyo_cabinet_engine",
61 "0.1",
62 "Padraig O'Sullivan, Brian Aker, Stewart Smith",
63 "Simple In-Memory Tokyo Cabinet Storage Engine",
64 PLUGIN_LICENSE_GPL,
65 init, /* Plugin Init */
66 deinit, /* Plugin Deinit */
67 NULL, /* status variables */
68 NULL, /* system variables */
69 NULL /* config options */
70}
71drizzle_declare_plugin_end;
072
=== added file 'plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.h'
--- plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.h 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/tokyo_cabinet_engine.h 2009-09-24 03:50:23 +0000
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file
21 *
22 * Declares the class that will represent this storage engine.
23 */
24
25#ifndef DRIZZLE_PLUGIN_TOKYO_CABINET_ENGINE_H
26#define DRIZZLE_PLUGIN_TOKYO_CABINET_ENGINE_H
27
28#include <drizzled/error.h>
29#include "tokyo_cabinet_handler.h"
30
31#include <string>
32
33class TokyoCabinetEngine : public StorageEngine
34{
35public:
36
37 TokyoCabinetEngine(const std::string &in_name)
38 :
39 StorageEngine(in_name,
40 HTON_CAN_RECREATE)
41 {}
42
43 ~TokyoCabinetEngine() {}
44
45 virtual handler *create(TableShare *table,
46 MEM_ROOT *mem_root)
47 {
48 return new(mem_root) TokyoCabinetHandler(this, table);
49 }
50
51 const char **bas_ext() const
52 {
53 return NULL;
54 }
55
56 int createTableImplementation(Session *,
57 const char *,
58 Table *,
59 HA_CREATE_INFO *,
60 drizzled::message::Table *)
61 {
62 return 0;
63 }
64
65 int deleteTableImplementation(Session *,
66 const string)
67 {
68 return 0;
69 }
70
71};
72
73#endif /* DRIZZLE_PLUGIN_TOKYO_CABINET_ENGINE_H */
074
=== added file 'plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.cc'
--- plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.cc 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.cc 2009-09-24 03:50:23 +0000
@@ -0,0 +1,221 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "drizzled/server_includes.h"
20#include "drizzled/join_table.h"
21#include "drizzled/handler.h"
22#include "drizzled/field/blob.h"
23#include "drizzled/field/timestamp.h"
24#include "drizzled/session.h"
25
26#include "tokyo_cabinet_handler.h"
27#include "tokyo_cabinet_share.h"
28#include "open_tables.h"
29
30#include <string>
31#include <map>
32
33using namespace std;
34using namespace drizzled;
35
36int TokyoCabinetHandler::open(const char *name, int, uint32_t)
37{
38 OpenTables &open_tables= OpenTables::singleton();
39 if (! (share= open_tables.getShare(name)))
40 {
41 return HA_ERR_OUT_OF_MEM;
42 }
43
44 assert(share);
45
46 thr_lock_data_init(share->getThreadLock(), &data_lock, NULL);
47
48 bool pack_table= ! (table->s->db_create_options &
49 HA_OPTION_PACK_RECORD);
50 share->setFixedLengthTable(pack_table);
51 share->setRowLength(getMaxRowLength());
52 share->setTableFields(table->field);
53 share->setNullBytes(table->s->null_bytes);
54 share->setTableRecord(table->record[0]);
55
56 return 0;
57}
58
59int TokyoCabinetHandler::close()
60{
61 OpenTables &open_tables= OpenTables::singleton();
62 open_tables.freeShare();
63 return 0;
64}
65
66int TokyoCabinetHandler::info(uint32_t flags)
67{
68 /*
69 * If this flag is set, then we know that the time of the last
70 * modification needs to be modified.
71 */
72 if (flags & HA_STATUS_TIME)
73 {
74 }
75
76 if (flags & HA_STATUS_VARIABLE)
77 {
78 stats.records= share->getNumOfRecords();
79 }
80
81 /*
82 * If this flag is set, then we know that the auto_increment value needs
83 * to be updated.
84 */
85 if (flags & HA_STATUS_AUTO)
86 {
87 stats.auto_increment_value= 1;
88 }
89
90 return 0;
91}
92
93int TokyoCabinetHandler::rnd_init(bool)
94{
95 share->initIterators();
96 return 0;
97}
98
99int TokyoCabinetHandler::rnd_next(unsigned char *buf)
100{
101 return (share->retrieveRow(buf));
102}
103
104int TokyoCabinetHandler::rnd_pos(unsigned char *buf, unsigned char *pos)
105{
106 Field *field_key= table->key_info[table->s->primary_key].key_part->field;
107 uint16_t len;
108 memcpy(&len, pos, sizeof(uint16_t));
109 int ret= share->findRow(field_key, buf, pos + 2, len);
110
111 return ret;
112}
113
114void TokyoCabinetHandler::position(const unsigned char *)
115{
116 return;
117}
118
119THR_LOCK_DATA **TokyoCabinetHandler::store_lock(Session *session,
120 THR_LOCK_DATA **to,
121 enum thr_lock_type lock_type)
122{
123 /* borrowed from archive and BDB engines. TODO: understand this! */
124 if (lock_type != TL_IGNORE && data_lock.type == TL_UNLOCK)
125 {
126 if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) &&
127 ! session_tablespace_op(session))
128 {
129 lock_type= TL_WRITE_ALLOW_WRITE;
130 }
131 if (lock_type == TL_READ_NO_INSERT)
132 {
133 lock_type= TL_READ;
134 }
135 data_lock.type= lock_type;
136 }
137 *to++= &data_lock;
138 return to;
139}
140
141uint32_t TokyoCabinetHandler::index_flags(uint32_t,
142 uint32_t,
143 bool) const
144{
145 return 0;
146}
147
148int TokyoCabinetHandler::index_read(unsigned char *buf,
149 const unsigned char *key,
150 uint32_t key_len,
151 enum ha_rkey_function)
152{
153 Field *key_field= table->key_info[active_index].key_part->field;
154 ha_statistic_increment(&SSV::ha_read_key_count);
155 int ret= share->findRow(key_field, buf, key, key_len);
156 return ret;
157}
158
159int TokyoCabinetHandler::index_next(unsigned char *)
160{
161 return HA_ERR_END_OF_FILE;
162}
163
164int TokyoCabinetHandler::write_row(unsigned char *buf)
165{
166 Field *key_field= table->key_info[table->s->primary_key].key_part->field;
167
168 ha_statistic_increment(&SSV::ha_write_count);
169
170 if (table->next_number_field && buf == table->record[0])
171 {
172 update_auto_increment();
173 }
174
175 /* push the data to the key/value store */
176 return (share->storeRow(key_field, buf));
177}
178
179int TokyoCabinetHandler::update_row(const unsigned char *,
180 unsigned char *new_data)
181{
182 Field *key_field= table->key_info[table->s->primary_key].key_part->field;
183
184 ha_statistic_increment(&SSV::ha_update_count);
185
186 if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
187 {
188 table->timestamp_field->set_time();
189 }
190
191 return (share->updateRow(key_field, new_data));
192}
193
194int TokyoCabinetHandler::delete_row(const unsigned char *)
195{
196 Field *key_field= table->key_info[table->s->primary_key].key_part->field;
197 ha_statistic_increment(&SSV::ha_delete_count);
198 return (share->deleteRow(key_field));
199}
200
201int TokyoCabinetHandler::delete_all_rows()
202{
203 share->deleteAllRows();
204 return 0;
205}
206
207uint32_t TokyoCabinetHandler::getMaxRowLength()
208{
209 uint32_t len= table->s->reclength + table->s->fields * 2;
210 uint32_t *pos= table->getBlobField();
211 uint32_t *end= pos + table->sizeBlobFields();
212
213 while (pos != end)
214 {
215 Field_blob *blob_field= static_cast<Field_blob *>(table->field[*pos]);
216 len+= 2 + blob_field->get_length();
217 pos++;
218 }
219
220 return len;
221}
0222
=== added file 'plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.h'
--- plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.h 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/tokyo_cabinet_handler.h 2009-09-24 03:50:23 +0000
@@ -0,0 +1,140 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file
21 *
22 * Declares the handler for the Tokyo Cabinet storage engine.
23 */
24
25#ifndef DRIZZLE_PLUGIN_TOKYO_CABINET_HANDLER_H
26#define DRIZZLE_PLUGIN_TOKYO_CABINET_HANDLER_H
27
28#include <drizzled/handler.h>
29#include <drizzled/show.h>
30#include <mysys/thr_lock.h>
31
32#include "tokyo_cabinet_share.h"
33
34class TokyoCabinetHandler : public handler
35{
36public:
37
38 /* determines how many indexes are allowed per table */
39 static const uint32_t MAX_KEYS= 1;
40 static const uint32_t MAX_KEY_PARTS= 1;
41 static const uint32_t MAX_KEY_LEN= 1024;
42
43 TokyoCabinetHandler(StorageEngine *engine_arg, TableShare *table_arg)
44 :
45 handler(engine_arg, table_arg)
46 {}
47
48 ~TokyoCabinetHandler() {}
49
50 const char *table_type() const
51 {
52 return "TOKYO";
53 }
54
55 /*
56 The name of the index type that will be used for display
57 don't implement this method unless you really have indexes
58 */
59 const char *index_type(uint32_t)
60 {
61 return "HASH";
62 }
63
64 uint64_t table_flags() const
65 {
66 return (HA_NO_TRANSACTIONS |
67 HA_REQUIRE_PRIMARY_KEY |
68 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
69 HA_PRIMARY_KEY_REQUIRED_FOR_DELETE);
70 }
71
72 /* open a table */
73 int open(const char *name, int mode, uint32_t test_if_locked);
74
75 /* close a table */
76 int close(void);
77
78 /* provide info to the optimizer */
79 int info(uint32_t flag);
80
81 /* preparation for table scan (is this true?) */
82 int rnd_init(bool scan);
83
84 /* get the next row and copy it into buf */
85 int rnd_next(unsigned char *buf);
86
87 /* locate row pointed to by pos, copy it into buf */
88 int rnd_pos(unsigned char *buf, unsigned char *pos);
89
90 /* record position of a record for reordering */
91 void position(const unsigned char *record);
92
93 THR_LOCK_DATA **store_lock(Session *session,
94 THR_LOCK_DATA **to,
95 enum thr_lock_type lock_type);
96
97 uint32_t index_flags(uint32_t idx, uint32_t part, bool all_parts) const;
98 int index_read(unsigned char *buf,
99 const unsigned char *key,
100 uint32_t key_len,
101 enum ha_rkey_function find_flag);
102 int index_next(unsigned char *buf);
103
104 int write_row(unsigned char *buf);
105 int update_row(const unsigned char *,
106 unsigned char *);
107 int delete_row(const unsigned char *);
108 int delete_all_rows();
109
110 uint32_t max_supported_keys() const
111 {
112 return MAX_KEYS;
113 }
114
115 uint32_t max_supported_key_parts() const
116 {
117 return MAX_KEY_PARTS;
118 }
119
120 uint32_t max_supported_key_length() const
121 {
122 return MAX_KEY_LEN;
123 }
124
125private:
126
127 /**
128 * Determine the maximum length of a row in the table we are working with.
129 * This function is "borrowed" from the archive storage engine.
130 *
131 * @return the max row length for a table
132 */
133 uint32_t getMaxRowLength();
134
135 THR_LOCK_DATA data_lock;
136 TokyoCabinetShare *share;
137
138};
139
140#endif /* DRIZZLE_PLUGIN_TOKYO_CABINET_HANDLER_H */
0141
=== added file 'plugin/tokyo_cabinet_engine/tokyo_cabinet_share.cc'
--- plugin/tokyo_cabinet_engine/tokyo_cabinet_share.cc 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/tokyo_cabinet_share.cc 2009-09-24 03:50:23 +0000
@@ -0,0 +1,240 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "drizzled/server_includes.h"
20#include "drizzled/handler.h"
21#include "drizzled/show.h"
22#include "mysys/thr_lock.h"
23
24#include <tcutil.h>
25#include <tchdb.h>
26#include <stdlib.h>
27#include <stdbool.h>
28#include <stdint.h>
29
30#include "tokyo_cabinet_share.h"
31
32using namespace std;
33
34bool TokyoCabinetShare::createDatabaseHandler()
35{
36 data_handler= tcmdbnew();
37 if (! data_handler)
38 {
39 return false;
40 }
41 return true;
42}
43
44bool TokyoCabinetShare::openTable()
45{
46 return true;
47}
48
49void TokyoCabinetShare::freeDatabaseHandler()
50{
51 tcmdbdel(data_handler);
52}
53
54int TokyoCabinetShare::storeRow(Field *key_field,
55 unsigned char *row)
56{
57 createKey(key_field);
58
59 unsigned char *buf= new(std::nothrow) unsigned char[row_len];
60 if (! buf)
61 {
62 return HA_ERR_OUT_OF_MEM;
63 }
64
65 size_t len= packRow(buf, row);
66
67 bool ret= tcmdbputkeep(data_handler,
68 primary_key,
69 primary_key_len,
70 buf,
71 len);
72 if (! ret)
73 {
74 delete buf;
75 return HA_ERR_GENERIC;
76 }
77
78 delete buf;
79 return 0;
80}
81
82int TokyoCabinetShare::updateRow(Field *key_field,
83 unsigned char *row)
84{
85 createKey(key_field);
86
87 unsigned char *buf= new(std::nothrow) unsigned char[row_len];
88 if (! buf)
89 {
90 return HA_ERR_OUT_OF_MEM;
91 }
92
93 size_t len= packRow(buf, row);
94
95 /* TODO: somehow, check if this operation succeeded */
96 tcmdbput(data_handler,
97 primary_key,
98 primary_key_len,
99 buf,
100 len);
101
102 delete buf;
103 return 0;
104}
105
106size_t TokyoCabinetShare::packRow(unsigned char *buf,
107 unsigned char *row)
108{
109 size_t len= 0;
110
111 if (fixed_length_table)
112 {
113 memcpy(buf, row, row_len);
114 len= row_len;
115 }
116 else
117 {
118 /* copy NULL bits */
119 memcpy(buf, row, null_bytes);
120 unsigned char *pos= buf + null_bytes;
121
122 for (Field **field= fields; *field; field++)
123 {
124 if (! ((*field)->is_null()))
125 {
126 pos= (*field)->pack(pos, row + (*field)->offset(row));
127 }
128 }
129 len= (size_t) (pos - buf);
130 }
131 return len;
132}
133
134void TokyoCabinetShare::unpackRow(unsigned char *buf,
135 const char *row)
136{
137 if (fixed_length_table)
138 {
139 memcpy(buf, row, row_len);
140 }
141 else
142 {
143 const unsigned char *pos= (const unsigned char *) row;
144 memcpy(buf, pos, null_bytes);
145 pos+= null_bytes;
146
147 for (Field **field= fields; *field; field++)
148 {
149 if (! (*field)->is_null())
150 {
151 pos= (*field)->unpack(buf + (*field)->offset(table_record), pos);
152 }
153 }
154 }
155}
156
157void TokyoCabinetShare::createKey(Field *key)
158{
159 char *pos= primary_key_buff;
160 char attr_buff[1024];
161
162 String attribute(attr_buff,
163 sizeof(attr_buff),
164 &my_charset_bin);
165
166 key->setReadSet();
167 key->val_str(&attribute, &attribute);
168
169 size_t len= strlen(key->field_name);
170 memcpy(pos, key->field_name, len);
171 pos+= len;
172
173 memcpy(pos, attribute.ptr(), attribute.length());
174 pos+= attribute.length();
175
176 primary_key_len= (size_t) (pos - primary_key_buff);
177 primary_key= primary_key_buff;
178}
179
180void TokyoCabinetShare::initIterators()
181{
182 tcmdbiterinit(data_handler);
183}
184
185int TokyoCabinetShare::retrieveRow(unsigned char *buf)
186{
187 char *key= NULL;
188
189 while ((key= tcmdbiternext2(data_handler)) != NULL)
190 {
191 char *value= tcmdbget2(data_handler, key);
192 free(key);
193 if (value)
194 {
195 unpackRow(buf, value);
196 free(value);
197 return 0;
198 }
199 }
200
201 return HA_ERR_END_OF_FILE;
202}
203
204int TokyoCabinetShare::deleteRow(Field *key_field)
205{
206 createKey(key_field);
207
208 bool ret= tcmdbout(data_handler,
209 primary_key,
210 primary_key_len);
211 if (! ret)
212 {
213 return -1;
214 }
215 return 0;
216}
217
218int TokyoCabinetShare::findRow(Field *key_field,
219 unsigned char *buf,
220 const unsigned char *key,
221 size_t key_len)
222{
223 key_field->set_key_image(key, key_len);
224 key_field->set_notnull();
225 createKey(key_field);
226
227 int size;
228 char *tc_row= (char *) tcmdbget(data_handler,
229 primary_key,
230 primary_key_len,
231 &size);
232 if (tc_row == NULL)
233 {
234 return HA_ERR_KEY_NOT_FOUND;
235 }
236
237 unpackRow(buf, tc_row);
238 free(tc_row);
239 return 0;
240}
0241
=== added file 'plugin/tokyo_cabinet_engine/tokyo_cabinet_share.h'
--- plugin/tokyo_cabinet_engine/tokyo_cabinet_share.h 1970-01-01 00:00:00 +0000
+++ plugin/tokyo_cabinet_engine/tokyo_cabinet_share.h 2009-09-24 03:50:23 +0000
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) 2009 Sun Microsystems
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file
21 *
22 * Contains a declaration of the share class for the Tokyo Cabinet storage
23 * engine.
24 *
25 * @todo
26 * would it not be better to create a class that encapsulates all the calls
27 * to the Tokyo Cabinet API that we can just use from within the table
28 * share?
29 */
30
31#ifndef DRIZZLE_PLUGIN_TOKYO_CABINET_SHARE_H
32#define DRIZZLE_PLUGIN_TOKYO_CABINET_SHARE_H
33
34#include <drizzled/handler.h>
35#include <drizzled/show.h>
36#include <mysys/thr_lock.h>
37
38#include <tcutil.h>
39#include <tchdb.h>
40#include <stdlib.h>
41#include <stdbool.h>
42#include <stdint.h>
43
44class TokyoCabinetShare
45{
46public:
47
48 static const uint32_t MAX_KEY_LEN= 1024;
49
50 TokyoCabinetShare()
51 :
52 use_count(0),
53 lock(),
54 name(),
55 data_handler(NULL),
56 fixed_length_table(false),
57 row_len(0),
58 fields(NULL),
59 null_bytes(0),
60 table_record(NULL),
61 primary_key(NULL),
62 primary_key_len(0)
63 {
64 data_handler= tcmdbnew();
65 }
66
67 TokyoCabinetShare(const std::string &in_name)
68 :
69 use_count(0),
70 lock(),
71 name(in_name),
72 data_handler(NULL),
73 fixed_length_table(false),
74 row_len(0),
75 fields(NULL),
76 null_bytes(0),
77 table_record(NULL),
78 primary_key(NULL),
79 primary_key_len(0)
80 {
81 data_handler= tcmdbnew();
82 }
83
84 ~TokyoCabinetShare()
85 {
86 thr_lock_delete(&lock);
87 tcmdbdel(data_handler);
88 }
89
90 uint32_t getUseCount() const
91 {
92 return use_count;
93 }
94
95 void incUseCount()
96 {
97 use_count++;
98 }
99
100 void decUseCount()
101 {
102 use_count--;
103 }
104
105 const std::string &getName() const
106 {
107 return name;
108 }
109
110 void initThreadLock()
111 {
112 thr_lock_init(&lock);
113 }
114
115 THR_LOCK *getThreadLock()
116 {
117 return &lock;
118 }
119
120 void setFixedLengthTable(bool input)
121 {
122 fixed_length_table= input;
123 }
124
125 bool isFixedLengthTable() const
126 {
127 return fixed_length_table;
128 }
129
130 void setRowLength(uint32_t in_len)
131 {
132 row_len= in_len;
133 }
134
135 void setTableFields(Field **in_fields)
136 {
137 fields= in_fields;
138 }
139
140 void setNullBytes(size_t in_null_bytes)
141 {
142 null_bytes= in_null_bytes;
143 }
144
145 void setTableRecord(unsigned char *in_record)
146 {
147 table_record= in_record;
148 }
149
150 bool createDatabaseHandler();
151
152 bool openTable();
153
154 void freeDatabaseHandler();
155
156 uint64_t getNumOfRecords()
157 {
158 return tcmdbrnum(data_handler);
159 }
160
161 int storeRow(Field *key_field,
162 unsigned char *row);
163
164 int updateRow(Field *key_field,
165 unsigned char *row);
166
167 /**
168 * Create a key for this row to be stored in the Tokyo Cabinet store. The
169 * key is created based on the primary key value for the row.
170 *
171 * @param[in] the primary key field
172 */
173 void createKey(Field *key);
174
175 int deleteRow(Field *key_field);
176
177 void deleteAllRows()
178 {
179 tcmdbvanish(data_handler);
180 }
181
182 void initIterators();
183
184 int retrieveRow(unsigned char *buf);
185
186 int findRow(Field *key_field,
187 unsigned char *buf,
188 const unsigned char *key,
189 size_t key_len);
190
191private:
192
193 /**
194 * Store a variable sized row in Tokyo Cabinet.
195 */
196 size_t packRow(unsigned char *buf, unsigned char *row);
197
198 /**
199 * Retrieve a variable sized row from Tokyo Cabinet.
200 */
201 void unpackRow(unsigned char *buf, const char *row);
202
203 uint32_t use_count;
204 THR_LOCK lock;
205 std::string name;
206 TCMDB *data_handler;
207 bool fixed_length_table;
208 uint32_t row_len;
209 Field **fields;
210 size_t null_bytes;
211 unsigned char *table_record;
212
213 char primary_key_buff[MAX_KEY_LEN];
214 char *primary_key;
215 size_t primary_key_len;
216
217};
218
219#endif /* DRIZZLE_PLUGIN_TOKYO_CABINET_SHARE_H */
0220
=== added directory 'tests/suite/tc_engine'
=== added directory 'tests/suite/tc_engine/r'
=== added file 'tests/suite/tc_engine/r/auto_increment.result'
--- tests/suite/tc_engine/r/auto_increment.result 1970-01-01 00:00:00 +0000
+++ tests/suite/tc_engine/r/auto_increment.result 2009-09-24 03:50:24 +0000
@@ -0,0 +1,32 @@
1DROP TABLE IF EXISTS t2;
2Warnings:
3Note 1051 Unknown table 't2'
4CREATE TABLE t2 (a int primary key auto_increment, b bigint) ENGINE=TOKYO;
5insert into t2 (b) values (42),(74),(108),(256);
6SELECT * from t2 ORDER BY a;
7a b
81 42
92 74
103 108
114 256
12SELECT COUNT(*) from t2;
13COUNT(*)
144
15EXPLAIN SELECT * FROM t2 WHERE a=1;
16id select_type table type possible_keys key key_len ref rows Extra
171 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
18SELECT * FROM t2 WHERE a=1;
19a b
201 42
21SELECT * FROM t2 WHERE a=2;
22a b
232 74
24SELECT * FROM t2 WHERE a=3;
25a b
263 108
27SELECT * FROM t2 WHERE a=4;
28a b
294 256
30SELECT * FROM t2 WHERE a=5;
31a b
32DROP TABLE t2;
033
=== added file 'tests/suite/tc_engine/r/basic.result'
--- tests/suite/tc_engine/r/basic.result 1970-01-01 00:00:00 +0000
+++ tests/suite/tc_engine/r/basic.result 2009-09-24 03:50:24 +0000
@@ -0,0 +1,138 @@
1DROP TABLE IF EXISTS t1;
2Warnings:
3Note 1051 Unknown table 't1'
4CREATE TABLE t1 (a int primary key, b varchar(200)) ENGINE=TOKYO;
5INSERT INTO t1 (a,b) VALUES (1, 'FOO');
6INSERT INTO t1 (a,b) VALUES (2, 'BAR');
7INSERT INTO t1 (a,b) VALUES (3, 'LCA ROCKS');
8INSERT INTO t1 (a,b) VALUES (4, 'freeze ray');
9INSERT INTO t1 (a,b) VALUES (5, 'this row appears because of the kind donations of....');
10SELECT COUNT(*) FROM t1;
11COUNT(*)
125
13SELECT * from t1;
14a b
154 freeze ray
165 this row appears because of the kind donations of....
171 FOO
182 BAR
193 LCA ROCKS
20DROP TABLE t1;
21CREATE TABLE t2 (a int primary key,b bigint) ENGINE=TOKYO;
22insert into t2 (a,b) values (1,42),(2,74),(3,108),(4,256);
23SELECT COUNT(*) FROM t2;
24COUNT(*)
254
26SELECT * from t2;
27a b
284 256
291 42
302 74
313 108
32SELECT * FROM t2 WHERE a > 2;
33a b
344 256
353 108
36SELECT * FROM t2 WHERE a > 4;
37a b
38DROP TABLE t2;
39CREATE TABLE t3 (a int primary key, b int unique) ENGINE=TOKYO;
40ERROR 42000: Too many keys specified; max 1 keys allowed
41CREATE TABLE t4 (a int, b int, PRIMARY KEY (a,b)) ENGINE=TOKYO;
42ERROR 42000: Too many key parts specified; max 1 parts allowed
43CREATE TABLE t5 (a int, index(a)) ENGINE=TOKYO;
44ERROR 42000: Table handler doesn't support NULL in given index. Please change column 'a' to be NOT NULL or use another handler
45drop table if exists t1,t2;
46create table t1 (id int primary key, num int) engine=tokyo;
47insert into t1 values (1, 100);
48insert into t1 values (2, 101);
49insert into t1 values (3, 102);
50insert into t1 values (4, 103);
51insert into t1 values (5, 104);
52select * from t1;
53id num
541 100
552 101
563 102
574 103
585 104
59select count(*) from t1;
60count(*)
615
62select * from t1 where id = 1;
63id num
641 100
65select * from t1 where id = 2;
66id num
672 101
68select * from t1 where id = 3;
69id num
703 102
71select * from t1 where id = 4;
72id num
734 103
74select * from t1 where id = 5;
75id num
765 104
77update t1 set num = 1111 where id = 1;
78update t1 set num = 2222 where id = 2;
79update t1 set num = 3333 where id = 3;
80select * from t1 where id < 4;
81id num
821 1111
832 2222
843 3333
85delete from t1 where id = 1;
86delete from t1 where id = 2;
87delete from t1 where id = 3;
88delete from t1;
89drop table t1;
90create table t2 (id int primary key, b blob) engine=tokyo;
91insert into t2 values (1, "aaa");
92insert into t2 values (2, "bbb");
93insert into t2 values (3, "aaaaaa");
94insert into t2 values (4, "bbbbbb");
95select * from t2;
96id b
971 aaa
982 bbb
993 aaaaaa
1004 bbbbbb
101update t2 set b = NULL where id = 1;
102update t2 set b = "updated" where id = 2;
103update t2 set b = NULL where id = 3;
104update t2 set b = "updated" where id = 4;
105select * from t2;
106id b
1071 NULL
1082 updated
1093 NULL
1104 updated
111drop table t2;
112create table t1(id int primary key, num1 int, num2 int) engine=tokyo;
113create table t2 like t1;
114insert into t2 values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6);
115insert into t2 values (7,7,7), (8,8,8), (9,9,9), (10,10,10), (11,11,11);
116insert into t1 select * from t2;
117select * from t1;
118id num1 num2
1198 8 8
1201 1 1
1219 9 9
12210 10 10
1232 2 2
12411 11 11
1253 3 3
1264 4 4
1275 5 5
1286 6 6
1297 7 7
130delete from t1;
131insert into t1 select * from t2 where id < 5;
132select * from t1;
133id num1 num2
1341 1 1
1352 2 2
1363 3 3
1374 4 4
138drop table t1, t2;
0139
=== added directory 'tests/suite/tc_engine/t'
=== added file 'tests/suite/tc_engine/t/auto_increment.test'
--- tests/suite/tc_engine/t/auto_increment.test 1970-01-01 00:00:00 +0000
+++ tests/suite/tc_engine/t/auto_increment.test 2009-09-24 03:50:24 +0000
@@ -0,0 +1,13 @@
1DROP TABLE IF EXISTS t2;
2CREATE TABLE t2 (a int primary key auto_increment, b bigint) ENGINE=TOKYO;
3insert into t2 (b) values (42),(74),(108),(256);
4SELECT * from t2 ORDER BY a;
5SELECT COUNT(*) from t2;
6EXPLAIN SELECT * FROM t2 WHERE a=1;
7SELECT * FROM t2 WHERE a=1;
8SELECT * FROM t2 WHERE a=2;
9SELECT * FROM t2 WHERE a=3;
10SELECT * FROM t2 WHERE a=4;
11SELECT * FROM t2 WHERE a=5;
12DROP TABLE t2;
13
014
=== added file 'tests/suite/tc_engine/t/basic.test'
--- tests/suite/tc_engine/t/basic.test 1970-01-01 00:00:00 +0000
+++ tests/suite/tc_engine/t/basic.test 2009-09-24 03:50:24 +0000
@@ -0,0 +1,107 @@
1--disable-warnings
2DROP TABLE IF EXISTS t1;
3--enable-warnings
4
5CREATE TABLE t1 (a int primary key, b varchar(200)) ENGINE=TOKYO;
6
7INSERT INTO t1 (a,b) VALUES (1, 'FOO');
8INSERT INTO t1 (a,b) VALUES (2, 'BAR');
9INSERT INTO t1 (a,b) VALUES (3, 'LCA ROCKS');
10INSERT INTO t1 (a,b) VALUES (4, 'freeze ray');
11INSERT INTO t1 (a,b) VALUES (5, 'this row appears because of the kind donations of....');
12SELECT COUNT(*) FROM t1;
13SELECT * from t1;
14
15DROP TABLE t1;
16
17CREATE TABLE t2 (a int primary key,b bigint) ENGINE=TOKYO;
18insert into t2 (a,b) values (1,42),(2,74),(3,108),(4,256);
19SELECT COUNT(*) FROM t2;
20SELECT * from t2;
21SELECT * FROM t2 WHERE a > 2;
22SELECT * FROM t2 WHERE a > 4;
23DROP TABLE t2;
24
25--error ER_TOO_MANY_KEYS
26CREATE TABLE t3 (a int primary key, b int unique) ENGINE=TOKYO;
27
28--error ER_TOO_MANY_KEY_PARTS
29CREATE TABLE t4 (a int, b int, PRIMARY KEY (a,b)) ENGINE=TOKYO;
30
31--error ER_NULL_COLUMN_IN_INDEX
32CREATE TABLE t5 (a int, index(a)) ENGINE=TOKYO;
33
34--disable_warnings
35drop table if exists t1,t2;
36--enable_warnings
37
38## Easy warm up test
39create table t1 (id int primary key, num int) engine=tokyo;
40
41insert into t1 values (1, 100);
42insert into t1 values (2, 101);
43insert into t1 values (3, 102);
44insert into t1 values (4, 103);
45insert into t1 values (5, 104);
46
47select * from t1;
48select count(*) from t1;
49
50# Test Primary Key
51select * from t1 where id = 1;
52select * from t1 where id = 2;
53select * from t1 where id = 3;
54select * from t1 where id = 4;
55select * from t1 where id = 5;
56
57# Update rows based on Primary Key
58update t1 set num = 1111 where id = 1;
59update t1 set num = 2222 where id = 2;
60update t1 set num = 3333 where id = 3;
61
62select * from t1 where id < 4;
63
64# Delete rows based on Primary Key
65delete from t1 where id = 1;
66delete from t1 where id = 2;
67delete from t1 where id = 3;
68
69# Delete remaining rows
70delete from t1;
71
72drop table t1;
73
74# Test BLOB type
75create table t2 (id int primary key, b blob) engine=tokyo;
76
77insert into t2 values (1, "aaa");
78insert into t2 values (2, "bbb");
79insert into t2 values (3, "aaaaaa");
80insert into t2 values (4, "bbbbbb");
81
82select * from t2;
83
84update t2 set b = NULL where id = 1;
85update t2 set b = "updated" where id = 2;
86update t2 set b = NULL where id = 3;
87update t2 set b = "updated" where id = 4;
88
89select * from t2;
90
91drop table t2;
92
93# Test INSERT-SELECT statements
94create table t1(id int primary key, num1 int, num2 int) engine=tokyo;
95create table t2 like t1;
96
97insert into t2 values (1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6);
98insert into t2 values (7,7,7), (8,8,8), (9,9,9), (10,10,10), (11,11,11);
99
100insert into t1 select * from t2;
101select * from t1;
102delete from t1;
103
104insert into t1 select * from t2 where id < 5;
105select * from t1;
106
107drop table t1, t2;