[Commits] 491fbd2: LevelDB Storage Engine: re-commit in git against webscale

Sergei Petrunia psergey at askmonty.org
Fri Jul 11 23:55:19 EEST 2014


revision-id: 491fbd248d0cda2c7920af425194ccf1e1660a2f
parent(s): 0238dae56915746f5ccca8c5845813e7ab88ac45
committer: Sergei Petrunia
branch nick: webscalesql-5.6
timestamp: 2014-07-12 00:55:19 +0400
message:

LevelDB Storage Engine: re-commit in git against webscale

-----------------------

 include/lf.h                                       |   17 +
 mysql-test/r/leveldb.result                        | 1171 +++++++++
 mysql-test/r/leveldb_qcache.result                 |   37 +
 mysql-test/suite/leveldb/1st.result                |   22 +
 mysql-test/suite/leveldb/1st.test                  |   34 +
 mysql-test/suite/leveldb/alter_table.result        |  181 ++
 mysql-test/suite/leveldb/alter_table.test          |   92 +
 mysql-test/suite/leveldb/analyze_table.result      |   29 +
 mysql-test/suite/leveldb/analyze_table.test        |   29 +
 mysql-test/suite/leveldb/autoinc_secondary.result  |   16 +
 mysql-test/suite/leveldb/autoinc_secondary.test    |   34 +
 mysql-test/suite/leveldb/autoinc_vars.result       |   64 +
 mysql-test/suite/leveldb/autoinc_vars.test         |   63 +
 mysql-test/suite/leveldb/autoincrement.result      |    5 +
 mysql-test/suite/leveldb/autoincrement.test        |  125 +
 mysql-test/suite/leveldb/check_table.inc           |   54 +
 mysql-test/suite/leveldb/check_table.result        |   68 +
 mysql-test/suite/leveldb/check_table.test          |   10 +
 mysql-test/suite/leveldb/checksum_table.result     |   20 +
 mysql-test/suite/leveldb/checksum_table.test       |   22 +
 .../suite/leveldb/checksum_table_live.result       |   20 +
 mysql-test/suite/leveldb/checksum_table_live.test  |   22 +
 mysql-test/suite/leveldb/col_not_null.inc          |   55 +
 .../suite/leveldb/col_not_null_timestamp.inc       |   61 +
 mysql-test/suite/leveldb/col_null.inc              |   33 +
 mysql-test/suite/leveldb/col_opt_default.result    |   20 +
 mysql-test/suite/leveldb/col_opt_default.test      |   25 +
 mysql-test/suite/leveldb/col_opt_not_null.result   | 2612 ++++++++++++++++++++
 mysql-test/suite/leveldb/col_opt_not_null.test     |  222 ++
 mysql-test/suite/leveldb/col_opt_null.result       | 2115 ++++++++++++++++
 mysql-test/suite/leveldb/col_opt_null.test         |  214 ++
 mysql-test/suite/leveldb/col_opt_unsigned.result   |  741 ++++++
 mysql-test/suite/leveldb/col_opt_unsigned.test     |   72 +
 mysql-test/suite/leveldb/col_opt_zerofill.result   |  723 ++++++
 mysql-test/suite/leveldb/col_opt_zerofill.test     |   65 +
 .../leveldb/cons_snapshot_repeatable_read.result   |   18 +
 .../leveldb/cons_snapshot_repeatable_read.test     |    4 +
 .../leveldb/cons_snapshot_serializable.result      |   24 +
 .../suite/leveldb/cons_snapshot_serializable.test  |    4 +
 mysql-test/suite/leveldb/consistent_snapshot.inc   |   42 +
 mysql-test/suite/leveldb/create_table.result       |   44 +
 mysql-test/suite/leveldb/create_table.test         |   67 +
 mysql-test/suite/leveldb/delete.result             |  123 +
 mysql-test/suite/leveldb/delete.test               |  100 +
 mysql-test/suite/leveldb/delete_ignore.result      |   59 +
 mysql-test/suite/leveldb/delete_ignore.test        |   35 +
 mysql-test/suite/leveldb/delete_quick.result       |   24 +
 mysql-test/suite/leveldb/delete_quick.test         |   30 +
 mysql-test/suite/leveldb/delete_with_keys.result   |   38 +
 mysql-test/suite/leveldb/delete_with_keys.test     |   37 +
 mysql-test/suite/leveldb/describe.result           |   19 +
 mysql-test/suite/leveldb/describe.test             |   22 +
 mysql-test/suite/leveldb/disabled.def              |   11 +
 mysql-test/suite/leveldb/index.inc                 |  113 +
 mysql-test/suite/leveldb/index.result              |   42 +
 mysql-test/suite/leveldb/index.test                |   21 +
 .../suite/leveldb/index_key_block_size.result      |   51 +
 mysql-test/suite/leveldb/index_key_block_size.test |   65 +
 mysql-test/suite/leveldb/index_primary.result      |   52 +
 mysql-test/suite/leveldb/index_primary.test        |   61 +
 mysql-test/suite/leveldb/index_type_btree.result   |   42 +
 mysql-test/suite/leveldb/index_type_btree.test     |   10 +
 mysql-test/suite/leveldb/index_type_hash.result    |   42 +
 mysql-test/suite/leveldb/index_type_hash.test      |   10 +
 mysql-test/suite/leveldb/insert.result             |  209 ++
 mysql-test/suite/leveldb/insert.test               |   99 +
 mysql-test/suite/leveldb/insert_with_keys.result   |   63 +
 mysql-test/suite/leveldb/insert_with_keys.test     |   91 +
 .../suite/leveldb/level_read_committed.result      |   91 +
 mysql-test/suite/leveldb/level_read_committed.test |    5 +
 .../suite/leveldb/level_read_uncommitted.result    |  116 +
 .../suite/leveldb/level_read_uncommitted.test      |    4 +
 .../suite/leveldb/level_repeatable_read.result     |   69 +
 .../suite/leveldb/level_repeatable_read.test       |    3 +
 mysql-test/suite/leveldb/level_serializable.result |   56 +
 mysql-test/suite/leveldb/level_serializable.test   |    3 +
 mysql-test/suite/leveldb/loaddata.result           |   93 +
 mysql-test/suite/leveldb/loaddata.test             |   91 +
 mysql-test/suite/leveldb/lock.result               |  108 +
 mysql-test/suite/leveldb/lock.test                 |  200 ++
 mysql-test/suite/leveldb/misc.result               |   89 +
 mysql-test/suite/leveldb/misc.test                 |   43 +
 mysql-test/suite/leveldb/my.cnf                    |    7 +
 mysql-test/suite/leveldb/optimize_table.inc        |   30 +
 mysql-test/suite/leveldb/optimize_table.result     |   29 +
 mysql-test/suite/leveldb/optimize_table.test       |    6 +
 mysql-test/suite/leveldb/repair_table.inc          |   38 +
 mysql-test/suite/leveldb/repair_table.result       |   37 +
 mysql-test/suite/leveldb/repair_table.test         |    6 +
 mysql-test/suite/leveldb/replace.result            |   32 +
 mysql-test/suite/leveldb/replace.test              |   52 +
 mysql-test/suite/leveldb/se-innodb.out             |    1 +
 mysql-test/suite/leveldb/select.result             |  373 +++
 mysql-test/suite/leveldb/select.test               |  200 ++
 mysql-test/suite/leveldb/select_for_update.result  |   35 +
 mysql-test/suite/leveldb/select_for_update.test    |   53 +
 .../suite/leveldb/select_lock_in_share_mode.result |   37 +
 .../suite/leveldb/select_lock_in_share_mode.test   |   52 +
 mysql-test/suite/leveldb/show_engine.result        |    5 +
 mysql-test/suite/leveldb/show_engine.test          |   13 +
 mysql-test/suite/leveldb/show_table_status.result  |   62 +
 mysql-test/suite/leveldb/show_table_status.test    |   26 +
 mysql-test/suite/leveldb/tbl_opt_ai.result         |   38 +
 mysql-test/suite/leveldb/tbl_opt_ai.test           |   27 +
 .../suite/leveldb/tbl_opt_avg_row_length.result    |   18 +
 .../suite/leveldb/tbl_opt_avg_row_length.test      |   21 +
 mysql-test/suite/leveldb/tbl_opt_checksum.result   |   18 +
 mysql-test/suite/leveldb/tbl_opt_checksum.test     |   17 +
 mysql-test/suite/leveldb/tbl_opt_connection.result |   26 +
 mysql-test/suite/leveldb/tbl_opt_connection.test   |   30 +
 .../suite/leveldb/tbl_opt_data_index_dir.result    |   20 +
 .../suite/leveldb/tbl_opt_data_index_dir.test      |   35 +
 .../suite/leveldb/tbl_opt_delay_key_write.result   |   18 +
 .../suite/leveldb/tbl_opt_delay_key_write.test     |   21 +
 .../suite/leveldb/tbl_opt_insert_method.result     |   18 +
 .../suite/leveldb/tbl_opt_insert_method.test       |   21 +
 .../suite/leveldb/tbl_opt_key_block_size.result    |   18 +
 .../suite/leveldb/tbl_opt_key_block_size.test      |   21 +
 mysql-test/suite/leveldb/tbl_opt_max_rows.result   |   18 +
 mysql-test/suite/leveldb/tbl_opt_max_rows.test     |   21 +
 mysql-test/suite/leveldb/tbl_opt_min_rows.result   |   18 +
 mysql-test/suite/leveldb/tbl_opt_min_rows.test     |   21 +
 mysql-test/suite/leveldb/tbl_opt_pack_keys.result  |   18 +
 mysql-test/suite/leveldb/tbl_opt_pack_keys.test    |   21 +
 mysql-test/suite/leveldb/tbl_opt_password.result   |   18 +
 mysql-test/suite/leveldb/tbl_opt_password.test     |   25 +
 mysql-test/suite/leveldb/tbl_opt_row_format.result |   18 +
 mysql-test/suite/leveldb/tbl_opt_row_format.test   |   21 +
 mysql-test/suite/leveldb/tbl_opt_union.result      |   16 +
 mysql-test/suite/leveldb/tbl_opt_union.test        |   26 +
 mysql-test/suite/leveldb/tbl_standard_opts.result  |   46 +
 mysql-test/suite/leveldb/tbl_standard_opts.test    |   40 +
 mysql-test/suite/leveldb/transaction_isolation.inc |   92 +
 mysql-test/suite/leveldb/truncate_table.result     |   33 +
 mysql-test/suite/leveldb/truncate_table.test       |   68 +
 mysql-test/suite/leveldb/type_binary.inc           |   45 +
 mysql-test/suite/leveldb/type_binary.result        |   48 +
 mysql-test/suite/leveldb/type_binary.test          |    6 +
 .../suite/leveldb/type_binary_indexes.result       |   85 +
 mysql-test/suite/leveldb/type_binary_indexes.test  |   86 +
 mysql-test/suite/leveldb/type_bit.inc              |   53 +
 mysql-test/suite/leveldb/type_bit.result           |   53 +
 mysql-test/suite/leveldb/type_bit.test             |    6 +
 mysql-test/suite/leveldb/type_bit_indexes.result   |   72 +
 mysql-test/suite/leveldb/type_bit_indexes.test     |  102 +
 mysql-test/suite/leveldb/type_blob.inc             |   49 +
 mysql-test/suite/leveldb/type_blob.result          |   57 +
 mysql-test/suite/leveldb/type_blob.test            |    6 +
 mysql-test/suite/leveldb/type_blob_indexes.result  |  152 ++
 mysql-test/suite/leveldb/type_blob_indexes.test    |  109 +
 mysql-test/suite/leveldb/type_bool.inc             |   64 +
 mysql-test/suite/leveldb/type_bool.result          |   73 +
 mysql-test/suite/leveldb/type_bool.test            |    6 +
 mysql-test/suite/leveldb/type_char.inc             |   45 +
 mysql-test/suite/leveldb/type_char.result          |   58 +
 mysql-test/suite/leveldb/type_char.test            |    6 +
 mysql-test/suite/leveldb/type_char_indexes.result  |   79 +
 mysql-test/suite/leveldb/type_char_indexes.test    |   92 +
 mysql-test/suite/leveldb/type_date_time.inc        |   45 +
 mysql-test/suite/leveldb/type_date_time.result     |   53 +
 mysql-test/suite/leveldb/type_date_time.test       |    7 +
 .../suite/leveldb/type_date_time_indexes.result    |  126 +
 .../suite/leveldb/type_date_time_indexes.test      |  143 ++
 mysql-test/suite/leveldb/type_enum.inc             |   50 +
 mysql-test/suite/leveldb/type_enum.result          |   47 +
 mysql-test/suite/leveldb/type_enum.test            |    6 +
 mysql-test/suite/leveldb/type_enum_indexes.result  |   74 +
 mysql-test/suite/leveldb/type_enum_indexes.test    |   81 +
 mysql-test/suite/leveldb/type_fixed.inc            |   85 +
 mysql-test/suite/leveldb/type_fixed.result         |  131 +
 mysql-test/suite/leveldb/type_fixed.test           |    6 +
 mysql-test/suite/leveldb/type_fixed_indexes.result |   99 +
 mysql-test/suite/leveldb/type_fixed_indexes.test   |   96 +
 mysql-test/suite/leveldb/type_float.inc            |  108 +
 mysql-test/suite/leveldb/type_float.result         |  306 +++
 mysql-test/suite/leveldb/type_float.test           |    6 +
 mysql-test/suite/leveldb/type_float_indexes.result |   75 +
 mysql-test/suite/leveldb/type_float_indexes.test   |  107 +
 mysql-test/suite/leveldb/type_int.inc              |   68 +
 mysql-test/suite/leveldb/type_int.result           |  212 ++
 mysql-test/suite/leveldb/type_int.test             |    6 +
 mysql-test/suite/leveldb/type_int_indexes.result   |   61 +
 mysql-test/suite/leveldb/type_int_indexes.test     |   66 +
 mysql-test/suite/leveldb/type_set.inc              |   49 +
 mysql-test/suite/leveldb/type_set.result           |   49 +
 mysql-test/suite/leveldb/type_set.test             |    6 +
 mysql-test/suite/leveldb/type_set_indexes.result   |   85 +
 mysql-test/suite/leveldb/type_set_indexes.test     |   94 +
 mysql-test/suite/leveldb/type_text.inc             |   49 +
 mysql-test/suite/leveldb/type_text.result          |   57 +
 mysql-test/suite/leveldb/type_text.test            |    6 +
 mysql-test/suite/leveldb/type_text_indexes.result  |  137 +
 mysql-test/suite/leveldb/type_text_indexes.test    |  102 +
 mysql-test/suite/leveldb/type_varbinary.inc        |   75 +
 mysql-test/suite/leveldb/type_varbinary.result     |   93 +
 mysql-test/suite/leveldb/type_varbinary.test       |    6 +
 mysql-test/suite/leveldb/type_varchar.inc          |   77 +
 mysql-test/suite/leveldb/type_varchar.result       |  128 +
 mysql-test/suite/leveldb/type_varchar.test         |    6 +
 mysql-test/suite/leveldb/update.result             |  113 +
 mysql-test/suite/leveldb/update.test               |   70 +
 mysql-test/suite/leveldb/update_ignore.result      |   58 +
 mysql-test/suite/leveldb/update_ignore.test        |   33 +
 mysql-test/suite/leveldb/update_multi.result       |   65 +
 mysql-test/suite/leveldb/update_multi.test         |   30 +
 mysql-test/suite/leveldb/update_with_keys.result   |   39 +
 mysql-test/suite/leveldb/update_with_keys.test     |   75 +
 mysql-test/t/leveldb.test                          | 1053 ++++++++
 mysql-test/t/leveldb_qcache-master.opt             |    1 +
 mysql-test/t/leveldb_qcache.test                   |   28 +
 mysql-test/valgrind.supp                           |   25 +
 mysys/lf_hash.c                                    |  147 +-
 sql/handler.h                                      |    1 +
 sql/key.cc                                         |    9 +-
 sql/table.cc                                       |    6 +
 storage/leveldb/CMakeLists.txt                     |   54 +
 storage/leveldb/ha_leveldb.cc                      | 2511 +++++++++++++++++++
 storage/leveldb/ha_leveldb.h                       |  307 +++
 storage/leveldb/ldb_applyiter.cc                   |  207 ++
 storage/leveldb/ldb_applyiter.h                    |   53 +
 storage/leveldb/ldb_datadic.cc                     |  795 ++++++
 storage/leveldb/ldb_datadic.h                      |  359 +++
 storage/leveldb/ldb_locks.cc                       |  311 +++
 storage/leveldb/ldb_locks.h                        |   96 +
 storage/leveldb/ldb_rowmods.cc                     |  364 +++
 storage/leveldb/ldb_rowmods.h                      |  140 ++
 storage/leveldb/unittest/CMakeLists.txt            |   11 +
 storage/leveldb/unittest/test_rowlocks.cc          |  165 ++
 storage/leveldb/unittest/thr_template.cc           |   93 +
 support-files/build-tags                           |    2 +-
 230 files changed, 25356 insertions(+), 17 deletions(-)

diff --git a/include/lf.h b/include/lf.h
index 44c8279..b2538cc 100644
--- a/include/lf.h
+++ b/include/lf.h
@@ -222,6 +222,11 @@ C_MODE_START
 
 #define LF_HASH_UNIQUE 1
 
+typedef int (*lf_key_comparison_func_t) (const uchar *s, size_t slen, 
+                                         const uchar *t, size_t tlen);
+
+typedef ulong (*lf_hashfunc_t) (const char *key, size_t key_len);
+
 /* lf_hash overhead per element (that is, sizeof(LF_SLIST) */
 extern const int LF_HASH_OVERHEAD;
 
@@ -235,6 +240,18 @@ typedef struct {
   uint flags;                           /* LF_HASH_UNIQUE, etc */
   int32 volatile size;                  /* size of array */
   int32 volatile count;                 /* number of elements in the hash */
+
+  /*
+    The hash needs to be able to compare keys when they have hash collision.
+
+    By default, key_comparator==NULL, and keys are compared with 
+      my_strnncoll(charset, KEY1, KEY2)
+
+    When my_strnncoll cannot provide correct comparison, the user should set
+    key_comparator to provide the comparison function.
+  */
+  lf_key_comparison_func_t  key_comparator;
+  lf_hashfunc_t             hashfunc;
 } LF_HASH;
 
 void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
diff --git a/mysql-test/r/leveldb.result b/mysql-test/r/leveldb.result
new file mode 100644
index 0000000..930b16c
--- /dev/null
+++ b/mysql-test/r/leveldb.result
@@ -0,0 +1,1171 @@
+select * from information_schema.engines where engine = 'leveldb';
+ENGINE	SUPPORT	COMMENT	TRANSACTIONS	XA	SAVEPOINTS
+LEVELDB	YES	LevelDB storage engine	YES	NO	NO
+drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+drop table if exists t11,t12,t13,t14,t15,t16,t17,t18,t19,t20;
+drop table if exists t21,t22,t23,t24,t25,t26,t27,t28,t29;
+drop table if exists t30,t31,t32,t33,t34,t35,t36,t37,t38,t39;
+drop table if exists t40,t41,t42,t43,t44,t45,t46,t47,t48,t49;
+create table t0 (a int primary key) engine=leveldb;
+show create table t0;
+Table	Create Table
+t0	CREATE TABLE `t0` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+drop table t0;
+# Try creating a table without PK:
+create table t1(a int) engine=leveldb;
+ERROR 42000: This table type requires a primary key
+create table t1 (a int primary key, b int) engine=leveldb;
+insert into t1 values (1,1);
+insert into t1 values (2,2);
+select * from t1;
+a	b
+1	1
+2	2
+# Check that we can create another table and insert there
+create table t2 (a varchar(10) primary key, b varchar(10)) engine=leveldb;
+insert into t2 value ('abc','def');
+insert into t2 value ('hijkl','mnopq');
+select * from t2;
+a	b
+abc	def
+hijkl	mnopq
+# Select again from t1 to see that records from different tables dont mix
+select * from t1;
+a	b
+1	1
+2	2
+explain select * from t2 where a='no-such-key';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+explain select * from t2 where a='abc';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	const	PRIMARY	PRIMARY	12	const	1	NULL
+select * from t2 where a='abc';
+a	b
+abc	def
+# Try a composite PK
+create table t3 (
+pk1 int, 
+pk2 varchar(10),
+col1 varchar(10),
+primary key(pk1, pk2)
+) engine=leveldb;
+insert into t3 values (2,'two', 'row#2');
+insert into t3 values (3,'three', 'row#3');
+insert into t3 values (1,'one', 'row#1');
+select * from t3;
+pk1	pk2	col1
+1	one	row#1
+2	two	row#2
+3	three	row#3
+select * from t3 where pk1=3 and pk2='three';
+pk1	pk2	col1
+3	three	row#3
+drop table t1, t2, t3;
+# 
+# Test blob values
+#
+create table t4 (a int primary key, b blob) engine=leveldb;
+insert into t4 values (1, repeat('quux-quux', 60));
+insert into t4 values (10, repeat('foo-bar', 43));
+insert into t4 values (5, repeat('foo-bar', 200));
+insert into t4 values (2, NULL);
+select 
+a,
+(case a 
+when 1  then b=repeat('quux-quux', 60)
+when 10 then b=repeat('foo-bar', 43)
+when 5  then b=repeat('foo-bar', 200)
+when 2  then b is null
+else 'IMPOSSIBLE!' end) as CMP
+from t4;
+a	CMP
+1	1
+2	1
+5	1
+10	1
+drop table t4;
+#
+# Test blobs of various sizes
+# 
+# TINYBLOB
+create table t5 (a int primary key, b tinyblob) engine=leveldb;
+insert into t5 values (1, repeat('quux-quux', 6));
+insert into t5 values (10, repeat('foo-bar', 4));
+insert into t5 values (5, repeat('foo-bar', 2));
+select 
+a,
+(case a 
+when 1  then b=repeat('quux-quux', 6)
+when 10 then b=repeat('foo-bar', 4)
+when 5  then b=repeat('foo-bar', 2)
+else 'IMPOSSIBLE!' end) as CMP
+from t5;
+a	CMP
+1	1
+5	1
+10	1
+drop table t5;
+# MEDIUMBLOB
+create table t6 (a int primary key, b mediumblob) engine=leveldb;
+insert into t6 values (1, repeat('AB', 65000));
+insert into t6 values (10, repeat('bbb', 40000));
+insert into t6 values (5, repeat('foo-bar', 2));
+select 
+a,
+(case a 
+when 1  then b=repeat('AB', 65000)
+when 10 then b=repeat('bbb', 40000)
+when 5  then b=repeat('foo-bar', 2)
+else 'IMPOSSIBLE!' end) as CMP
+from t6;
+a	CMP
+1	1
+5	1
+10	1
+drop table t6;
+# LONGBLOB
+create table t7 (a int primary key, b longblob) engine=leveldb;
+insert into t7 values (1, repeat('AB', 65000));
+insert into t7 values (10, repeat('bbb', 40000));
+insert into t7 values (5, repeat('foo-bar', 2));
+select 
+a,
+(case a 
+when 1  then b=repeat('AB', 65000)
+when 10 then b=repeat('bbb', 40000)
+when 5  then b=repeat('foo-bar', 2)
+else 'IMPOSSIBLE!' end) as CMP
+from t7;
+a	CMP
+1	1
+5	1
+10	1
+drop table t7;
+#
+# Check if DELETEs work
+# 
+create table t8 (a varchar(10) primary key, col1 varchar(12)) engine=leveldb;
+insert into t8 values 
+('one', 'eins'),
+('two', 'zwei'),
+('three', 'drei'),
+('four', 'vier'),
+('five', 'funf');
+# Delete by PK
+explain delete from t8 where a='three';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t8	range	PRIMARY	PRIMARY	12	NULL	1	Using where
+delete from t8 where a='three';
+select * from t8;
+a	col1
+five	funf
+four	vier
+one	eins
+two	zwei
+# Delete while doing a full table scan
+delete from t8 where col1='eins' or col1='vier';
+select * from t8;
+a	col1
+five	funf
+two	zwei
+# delete w/o WHERE:
+delete from t8;
+select * from t8;
+a	col1
+#
+# Test UPDATEs
+#
+insert into t8 values 
+('one', 'eins'),
+('two', 'zwei'),
+('three', 'drei'),
+('four', 'vier'),
+('five', 'funf');
+update t8 set col1='dva' where a='two';
+update t8 set a='fourAAA' where col1='vier';
+select * from t8;
+a	col1
+five	funf
+fourAAA	vier
+one	eins
+three	drei
+two	dva
+delete from t8;
+#
+# Basic transactions tests
+#
+begin;
+insert into t8 values ('trx1-val1', 'data');
+insert into t8 values ('trx1-val2', 'data');
+rollback;
+select * from t8;
+a	col1
+begin;
+insert into t8 values ('trx1-val1', 'data');
+insert into t8 values ('trx1-val2', 'data');
+commit;
+select * from t8;
+a	col1
+trx1-val1	data
+trx1-val2	data
+drop table t8;
+#
+# Check if DROP TABLE works
+#
+create table t8 (a varchar(10) primary key, col1 varchar(12)) engine=leveldb;
+select * from t8;
+a	col1
+insert into t8 values ('foo','foo');
+drop table t8;
+create table t8 (a varchar(10) primary key, col1 varchar(12)) engine=leveldb;
+select * from t8;
+a	col1
+drop table t8;
+#
+# MDEV-3961: Assertion ... on creating a TEMPORARY LevelDB table
+#
+CREATE TEMPORARY TABLE t10 (pk INT PRIMARY KEY) ENGINE=LevelDB;
+ERROR HY000: Table storage engine 'LEVELDB' does not support the create option 'TEMPORARY'
+#
+# MDEV-3963: JOIN or WHERE conditions involving keys on LevelDB tables don't work
+#
+CREATE TABLE t10 (i INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t10 VALUES (1),(3);
+CREATE TABLE t11 (j INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t11 VALUES (1),(4);
+select * from t10;
+i
+1
+3
+select * from t11;
+j
+1
+4
+EXPLAIN
+SELECT * FROM t10, t11 WHERE i=j;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t10	index	PRIMARY	PRIMARY	4	NULL	1000	Using index
+1	SIMPLE	t11	eq_ref	PRIMARY	PRIMARY	4	test.t10.i	1	Using index
+SELECT * FROM t10, t11 WHERE i=j;
+i	j
+1	1
+DROP TABLE t10,t11;
+#
+# MDEV-3962: SELECT with ORDER BY causes "ERROR 1030 (HY000): Got error 122
+#
+CREATE TABLE t12 (pk INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t12 VALUES (2),(1);
+SELECT * FROM t12 ORDER BY pk;
+pk
+1
+2
+DROP TABLE t12;
+#
+# MDEV-3964: Assertion `!pk_descr' fails in ha_leveldb::open on adding partitions ...
+#
+create table t14 (pk int primary key) engine=LevelDB partition by hash(pk) partitions 2;
+drop table t14;
+#
+# MDEV-3960: Server crashes on running DISCARD TABLESPACE on a LevelDB table
+#
+create table t9 (i int primary key) engine=leveldb;
+alter table t9 discard tablespace;
+ERROR HY000: Table storage engine for 't9' doesn't have this option
+drop table t9;
+#
+# MDEV-3959: Assertion `slice->size() == table->s->reclength' fails ...
+#   on accessing a table after ALTER
+#
+CREATE TABLE t15 (a INT, leveldb_pk INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t15 VALUES (1,1),(5,2);
+ALTER TABLE t15 DROP COLUMN a;
+DROP TABLE t15;
+#
+# MDEV-3968: UPDATE produces a wrong result while modifying a PK on a LevelDB table
+#
+create table t16 (pk int primary key, a char(8)) engine=LevelDB;
+insert into t16 values (1,'a'),(2,'b'),(3,'c'),(4,'d');
+update t16 set pk=100, a = 'updated' where a in ('b','c');
+ERROR 23000: Duplicate entry '100' for key 'PRIMARY'
+select * from t16;
+pk	a
+1	a
+2	b
+3	c
+4	d
+drop table t16;
+#
+# MDEV-3970: A set of assorted crashes on inserting a row into a LevelDB table 
+#
+drop table if exists t_very_long_table_name;
+CREATE TABLE `t_very_long_table_name` (
+`c` char(1) NOT NULL,
+`c0` char(0) NOT NULL,
+`c1` char(1) NOT NULL,
+`c20` char(20) NOT NULL,
+`c255` char(255) NOT NULL,
+PRIMARY KEY (`c255`)
+) ENGINE=LevelDB DEFAULT CHARSET=latin1;
+INSERT INTO t_very_long_table_name VALUES ('a', '', 'c', REPEAT('a',20), REPEAT('x',255));
+drop table t_very_long_table_name;
+#
+# Test table locking and read-before-write checks.
+#
+create table t17 (pk varchar(12) primary key, col1 varchar(12)) engine=leveldb;
+insert into t17 values ('row1', 'val1');
+insert into t17 values ('row1', 'val1-try2');
+ERROR 23000: Duplicate entry 'row1' for key 'PRIMARY'
+insert into t17 values ('ROW1', 'val1-try2');
+ERROR 23000: Duplicate entry 'ROW1' for key 'PRIMARY'
+insert into t17 values ('row2', 'val2');
+insert into t17 values ('row3', 'val3');
+# This is ok
+update t17 set pk='row4' where pk='row1';
+# This will try to overwrite another row:
+update t17 set pk='row3' where pk='row2';
+ERROR 23000: Duplicate entry 'row3' for key 'PRIMARY'
+select * from t17;
+pk	col1
+row2	val2
+row3	val3
+row4	val1
+#
+# Locking tests
+#
+# First, make sure there's no locking when transactions update different rows
+set autocommit=0;
+update t17 set col1='UPD1' where pk='row2';
+update t17 set col1='UPD2' where pk='row3';
+commit;
+select * from t17;
+pk	col1
+row2	UPD1
+row3	UPD2
+row4	val1
+# Check the variable
+show variables like 'leveldb_lock_wait_timeout';
+Variable_name	Value
+leveldb_lock_wait_timeout	1
+set leveldb_lock_wait_timeout=2;
+show variables like 'leveldb_lock_wait_timeout';
+Variable_name	Value
+leveldb_lock_wait_timeout	2
+# Try updating the same row from two transactions
+begin;
+update t17 set col1='UPD2-AA' where pk='row2';
+update t17 set col1='UPD2-BB' where pk='row2';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+set leveldb_lock_wait_timeout=1000;
+update t17 set col1='UPD2-CC' where pk='row2';
+rollback;
+select * from t17 where pk='row2';
+pk	col1
+row2	UPD2-CC
+drop table t17;
+#
+#  MDEV-4035: LevelDB: SELECT produces different results inside a transaction (read is not repeatable)
+#
+create table t18 (pk int primary key, i int) engine=LevelDB;
+begin;
+select * from t18;
+pk	i
+select * from t18 where pk = 1;
+pk	i
+connect  con1,localhost,root,,;
+insert into t18 values (1,100);
+connection default;
+select * from t18;
+pk	i
+select * from t18 where pk = 1;
+pk	i
+commit;
+drop table t18;
+#
+# MDEV-4036: LevelDB: INSERT .. ON DUPLICATE KEY UPDATE does not work, produces ER_DUP_KEY
+#
+create table t19 (pk int primary key, i int) engine=LevelDB;
+insert into t19 values (1,1);
+insert into t19 values (1,100) on duplicate key update i = 102;
+select * from t19;
+pk	i
+1	102
+drop table t19;
+# MDEV-4037: LevelDB: REPLACE doesn't work, produces ER_DUP_KEY
+create table t20 (pk int primary key, i int) engine=LevelDB;
+insert into t20 values (1,1);
+replace into t20 values (1,100);
+select * from t20;
+pk	i
+1	100
+drop table t20;
+#
+# MDEV-4041: Server crashes in Primary_key_comparator::get_hashnr on INSERT 
+#
+create table t21 (v varbinary(16) primary key, i int) engine=LevelDB;
+insert into t21 values ('a',1);
+select * from t21;
+v	i
+a	1
+drop table t21;
+#
+# MDEV-4047: LevelDB: Assertion `0' fails in Protocol::end_statement() on multi-table INSERT IGNORE
+#
+CREATE TABLE t22 (a int primary key) ENGINE=LevelDB;
+INSERT INTO t22 VALUES (1),(2);
+CREATE TABLE t23 (b int primary key) ENGINE=LevelDB;
+INSERT INTO t23 SELECT * FROM t22;
+DELETE IGNORE t22.*, t23.* FROM t22, t23 WHERE b < a;
+DROP TABLE t22,t23;
+#
+# MDEV-4046: LevelDB: Multi-table DELETE locks itself and ends with ER_LOCK_WAIT_TIMEOUT
+#
+CREATE TABLE t24 (pk int primary key) ENGINE=LevelDB;
+INSERT INTO t24 VALUES (1),(2);
+CREATE TABLE t25 LIKE t24;
+INSERT INTO t25 SELECT * FROM t24;
+DELETE t25.* FROM t24, t25;
+DROP TABLE t24,t25;
+#
+# MDEV-4044: LevelDB: UPDATE or DELETE with ORDER BY locks itself
+#
+create table t26 (pk int primary key, c char(1)) engine=LevelDB;
+insert into t26 values (1,'a'),(2,'b');
+update t26 set c = 'x' order by pk limit 1;
+delete from t26 order by pk limit 1;
+select * from t26;
+pk	c
+2	b
+drop table t26;
+#
+# Test whether SELECT ... FOR UPDATE puts locks
+#
+create table t27(pk varchar(10) primary key, col1 varchar(20)) engine=LevelDB;
+insert into t27 values 
+('row1', 'row1data'),
+('row2', 'row2data'),
+('row3', 'row3data');
+connection con1;
+begin;
+select * from t27 where pk='row3' for update;
+pk	col1
+row3	row3data
+connection default;
+set leveldb_lock_wait_timeout=1;
+update t27 set col1='row2-modified' where pk='row3';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection con1;
+rollback;
+connection default;
+disconnect con1;
+drop table t27;
+#
+# MDEV-4060: LevelDB: Assertion `! trx->batch' fails in 
+#
+create table t28 (pk int primary key, a int) engine=LevelDB;
+insert into t28 values (1,10),(2,20);
+begin;
+update t28 set a = 100 where pk = 3;
+rollback;
+select * from t28;
+pk	a
+1	10
+2	20
+drop table t28;
+# 
+# Secondary indexes
+#
+create table t30 (
+pk varchar(16) not null primary key, 
+key1 varchar(16) not null, 
+col1 varchar(16) not null,
+key(key1)
+) engine=leveldb;
+insert into t30 values ('row1', 'row1-key', 'row1-data');
+insert into t30 values ('row2', 'row2-key', 'row2-data');
+insert into t30 values ('row3', 'row3-key', 'row3-data');
+explain
+select * from t30 where key1='row2-key';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	ref	key1	key1	18	const	10	Using where
+select * from t30 where key1='row2-key';
+pk	key1	col1
+row2	row2-key	row2-data
+explain 
+select * from t30 where key1='row1';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	ref	key1	key1	18	const	10	Using where
+# This will produce nothing:
+select * from t30 where key1='row1';
+pk	key1	col1
+explain
+select key1 from t30;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	ALL	NULL	NULL	NULL	NULL	1000	NULL
+select key1 from t30;
+key1
+row1-key
+row2-key
+row3-key
+# Create a duplicate record
+insert into t30 values ('row2a', 'row2-key', 'row2a-data');
+# Can we see it?
+select * from t30 where key1='row2-key';
+pk	key1	col1
+row2	row2-key	row2-data
+row2a	row2-key	row2a-data
+delete from t30 where pk='row2';
+select * from t30 where key1='row2-key';
+pk	key1	col1
+row2a	row2-key	row2a-data
+#
+# Range scans on secondary index
+#
+delete from t30;
+insert into t30 values 
+('row1', 'row1-key', 'row1-data'),
+('row2', 'row2-key', 'row2-data'),
+('row3', 'row3-key', 'row3-data'),
+('row4', 'row4-key', 'row4-data'),
+('row5', 'row5-key', 'row5-data');
+explain 
+select * from t30 where key1 <='row3-key';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	key1	key1	18	NULL	10	Using where
+select * from t30 where key1 <='row3-key';
+pk	key1	col1
+row1	row1-key	row1-data
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+explain 
+select * from t30 where key1 between 'row2-key' and 'row4-key';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	key1	key1	18	NULL	10	Using where
+select * from t30 where key1 between 'row2-key' and 'row4-key';
+pk	key1	col1
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+row4	row4-key	row4-data
+explain 
+select * from t30 where key1 in ('row2-key','row4-key');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	key1	key1	18	NULL	20	Using where
+select * from t30 where key1 in ('row2-key','row4-key');
+pk	key1	col1
+row2	row2-key	row2-data
+row4	row4-key	row4-data
+explain 
+select key1 from t30 where key1 in ('row2-key','row4-key');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	key1	key1	18	NULL	20	Using where
+select key1 from t30 where key1 in ('row2-key','row4-key');
+key1
+row2-key
+row4-key
+explain 
+select * from t30 where key1 > 'row1-key' and key1 < 'row4-key';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	key1	key1	18	NULL	10	Using where
+select * from t30 where key1 > 'row1-key' and key1 < 'row4-key';
+pk	key1	col1
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+explain 
+select * from t30 order by key1 limit 3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	index	NULL	key1	18	NULL	3	NULL
+select * from t30 order by key1 limit 3;
+pk	key1	col1
+row1	row1-key	row1-data
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+explain 
+select * from t30 order by key1 desc limit 3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	index	NULL	key1	18	NULL	3	NULL
+select * from t30 order by key1 desc limit 3;
+pk	key1	col1
+row5	row5-key	row5-data
+row4	row4-key	row4-data
+row3	row3-key	row3-data
+#
+# Range scans on primary key
+#
+explain 
+select * from t30 where pk <='row3';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	PRIMARY	PRIMARY	18	NULL	10	Using where
+select * from t30 where pk <='row3';
+pk	key1	col1
+row1	row1-key	row1-data
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+explain 
+select * from t30 where pk between 'row2' and 'row4';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	PRIMARY	PRIMARY	18	NULL	10	Using where
+select * from t30 where pk between 'row2' and 'row4';
+pk	key1	col1
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+row4	row4-key	row4-data
+explain 
+select * from t30 where pk in ('row2','row4');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	range	PRIMARY	PRIMARY	18	NULL	2	Using where
+select * from t30 where pk in ('row2','row4');
+pk	key1	col1
+row2	row2-key	row2-data
+row4	row4-key	row4-data
+explain 
+select * from t30 order by pk limit 3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t30	index	NULL	PRIMARY	18	NULL	3	NULL
+select * from t30 order by pk limit 3;
+pk	key1	col1
+row1	row1-key	row1-data
+row2	row2-key	row2-data
+row3	row3-key	row3-data
+drop table t30;
+#
+# MDEV-3841: LevelDB: Reading by PK prefix does not work
+#
+create table t31 (i int, j int, k int, primary key(i,j,k)) engine=LevelDB;
+insert into t31 values (1,10,100),(2,20,200);
+select * from t31 where i = 1;
+i	j	k
+1	10	100
+select * from t31 where j = 10;
+i	j	k
+1	10	100
+select * from t31 where k = 100;
+i	j	k
+1	10	100
+select * from t31 where i = 1 and j = 10;
+i	j	k
+1	10	100
+select * from t31 where i = 1 and k = 100;
+i	j	k
+1	10	100
+select * from t31 where j = 10 and k = 100;
+i	j	k
+1	10	100
+select * from t31 where i = 1 and j = 10 and k = 100;
+i	j	k
+1	10	100
+drop table t31;
+#
+# MDEV-4055: LevelDB: UPDATE/DELETE by a multi-part PK does not work
+#
+create table t32 (i int, j int, k int, primary key(i,j,k), a varchar(8)) engine=LevelDB;
+insert into t32 values 
+(1,10,100,''),
+(2,20,200,'');
+select * from t32 where i = 1 and j = 10 and k = 100;
+i	j	k	a
+1	10	100	
+update t32 set a = 'updated' where i = 1 and j = 10 and k = 100;
+select * from t32;
+i	j	k	a
+1	10	100	updated
+2	20	200	
+drop table t32;
+#
+# MDEV-3841: LevelDB: Assertion `0' fails in ha_leveldb::index_read_map on range select with ORDER BY .. DESC
+#
+CREATE TABLE t33 (pk INT PRIMARY KEY, a CHAR(1)) ENGINE=LevelDB;
+INSERT INTO t33 VALUES (1,'a'),(2,'b');
+SELECT * FROM t33 WHERE pk <= 10 ORDER BY pk DESC;
+pk	a
+2	b
+1	a
+DROP TABLE t33;
+#
+# MDEV-4081: LevelDB throws error 122 on an attempt to create a table with unique index
+#
+create table t33 (pk int primary key, u int, unique index(u)) engine=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+#
+# MDEV-4077: LevelDB: Wrong result (duplicate row) on select with range 
+#
+CREATE TABLE t34 (pk INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t34 VALUES (10),(11);
+SELECT pk FROM t34 WHERE pk > 5 AND pk < 15;
+pk
+10
+11
+SELECT pk FROM t34 WHERE pk BETWEEN 5 AND 15;
+pk
+10
+11
+SELECT pk FROM t34 WHERE pk > 5;
+pk
+10
+11
+SELECT pk FROM t34 WHERE pk < 15;
+pk
+10
+11
+drop table t34;
+#
+# MDEV-4086: LevelDB does not allow a query with multi-part pk and index and ORDER BY .. DEC
+#
+create table t35 (a int, b int, c int, d int, e int, primary key (a,b,c), key (a,c,d,e)) engine=LevelDB;
+insert into t35 values (1,1,1,1,1),(2,2,2,2,2);
+select * from t35 where a = 1 and c = 1 and d = 1 order by e desc;
+a	b	c	d	e
+1	1	1	1	1
+drop table t35;
+#
+# MDEV-4084: LevelDB: Wrong result on IN subquery with index
+#
+CREATE TABLE t36 (pk INT PRIMARY KEY, a INT, KEY(a)) ENGINE=LevelDB;
+INSERT INTO t36 VALUES (1,10),(2,20);
+SELECT 3 IN ( SELECT a FROM t36 );
+3 IN ( SELECT a FROM t36 )
+0
+drop table t36;
+#
+# MDEV-4084: LevelDB: Wrong result on IN subquery with index
+#
+CREATE TABLE t37 (pk INT PRIMARY KEY, a INT, b CHAR(1), KEY(a), KEY(a,b)) 
+ENGINE=LevelDB;
+INSERT INTO t37 VALUES (1,10,'x'), (2,20,'y');
+SELECT MAX(a) FROM t37 WHERE a < 100;
+MAX(a)
+20
+DROP TABLE t37;
+#
+# MDEV-4090: LevelDB: Wrong result (duplicate rows) on range access with secondary key and ORDER BY DESC
+#
+CREATE TABLE t38 (pk INT PRIMARY KEY, i INT, KEY(i)) ENGINE=LevelDB;
+INSERT INTO t38 VALUES (1,10), (2,20);
+SELECT i FROM t38 WHERE i NOT IN (8) ORDER BY i DESC;
+i
+20
+10
+drop table t38;
+#
+# MDEV-4092: LevelDB: Assertion `in_table(pa, a_len)' fails in LDBSE_KEYDEF::cmp_full_keys 
+#            with a multi-part key and ORDER BY .. DESC
+#
+CREATE TABLE t40 (pk1 INT PRIMARY KEY, a INT, b VARCHAR(1), KEY(b,a)) ENGINE=LevelDB;
+INSERT INTO t40 VALUES (1, 7,'x'),(2,8,'y');
+CREATE TABLE t41 (pk2 INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t41 VALUES (1),(2);
+SELECT * FROM t40, t41 WHERE pk1 = pk2 AND b = 'o' ORDER BY a DESC;
+pk1	a	b	pk2
+DROP TABLE t40,t41;
+#
+# MDEV-4093: LevelDB: IN subquery by secondary key with NULL among values returns true instead of NULL
+#
+CREATE TABLE t42 (pk INT PRIMARY KEY, a INT, KEY(a)) ENGINE=LevelDB;
+INSERT INTO t42 VALUES (1, NULL),(2, 8);
+SELECT ( 3 ) NOT IN ( SELECT a FROM t42 );
+( 3 ) NOT IN ( SELECT a FROM t42 )
+NULL
+DROP TABLE t42;
+#
+# MDEV-4094: LevelDB: Wrong result on SELECT and ER_KEY_NOT_FOUND on 
+#            DELETE with search by NULL-able secondary key ...
+#
+CREATE TABLE t43 (pk INT PRIMARY KEY, a INT, b CHAR(1), KEY(a)) ENGINE=LevelDB;
+INSERT INTO t43 VALUES (1,8,'g'),(2,9,'x');
+UPDATE t43 SET pk = 10 WHERE a = 8;
+REPLACE INTO t43 ( a ) VALUES ( 8 );
+Warnings:
+Warning	1364	Field 'pk' doesn't have a default value
+REPLACE INTO t43 ( b ) VALUES ( 'y' );
+Warnings:
+Warning	1364	Field 'pk' doesn't have a default value
+SELECT * FROM t43 WHERE a = 8;
+pk	a	b
+10	8	g
+DELETE FROM t43 WHERE a = 8;
+DROP TABLE t43;
+#
+# Basic AUTO_INCREMENT tests
+#
+create table t44(pk int primary key auto_increment, col1 varchar(12)) engine=leveldb;
+insert into t44 (col1) values ('row1');
+insert into t44 (col1) values ('row2');
+insert into t44 (col1) values ('row3');
+select * from t44;
+pk	col1
+1	row1
+2	row2
+3	row3
+drop table t44;
+#
+# ALTER TABLE tests
+#
+create table t45 (pk int primary key, col1 varchar(12)) engine=leveldb;
+insert into t45 values (1, 'row1');
+insert into t45 values (2, 'row2');
+alter table t45 rename t46;
+select * from t46;
+pk	col1
+1	row1
+2	row2
+drop table t46;
+drop table t45;
+ERROR 42S02: Unknown table 'test.t45'
+#
+# Check Bulk loading
+#
+show variables like 'leveldb%';
+Variable_name	Value
+leveldb_bulk_load	OFF
+leveldb_bulk_load_size	1000
+leveldb_lock_wait_timeout	1
+leveldb_max_row_locks	1073741824
+create table t47 (pk int primary key, col1 varchar(12)) engine=leveldb;
+insert into t47 values (1, 'row1');
+insert into t47 values (2, 'row2');
+set leveldb_bulk_load=1;
+insert into t47 values (1, 'row1-NEW'),(2, 'row2-NEW');
+set leveldb_bulk_load=0;
+select * from t47;
+pk	col1
+1	row1-NEW
+2	row2-NEW
+drop table t47;
+#
+# Fix TRUNCATE over empty table (transaction is committed when it wasn't
+# started)
+#
+create table t48(pk int primary key auto_increment, col1 varchar(12)) engine=leveldb;
+set autocommit=0;
+truncate table t48;
+set autocommit=1;
+drop table t48;
+#
+# MDEV-4059: LevelDB: query waiting for a lock cannot be killed until query timeout exceeded
+#
+create table t49 (pk int primary key, a int) engine=LevelDB;
+insert into t49 values (1,10),(2,20);
+begin;
+update t49 set a = 100 where pk = 1;
+connect  con1,localhost,root,,;
+set leveldb_lock_wait_timeout=5000;
+set @var1= to_seconds(now());
+update t49 set a = 1000 where pk = 1;
+connect  con2,localhost,root,,;
+kill query $con1_id;
+connection con1;
+ERROR 70100: Query execution was interrupted
+set @var2= to_seconds(now());
+select (@var2 - at var1) < 400;
+(@var2 - at var1) < 400
+1
+connection default;
+disconnect con1;
+commit;
+drop table t49;
+#
+# Index-only tests for INT-based columns
+#
+create table t1 (pk int primary key, key1 int, col1 int, key(key1)) engine=leveldb;
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (-5,-5,-5);
+# INT column uses index-only:
+explain
+select key1 from t1 where key1=2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ref	key1	key1	5	const	10	Using index
+select key1 from t1 where key1=2;
+key1
+2
+select key1 from t1 where key1=-5;
+key1
+-5
+drop table t1;
+create table t2 (pk int primary key, key1 int unsigned, col1 int, key(key1)) engine=leveldb;
+insert into t2 values (1,1,1), (2,2,2);
+# INT UNSIGNED column uses index-only:
+explain
+select key1 from t2 where key1=2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ref	key1	key1	5	const	10	Using index
+select key1 from t2 where key1=2;
+key1
+2
+drop table t2;
+create table t3 (pk bigint primary key, key1 bigint, col1 int, key(key1)) engine=leveldb;
+insert into t3 values (1,1,1), (2,2,2);
+# BIGINT uses index-only:
+explain 
+select key1 from t3 where key1=2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ref	key1	key1	9	const	10	Using index
+select key1 from t3 where key1=2;
+key1
+2
+drop table t3;
+#
+# Index-only reads for string columns
+#
+create table t1 (
+pk int primary key, 
+key1 char(10) character set binary,
+col1 int,
+key (key1)
+) engine=leveldb;
+insert into t1 values(1, 'one',11), (2,'two',22);
+explain 
+select key1 from t1 where key1='one';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ref	key1	key1	11	const	10	Using where; Using index
+# The following will produce no rows. This looks like a bug,
+#  but it is actually correct behavior. Binary strings are end-padded
+#  with \0 character (and not space).  Comparison does not ignore
+#   the tail of \0.
+select key1 from t1 where key1='one';
+key1
+explain
+select hex(key1) from t1 where key1='one\0\0\0\0\0\0\0';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ref	key1	key1	11	const	10	Using where; Using index
+select hex(key1) from t1 where key1='one\0\0\0\0\0\0\0';
+hex(key1)
+6F6E6500000000000000
+drop table t1;
+create table t2 (
+pk int primary key, 
+key1 char(10) collate latin1_bin,
+col1 int,
+key (key1)
+) engine=leveldb;
+insert into t2 values(1, 'one',11), (2,'two',22);
+explain 
+select key1 from t2 where key1='one';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ref	key1	key1	11	const	10	Using where; Using index
+select key1 from t2 where key1='one';
+key1
+one
+drop table t2;
+create table t3 (
+pk int primary key, 
+key1 char(10) collate utf8_bin,
+col1 int,
+key (key1)
+) engine=leveldb;
+insert into t3 values(1, 'one',11), (2,'two',22);
+explain 
+select key1 from t3 where key1='one';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	ref	key1	key1	31	const	10	Using where; Using index
+select key1 from t3 where key1='one';
+key1
+one
+drop table t3;
+# a VARCHAR column
+create table t4 (
+pk int primary key, 
+key1 varchar(10) collate latin1_bin, 
+key(key1)
+) engine=leveldb;
+insert into t4 values(1, 'one'), (2,'two'),(3,'threee'),(55,'fifty-five');
+explain 
+select key1 from t4 where key1='two';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t4	ref	key1	key1	13	const	10	Using where; Using index
+select key1 from t4 where key1='two';
+key1
+two
+select key1 from t4 where key1='fifty-five';
+key1
+fifty-five
+explain 
+select key1 from t4 where key1 between 's' and 'u';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t4	range	key1	key1	13	NULL	10	Using where; Using index
+select key1 from t4 where key1 between 's' and 'u';
+key1
+threee
+two
+drop table t4;
+# 
+# MDEV-4305: LevelDB: Assertion `((keypart_map + 1) & keypart_map) == 0' fails in calculate_key_len
+# 
+CREATE TABLE t1 (pk1 INT, pk2 CHAR(32), i INT, PRIMARY KEY(pk1,pk2), KEY(i)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,'test1',6),(2,'test2',8);
+SELECT * FROM t1 WHERE i != 3 OR  pk1 > 9;
+pk1	pk2	i
+1	test1	6
+2	test2	8
+DROP TABLE t1;
+# 
+# MDEV-4298: LevelDB: Assertion `thd->is_error() || kill_errno' fails in ha_rows filesort
+# 
+CREATE TABLE t1 (pk INT PRIMARY KEY, i INT, KEY(i)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1),(2,2);
+BEGIN;
+UPDATE t1 SET i = 100;
+connect  con1,localhost,root,,test;
+DELETE IGNORE FROM t1 ORDER BY i;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+disconnect con1;
+connection default;
+COMMIT;
+DROP TABLE t1;
+#
+# MDEV-4313: LevelDB: Server crashes in LDBSE_KEYDEF::setup on dropping the primary key column
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, i INT NOT NULL, KEY(i)) ENGINE=LevelDB;
+ALTER TABLE t1 DROP COLUMN `pk`;
+ERROR HY000: Got error 188 'Table must have a PRIMARY KEY' from LEVELDB
+DROP TABLE t1;
+#
+# MDEV-4324: LevelDB: Valgrind "Use of uninitialised value" warnings on inserting value into varchar field
+#  (testcase only)
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, c VARCHAR(4)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,'foo'), (2,'bar');
+DROP TABLE t1;
+#
+# MDEV-4304: LevelDB: Index-only scan by a field with utf8_bin collation returns garbage symbols
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, c1 CHAR(1), c2 CHAR(1), KEY(c1)) ENGINE=LevelDB CHARSET utf8 COLLATE utf8_bin;
+INSERT INTO t1 VALUES (1,'h','h');
+SELECT * FROM t1;
+pk	c1	c2
+1	h	h
+SELECT c1 FROM t1;
+c1
+h
+DROP TABLE t1;
+#
+# MDEV-4300: LevelDB: Server crashes in inline_mysql_mutex_lock on SELECT .. FOR UPDATE
+#
+CREATE TABLE t2 (pk INT PRIMARY KEY, i INT, KEY (i)) ENGINE=LevelDB;
+INSERT INTO t2 VALUES (1,4),(2,5);
+SELECT 1 FROM t2 WHERE i < 0 FOR UPDATE;
+1
+DROP TABLE t2;
+#
+# MDEV-4301: LevelDB: Assertion `pack_info != __null' fails in LDBSE_KEYDEF::unpack_record
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, i INT, c CHAR(1), KEY(c,i)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,4,'d'),(2,8,'e');
+SELECT MAX( pk ) FROM t1 WHERE i = 105 AND c = 'h';
+MAX( pk )
+NULL
+DROP TABLE t1;
+#
+# MDEV-4337: LevelDB: Inconsistent results comparing a char field with an int field
+#
+create table t1 (c char(1), i int, primary key(c), key(i)) engine=LevelDB;
+insert into t1 values ('2',2),('6',6);
+select * from t1 where c = i;
+c	i
+2	2
+6	6
+select * from t1 ignore index (i) where c = i;
+c	i
+2	2
+6	6
+drop table t1;
+#
+# Test statement rollback inside a transaction
+#
+create table t1 (pk varchar(12) primary key) engine=leveldb;
+insert into t1 values ('old-val1'),('old-val2');
+create table t2 (pk varchar(12) primary key) engine=leveldb;
+insert into t2 values ('new-val2'),('old-val1');
+begin;
+insert into t1 values ('new-val1');
+insert into t1 select * from t2;
+ERROR 23000: Duplicate entry 'old-val1' for key 'PRIMARY'
+commit;
+select * from t1;
+pk
+new-val1
+old-val1
+old-val2
+drop table t1, t2;
+#
+# MDEV-4383: LevelDB: Wrong result of DELETE .. ORDER BY .. LIMIT: 
+#   rows that should be deleted remain in the table
+#
+CREATE TABLE t2 (pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (pk) VALUES (NULL),(NULL);
+BEGIN;
+INSERT INTO t2 (pk) VALUES (NULL),(NULL);
+INSERT INTO t1 (pk) VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+SELECT * FROM t1 ORDER BY pk LIMIT 9;
+pk
+1
+2
+3
+4
+5
+6
+7
+8
+affected rows: 8
+DELETE FROM t1 ORDER BY pk LIMIT 9;
+affected rows: 8
+SELECT * FROM t1 ORDER BY pk LIMIT 9;
+pk
+affected rows: 0
+DROP TABLE t1,t2;
+#
+# MDEV-4374: LevelDB: Valgrind warnings 'Use of uninitialised value' on 
+#   inserting into a varchar column
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, a VARCHAR(32)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+DROP TABLE t1;
+#
+# MDEV-4061: LevelDB: Changes from an interrupted query are still applied
+#
+create table t1 (pk int primary key, a int) engine=LevelDB;
+insert into t1 values (1,10),(2,20);
+set autocommit = 1;
+update t1 set a = sleep(100) where pk = 1;
+connect  con1,localhost,root,,;
+kill query $con_id;
+connection default;
+ERROR 70100: Query execution was interrupted
+select * from t1;
+pk	a
+1	10
+2	20
+disconnect con1;
+drop table t1;
+#
+# MDEV-4099: LevelDB: Wrong results with index and range access after INSERT IGNORE or REPLACE
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, a SMALLINT, b INT, KEY (a)) ENGINE=LevelDB;
+INSERT IGNORE INTO t1 VALUES (1, 157, 0), (2, 1898, -504403), (1, -14659,  0);
+SELECT * FROM t1;
+pk	a	b
+1	157	0
+2	1898	-504403
+SELECT pk FROM t1;
+pk
+1
+2
+SELECT * FROM t1 WHERE a != 97;
+pk	a	b
+1	157	0
+2	1898	-504403
+DROP TABLE t1;
+#
+# Test @@leveldb_max_row_locks
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, a int) ENGINE=LevelDB;
+set @a=-1;
+insert into t1 select (@a:=@a+1), 1234 from information_schema.session_variables limit 100;
+set @tmp1= @@leveldb_max_row_locks;
+set leveldb_max_row_locks= 20;
+update t1 set a=a+10;
+ERROR HY000: Got error 189 'Number of locks held reached @@leveldb_max_row_locks' from LEVELDB
+DROP TABLE t1;
diff --git a/mysql-test/r/leveldb_qcache.result b/mysql-test/r/leveldb_qcache.result
new file mode 100644
index 0000000..1a52a46
--- /dev/null
+++ b/mysql-test/r/leveldb_qcache.result
@@ -0,0 +1,37 @@
+create table t1 (pk int primary key, c char(8)) engine=LevelDB;
+insert into t1 values (1,'new'),(2,'new');
+select * from t1;
+pk	c
+1	new
+2	new
+connect  con1,localhost,root,,;
+update t1 set c = 'updated';
+connection default;
+flush status;
+show status like 'Qcache_hits';
+Variable_name	Value
+Qcache_hits	0
+show global status like 'Qcache_hits';
+Variable_name	Value
+Qcache_hits	0
+select * from t1;
+pk	c
+1	updated
+2	updated
+select sql_no_cache * from t1;
+pk	c
+1	updated
+2	updated
+select * from t1 where pk = 1;
+pk	c
+1	updated
+show status like 'Qcache_hits';
+Variable_name	Value
+Qcache_hits	0
+show status like 'Qcache_not_cached';
+Variable_name	Value
+Qcache_not_cached	3
+show global status like 'Qcache_hits';
+Variable_name	Value
+Qcache_hits	0
+drop table t1;
diff --git a/mysql-test/suite/leveldb/1st.result b/mysql-test/suite/leveldb/1st.result
new file mode 100644
index 0000000..9ace765
--- /dev/null
+++ b/mysql-test/suite/leveldb/1st.result
@@ -0,0 +1,22 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=LevelDB;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL DEFAULT '0',
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	0	
+a	int(11)	YES		NULL	
+b	char(8)	YES		NULL	
+INSERT INTO t1 VALUES (1, 1,'a');
+INSERT INTO t1 (a,b) VALUES (2,'b');
+SELECT a,b FROM t1;
+a	b
+1	a
+2	b
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/1st.test b/mysql-test/suite/leveldb/1st.test
new file mode 100644
index 0000000..820d883
--- /dev/null
+++ b/mysql-test/suite/leveldb/1st.test
@@ -0,0 +1,34 @@
+# 
+# This test checks some very basic capabilities
+# which will be used in almost every other test,
+# and will not be checked through support* variables.
+# If this test does not pass, there is no point
+# at executing other ones.
+#
+# Minimal requirements:
+# - supported column types: INT, CHAR (default CHAR(8), INT(11));
+# - column attributes as declared in define_engine.inc ($default_col_opts)
+#     (by default empty, which means no additional attributes apart from the type);
+# - table attributes as declared in define_engine.inc ($default_tbl_opts)
+#     (by default empty, which means no additional attributes apart from ENGINE);
+# - CREATE TABLE .. (column1 <column options>, column2 <column options>) ENGINE=<storage_engine>;
+# - INSERT INTO TABLE .. VALUES (val1,val2);
+# - DROP TABLE ..
+# - SELECT a,b FROM ..
+# - SHOW CREATE TABLE ..
+# - SHOW COLUMNS IN ...
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (pk INT PRIMARY KEY DEFAULT '0', a INT(11), b CHAR(8)) ENGINE=LevelDB;
+SHOW CREATE TABLE t1;
+SHOW COLUMNS IN t1;
+INSERT INTO t1 VALUES (1, 1,'a');
+INSERT INTO t1 (a,b) VALUES (2,'b');
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/alter_table.result b/mysql-test/suite/leveldb/alter_table.result
new file mode 100644
index 0000000..fa05c99
--- /dev/null
+++ b/mysql-test/suite/leveldb/alter_table.result
@@ -0,0 +1,181 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, c CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1,'a'),(2,5,'z');
+ALTER TABLE t1 ADD COLUMN b INT;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `c` char(8) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 ALTER COLUMN a SET DEFAULT '0';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT '0',
+  `c` char(8) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 ALTER a DROP DEFAULT;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 CHANGE COLUMN b b1 CHAR(8) FIRST;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `b1` char(8) DEFAULT NULL,
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 CHANGE b1 b INT AFTER c;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 CHANGE b b CHAR(8);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY COLUMN b INT;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY COLUMN b CHAR(8) FIRST;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `b` char(8) DEFAULT NULL,
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY COLUMN b INT AFTER a;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `b` int(11) DEFAULT NULL,
+  `c` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 DROP COLUMN b;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 RENAME TO t2;
+SHOW CREATE TABLE t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `pk` int(11) NOT NULL,
+  `a` int(11),
+  `c` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b INT) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1,5),(2,2,2),(3,4,3);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 ORDER BY b ASC, a DESC, pk DESC;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `b` int(11) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+pk	a	b
+1	1	5
+2	2	2
+3	4	3
+DROP TABLE t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(8), c CHAR(8)) ENGINE=LevelDB CHARACTER SET latin1 COLLATE latin1_general_cs;
+INSERT INTO t1 VALUES (1,5,'z','t');
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) COLLATE latin1_general_cs DEFAULT NULL,
+  `c` char(8) COLLATE latin1_general_cs DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
+ALTER TABLE t1 CONVERT TO CHARACTER SET utf8;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) DEFAULT NULL,
+  `c` char(8) DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=utf8
+ALTER TABLE t1 DEFAULT CHARACTER SET = latin1 COLLATE latin1_general_ci;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) CHARACTER SET utf8 DEFAULT NULL,
+  `c` char(8) CHARACTER SET utf8 DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
+ALTER TABLE t1 FORCE;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) CHARACTER SET utf8 DEFAULT NULL,
+  `c` char(8) CHARACTER SET utf8 DEFAULT NULL,
+  PRIMARY KEY (`pk`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/alter_table.test b/mysql-test/suite/leveldb/alter_table.test
new file mode 100644
index 0000000..f00667b
--- /dev/null
+++ b/mysql-test/suite/leveldb/alter_table.test
@@ -0,0 +1,92 @@
+# 
+# Basic ALTER TABLE statements.
+#
+# USAGE of table options in ALTER statements
+#   is covered in tbl_standard_opts and tbl_opt*.tests.
+#
+# Index operations are covered in index* tests.
+#
+# ALTER OFFLINE is not covered as it is not supported, as of 5.5.23
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, c CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1,'a'),(2,5,'z');
+
+# Column operations
+
+ALTER TABLE t1 ADD COLUMN b INT;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 ALTER COLUMN a SET DEFAULT '0';
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 ALTER a DROP DEFAULT;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 CHANGE COLUMN b b1 CHAR(8) FIRST;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 CHANGE b1 b INT AFTER c;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 CHANGE b b CHAR(8);
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 MODIFY COLUMN b INT;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 MODIFY COLUMN b CHAR(8) FIRST;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 MODIFY COLUMN b INT AFTER a;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 DROP COLUMN b;
+SHOW CREATE TABLE t1;
+
+
+# Rename table
+
+ALTER TABLE t1 RENAME TO t2;
+--error ER_NO_SUCH_TABLE
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+
+# ORDER BY
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b INT) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1,5),(2,2,2),(3,4,3);
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 ORDER BY b ASC, a DESC, pk DESC;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+# Character set, collate
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT, b CHAR(8), c CHAR(8)) ENGINE=LevelDB CHARACTER SET latin1 COLLATE latin1_general_cs;
+INSERT INTO t1 VALUES (1,5,'z','t');
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 CONVERT TO CHARACTER SET utf8;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 DEFAULT CHARACTER SET = latin1 COLLATE latin1_general_ci;
+SHOW CREATE TABLE t1;
+
+
+# A 'null' ALTER operation
+
+ALTER TABLE t1 FORCE;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/analyze_table.result b/mysql-test/suite/leveldb/analyze_table.result
new file mode 100644
index 0000000..6094cd9
--- /dev/null
+++ b/mysql-test/suite/leveldb/analyze_table.result
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT(11), b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b');
+CREATE TABLE t2 (pk INT PRIMARY KEY, a INT(11), b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (3,3,'c');
+ANALYZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	note	The storage engine for the table doesn't support analyze
+INSERT INTO t2 VALUES (1,4,'d');
+ANALYZE NO_WRITE_TO_BINLOG TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	analyze	note	The storage engine for the table doesn't support analyze
+INSERT INTO t1 VALUES (4,5,'e');
+INSERT INTO t2 VALUES (2,6,'f');
+ANALYZE LOCAL TABLE t1, t2;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	note	The storage engine for the table doesn't support analyze
+test.t2	analyze	note	The storage engine for the table doesn't support analyze
+DROP TABLE t1, t2;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT(11), KEY(a)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1),(2,2),(3,4),(4,7);
+ANALYZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	note	The storage engine for the table doesn't support analyze
+INSERT INTO t1 VALUES (5,8),(6,10),(7,11),(8,12);
+ANALYZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	note	The storage engine for the table doesn't support analyze
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/analyze_table.test b/mysql-test/suite/leveldb/analyze_table.test
new file mode 100644
index 0000000..02861d5
--- /dev/null
+++ b/mysql-test/suite/leveldb/analyze_table.test
@@ -0,0 +1,29 @@
+# 
+# ANALYZE TABLE statements
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT(11), b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b');
+CREATE TABLE t2 (pk INT PRIMARY KEY, a INT(11), b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (3,3,'c');
+ANALYZE TABLE t1;
+INSERT INTO t2 VALUES (1,4,'d');
+ANALYZE NO_WRITE_TO_BINLOG TABLE t2;
+INSERT INTO t1 VALUES (4,5,'e');
+INSERT INTO t2 VALUES (2,6,'f');
+ANALYZE LOCAL TABLE t1, t2;
+
+DROP TABLE t1, t2;
+
+  --let $create_definition = a $int_indexed_col, $default_index(a)
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT(11), KEY(a)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1),(2,2),(3,4),(4,7);
+ANALYZE TABLE t1;
+INSERT INTO t1 VALUES (5,8),(6,10),(7,11),(8,12);
+ANALYZE TABLE t1;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/autoinc_secondary.result b/mysql-test/suite/leveldb/autoinc_secondary.result
new file mode 100644
index 0000000..cfdf42e
--- /dev/null
+++ b/mysql-test/suite/leveldb/autoinc_secondary.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT, b CHAR(8), PRIMARY KEY(a,b)) ENGINE=LevelDB;
+INSERT INTO t1 (b) VALUES ('a'),('b'),('b'),('c'),('a');
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+1
+SELECT a,b FROM t1;
+a	b
+1	a
+2	b
+3	b
+4	c
+5	a
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(8), b INT AUTO_INCREMENT, PRIMARY KEY (a,b), KEY(b)) ENGINE=LevelDB;
+ERROR HY000: Got error 122 from storage engine
diff --git a/mysql-test/suite/leveldb/autoinc_secondary.test b/mysql-test/suite/leveldb/autoinc_secondary.test
new file mode 100644
index 0000000..71822a0
--- /dev/null
+++ b/mysql-test/suite/leveldb/autoinc_secondary.test
@@ -0,0 +1,34 @@
+# 
+# AUTO_INCREMENT on a secondary column in a multi-part key
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# 
+# AUTO_INCREMENT is the primary column in a multiple-column index
+#
+
+CREATE TABLE t1 (a INT AUTO_INCREMENT, b CHAR(8), PRIMARY KEY(a,b)) ENGINE=LevelDB;
+INSERT INTO t1 (b) VALUES ('a'),('b'),('b'),('c'),('a');
+SELECT LAST_INSERT_ID();
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+
+# AUTO_INCREMENT is the secondary column in a multiple-column index,
+# and primary in another index
+#
+--error ER_GET_ERRNO
+CREATE TABLE t1 (a CHAR(8), b INT AUTO_INCREMENT, PRIMARY KEY (a,b), KEY(b)) ENGINE=LevelDB;
+--disable_parsing
+INSERT INTO t1 (a) VALUES ('a'),('b'),('b'),('c'),('a');
+SELECT LAST_INSERT_ID();
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+--enable_parsing
+
+
diff --git a/mysql-test/suite/leveldb/autoinc_vars.result b/mysql-test/suite/leveldb/autoinc_vars.result
new file mode 100644
index 0000000..bea0c2e
--- /dev/null
+++ b/mysql-test/suite/leveldb/autoinc_vars.result
@@ -0,0 +1,64 @@
+DROP TABLE IF EXISTS t1;
+#---------------------------
+# auto_increment_offset
+#---------------------------
+SET auto_increment_offset = 200;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (NULL,'a'),(NULL,'b'),(NULL,'c');
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+1
+SELECT a,b FROM t1 ORDER BY a;
+a	b
+1	a
+2	b
+3	c
+#---------------------------
+# auto_increment_increment
+#---------------------------
+SET auto_increment_increment = 300;
+INSERT INTO t1 (a,b) VALUES (NULL,'d'),(NULL,'e'),(NULL,'f');
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+200
+SELECT a,b FROM t1 ORDER BY a;
+a	b
+1	a
+2	b
+3	c
+200	d
+500	e
+800	f
+SET auto_increment_increment = 50;
+INSERT INTO t1 (a,b) VALUES (NULL,'g'),(NULL,'h'),(NULL,'i');
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+34
+SELECT a,b FROM t1 ORDER BY a;
+a	b
+1	a
+2	b
+3	c
+34	g
+84	h
+134	i
+200	d
+500	e
+800	f
+DROP TABLE t1;
+#---------------------------
+# offset is greater than the max value
+#---------------------------
+SET auto_increment_increment = 500;
+SET auto_increment_offset = 300;
+CREATE TABLE t1 (a TINYINT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a) VALUES (NULL);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT LAST_INSERT_ID();
+LAST_INSERT_ID()
+127
+SELECT a FROM t1 ORDER BY a;
+a
+127
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/autoinc_vars.test b/mysql-test/suite/leveldb/autoinc_vars.test
new file mode 100644
index 0000000..96b33fc
--- /dev/null
+++ b/mysql-test/suite/leveldb/autoinc_vars.test
@@ -0,0 +1,63 @@
+# 
+# auto-increment-offset and auto-increment-increment
+#
+
+############################################
+# TODO:
+# This test currently produces wrong result 
+# on the line 36 of the result file and further
+# due to bug MySQL:47118. 
+# When/if the bug is fixed, 
+# the result will need to be updated
+############################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #---------------------------
+--echo # auto_increment_offset
+--echo #---------------------------
+SET auto_increment_offset = 200;
+
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+
+# If auto_increment_offset is greater than auto_increment_increment,
+# the offset is ignored
+
+INSERT INTO t1 (a,b) VALUES (NULL,'a'),(NULL,'b'),(NULL,'c');
+SELECT LAST_INSERT_ID();
+SELECT a,b FROM t1 ORDER BY a;
+
+--echo #---------------------------
+--echo # auto_increment_increment
+--echo #---------------------------
+
+SET auto_increment_increment = 300;
+# offset should not be ignored anymore
+
+INSERT INTO t1 (a,b) VALUES (NULL,'d'),(NULL,'e'),(NULL,'f');
+SELECT LAST_INSERT_ID();
+SELECT a,b FROM t1 ORDER BY a;
+
+SET auto_increment_increment = 50;
+INSERT INTO t1 (a,b) VALUES (NULL,'g'),(NULL,'h'),(NULL,'i');
+SELECT LAST_INSERT_ID();
+SELECT a,b FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+
+--echo #---------------------------
+--echo # offset is greater than the max value
+--echo #---------------------------
+
+SET auto_increment_increment = 500;
+SET auto_increment_offset = 300;
+
+CREATE TABLE t1 (a TINYINT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a) VALUES (NULL);
+SELECT LAST_INSERT_ID();
+SELECT a FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/autoincrement.result b/mysql-test/suite/leveldb/autoincrement.result
new file mode 100644
index 0000000..7bfda79
--- /dev/null
+++ b/mysql-test/suite/leveldb/autoincrement.result
@@ -0,0 +1,5 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT AUTO_INCREMENT, b CHAR(8), KEY(a)) ENGINE=LevelDB;
+ERROR HY000: Got error 122 from storage engine
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT AUTO_INCREMENT, b CHAR(8), KEY(a)) ENGINE=LevelDB AUTO_INCREMENT=100;
+ERROR HY000: Got error 122 from storage engine
diff --git a/mysql-test/suite/leveldb/autoincrement.test b/mysql-test/suite/leveldb/autoincrement.test
new file mode 100644
index 0000000..03fb2a8
--- /dev/null
+++ b/mysql-test/suite/leveldb/autoincrement.test
@@ -0,0 +1,125 @@
+# 
+# Basic AUTO_INCREMENT capabilities
+#
+############################################
+# TODO:
+# This test currently produces wrong result 
+# due to bugs MDEV-4196, MDEV-4197.
+# When the bugs are fixed, 
+# the result will need to be updated
+############################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--error ER_GET_ERRNO
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT AUTO_INCREMENT, b CHAR(8), KEY(a)) ENGINE=LevelDB;
+--disable_parsing
+SHOW CREATE TABLE t1;
+
+# Automatic values
+
+INSERT INTO t1 (pk,b) VALUES (1,'a'),(2,'b');
+SELECT a,b FROM t1 ORDER BY a;
+SELECT LAST_INSERT_ID();
+
+INSERT INTO t1 (pk,a,b) VALUES (3,NULL,'c'),(4,0,'d');
+SELECT a,b FROM t1 ORDER BY a;
+SELECT LAST_INSERT_ID();
+
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+let $sql_mode = `SELECT @@sql_mode`;
+SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
+
+INSERT INTO t1 (pk,a,b) VALUES (5,NULL,'e');
+SELECT a,b FROM t1 ORDER BY a;
+SELECT LAST_INSERT_ID();
+
+INSERT INTO t1 (pk,a,b) VALUES (6,0,'f');
+SELECT a,b FROM t1 ORDER BY a;
+SELECT LAST_INSERT_ID();
+
+--replace_result $sql_mode <INITIAL_SQL_MODE>
+eval SET sql_mode = '$sql_mode';
+
+
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+INSERT INTO t1 (pk,a,b) VALUES (7,6,'g'),(8,7,'h');
+
+SELECT LAST_INSERT_ID();
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+
+# Mix of automatic and explicit values
+
+INSERT INTO t1 (pk,a,b) VALUES (9,NULL,'i'),(10,9,'j');
+SELECT a,b FROM t1 ORDER BY a;
+
+SELECT LAST_INSERT_ID();
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+
+# Creating a gap in the sequence
+
+INSERT INTO t1 (pk,a,b) VALUES (11,20,'k');
+
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+INSERT INTO t1 (pk,a,b) VALUES (12,NULL,'l');
+SELECT a,b FROM t1 ORDER BY a;
+
+SELECT LAST_INSERT_ID();
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+
+# Negative values: we will try to insert one just to check that it does not cause a crash
+# although we don't care so much about what happens to the sequence after that, 
+# since the behavior is undefined
+
+INSERT INTO t1 (pk,a,b) VALUES (13,-5,'m');
+SELECT a,b FROM t1 ORDER BY a;
+
+SELECT LAST_INSERT_ID();
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+INSERT INTO t1 (pk,a,b) VALUES (14,NULL,'n');
+
+SELECT LAST_INSERT_ID();
+SHOW CREATE TABLE t1;
+--replace_column 12 #
+query_vertical SHOW TABLE STATUS FROM test LIKE 't1';
+
+DROP TABLE t1;
+--enable_parsing
+
+
+# Autoincrement with table option AUTO_INCREMENT
+
+--error ER_GET_ERRNO
+CREATE TABLE t1 (pk INT PRIMARY KEY, a INT AUTO_INCREMENT, b CHAR(8), KEY(a)) ENGINE=LevelDB AUTO_INCREMENT=100;
+--disable_parsing
+INSERT INTO t1 (pk,a,b) VALUES (1,NULL,'a'),(2,NULL,'b');
+--sorted_result
+SELECT a,b FROM t1;
+SELECT LAST_INSERT_ID();
+
+DROP TABLE t1;
+--enable_parsing
+
diff --git a/mysql-test/suite/leveldb/check_table.inc b/mysql-test/suite/leveldb/check_table.inc
new file mode 100644
index 0000000..b924c57
--- /dev/null
+++ b/mysql-test/suite/leveldb/check_table.inc
@@ -0,0 +1,54 @@
+# 
+# CHECK TABLE statements
+#
+# Note: the output is likely to be different for the engine under test,
+# in which case rdiff will be needed. Or, the output might say that
+# the storage engine does not support CHECK.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+CHECK TABLE t1;
+INSERT INTO t1 (a,b) VALUES (3,'c');
+INSERT INTO t2 (a,b) VALUES (4,'d');
+CHECK TABLE t1, t2 FOR UPGRADE;
+INSERT INTO t2 (a,b) VALUES (5,'e');
+CHECK TABLE t2 QUICK;
+INSERT INTO t1 (a,b) VALUES (6,'f');
+CHECK TABLE t1 FAST;
+INSERT INTO t1 (a,b) VALUES (7,'g');
+INSERT INTO t2 (a,b) VALUES (8,'h');
+CHECK TABLE t2, t1 MEDIUM;
+INSERT INTO t1 (a,b) VALUES (9,'i');
+INSERT INTO t2 (a,b) VALUES (10,'j');
+CHECK TABLE t1, t2 EXTENDED;
+INSERT INTO t1 (a,b) VALUES (11,'k');
+CHECK TABLE t1 CHANGED;
+
+DROP TABLE t1, t2;
+
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, KEY(a)) ENGINE=LevelDB;
+INSERT INTO t1 (a) VALUES (1),(2),(5);
+CHECK TABLE t1;
+INSERT INTO t1 (a) VALUES (6),(8),(12);
+CHECK TABLE t1 FOR UPGRADE;
+INSERT INTO t1 (a) VALUES (13),(15),(16);
+CHECK TABLE t1 QUICK;
+INSERT INTO t1 (a) VALUES (17),(120),(132);
+CHECK TABLE t1 FAST;
+INSERT INTO t1 (a) VALUES (801),(900),(7714);
+CHECK TABLE t1 MEDIUM;
+INSERT INTO t1 (a) VALUES (8760),(10023),(12000);
+CHECK TABLE t1 EXTENDED;
+INSERT INTO t1 (a) VALUES (13345),(24456),(78302),(143028);
+CHECK TABLE t1 CHANGED;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/check_table.result b/mysql-test/suite/leveldb/check_table.result
new file mode 100644
index 0000000..fedadba
--- /dev/null
+++ b/mysql-test/suite/leveldb/check_table.result
@@ -0,0 +1,68 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a,b) VALUES (3,'c');
+INSERT INTO t2 (a,b) VALUES (4,'d');
+CHECK TABLE t1, t2 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+test.t2	check	status	OK
+INSERT INTO t2 (a,b) VALUES (5,'e');
+CHECK TABLE t2 QUICK;
+Table	Op	Msg_type	Msg_text
+test.t2	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a,b) VALUES (6,'f');
+CHECK TABLE t1 FAST;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a,b) VALUES (7,'g');
+INSERT INTO t2 (a,b) VALUES (8,'h');
+CHECK TABLE t2, t1 MEDIUM;
+Table	Op	Msg_type	Msg_text
+test.t2	check	note	The storage engine for the table doesn't support check
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a,b) VALUES (9,'i');
+INSERT INTO t2 (a,b) VALUES (10,'j');
+CHECK TABLE t1, t2 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+test.t2	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a,b) VALUES (11,'k');
+CHECK TABLE t1 CHANGED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, KEY(a)) ENGINE=LevelDB;
+INSERT INTO t1 (a) VALUES (1),(2),(5);
+CHECK TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a) VALUES (6),(8),(12);
+CHECK TABLE t1 FOR UPGRADE;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+INSERT INTO t1 (a) VALUES (13),(15),(16);
+CHECK TABLE t1 QUICK;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a) VALUES (17),(120),(132);
+CHECK TABLE t1 FAST;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a) VALUES (801),(900),(7714);
+CHECK TABLE t1 MEDIUM;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a) VALUES (8760),(10023),(12000);
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+INSERT INTO t1 (a) VALUES (13345),(24456),(78302),(143028);
+CHECK TABLE t1 CHANGED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	note	The storage engine for the table doesn't support check
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/check_table.test b/mysql-test/suite/leveldb/check_table.test
new file mode 100644
index 0000000..8065e4e
--- /dev/null
+++ b/mysql-test/suite/leveldb/check_table.test
@@ -0,0 +1,10 @@
+# 
+# CHECK TABLE statements
+#
+# Note: the output is likely to be different for the engine under test,
+# in which case rdiff will be needed. Or, the output might say that
+# the storage engine does not support CHECK.
+#
+
+--source check_table.inc
+
diff --git a/mysql-test/suite/leveldb/checksum_table.result b/mysql-test/suite/leveldb/checksum_table.result
new file mode 100644
index 0000000..f2bebf5
--- /dev/null
+++ b/mysql-test/suite/leveldb/checksum_table.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=0;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=0;
+CHECKSUM TABLE t1;
+Table	Checksum
+test.t1	4259194219
+CHECKSUM TABLE t2, t1;
+Table	Checksum
+test.t2	0
+test.t1	4259194219
+CHECKSUM TABLE t1, t2 QUICK;
+Table	Checksum
+test.t1	NULL
+test.t2	NULL
+CHECKSUM TABLE t1, t2 EXTENDED;
+Table	Checksum
+test.t1	4259194219
+test.t2	0
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/checksum_table.test b/mysql-test/suite/leveldb/checksum_table.test
new file mode 100644
index 0000000..7d98c6d
--- /dev/null
+++ b/mysql-test/suite/leveldb/checksum_table.test
@@ -0,0 +1,22 @@
+# 
+# CHECKSUM TABLE statements for standard CHECKSUM properties.
+# Live checksums are covered in checksum_table_live.test
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=0;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+
+CREATE TABLE t2 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=0;
+
+CHECKSUM TABLE t1; 
+CHECKSUM TABLE t2, t1;
+CHECKSUM TABLE t1, t2 QUICK;
+CHECKSUM TABLE t1, t2 EXTENDED;
+
+DROP TABLE t1, t2;
+
+
diff --git a/mysql-test/suite/leveldb/checksum_table_live.result b/mysql-test/suite/leveldb/checksum_table_live.result
new file mode 100644
index 0000000..3fe4562
--- /dev/null
+++ b/mysql-test/suite/leveldb/checksum_table_live.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=1;
+CHECKSUM TABLE t1;
+Table	Checksum
+test.t1	4259194219
+CHECKSUM TABLE t2, t1;
+Table	Checksum
+test.t2	0
+test.t1	4259194219
+CHECKSUM TABLE t1, t2 QUICK;
+Table	Checksum
+test.t1	NULL
+test.t2	NULL
+CHECKSUM TABLE t1, t2 EXTENDED;
+Table	Checksum
+test.t1	4259194219
+test.t2	0
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/checksum_table_live.test b/mysql-test/suite/leveldb/checksum_table_live.test
new file mode 100644
index 0000000..70d8779
--- /dev/null
+++ b/mysql-test/suite/leveldb/checksum_table_live.test
@@ -0,0 +1,22 @@
+# 
+# CHECKSUM TABLE statements for live CHECKSUM.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+# For most engines CHECKSUM=1 option will be ignored,
+# and the results will be different
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=1;
+
+CHECKSUM TABLE t1; 
+CHECKSUM TABLE t2, t1;
+CHECKSUM TABLE t1, t2 QUICK;
+CHECKSUM TABLE t1, t2 EXTENDED;
+
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/col_not_null.inc b/mysql-test/suite/leveldb/col_not_null.inc
new file mode 100644
index 0000000..49eea46
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_not_null.inc
@@ -0,0 +1,55 @@
+#
+# NOT NULL attribute in columns
+#
+# Usage:
+# let $col_type = <column type>;
+# let $col_default = <default value for a column>;
+# --source col_not_null.inc
+#
+# We will add NOT NULL to the column options;
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #----------------------------------
+--echo # $col_type NOT NULL columns without a default
+--echo #----------------------------------
+
+eval CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c $col_type NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 (c) VALUES (NULL);
+eval INSERT INTO t1 (c) VALUES ($col_default);
+SELECT HEX(c) FROM t1;
+
+DROP TABLE t1;
+
+--echo #----------------------------------
+--echo # $col_type NOT NULL columns with a default
+--echo #----------------------------------
+
+eval CREATE TABLE t1 (
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  c $col_type NOT NULL DEFAULT $col_default
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+--error ER_INVALID_DEFAULT
+eval ALTER TABLE t1 ADD COLUMN err $col_type NOT NULL DEFAULT NULL;
+
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 (c) VALUES (NULL);
+
+eval INSERT INTO t1 (c) VALUES ($col_default);
+eval INSERT INTO t1 () VALUES ();
+
+# HEX should be universal for all column types
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/col_not_null_timestamp.inc b/mysql-test/suite/leveldb/col_not_null_timestamp.inc
new file mode 100644
index 0000000..f18be14
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_not_null_timestamp.inc
@@ -0,0 +1,61 @@
+#
+# NOT NULL attribute in TIMESTAMP columns
+#
+# This is a copy of col_not_null.inc, except that 
+# instead of getting an error on inserting NULL into a non-NULL column,
+# we are getting the current timestamp (see MySQL:68472).
+# If the bug is ever fixed, this include file won't be needed anymore.
+
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #----------------------------------
+--echo # $col_type NOT NULL column without a default
+--echo #----------------------------------
+
+eval CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c $col_type NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+
+# Here where the non-standard behavior strikes: 
+# instead of an error we are getting the current timestamp
+
+# As of mysql-5.6.11, this no longer works, and we get an error:
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 (c) VALUES (NULL);
+eval INSERT INTO t1 (c) VALUES ($col_default);
+SELECT HEX(c) FROM t1;
+
+DROP TABLE t1;
+
+--echo #----------------------------------
+--echo # $col_type NOT NULL columns with a default
+--echo #----------------------------------
+
+eval CREATE TABLE t1 (
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  c $col_type NOT NULL DEFAULT $col_default
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+--error ER_INVALID_DEFAULT
+eval ALTER TABLE t1 ADD COLUMN err $col_type NOT NULL DEFAULT NULL;
+
+# Here where the non-standard behavior strikes: 
+# instead of an error we are getting the current timestamp
+
+# As of mysql-5.6.11, this no longer works, and we get an error:
+--error ER_BAD_NULL_ERROR
+INSERT INTO t1 (c) VALUES (NULL);
+
+eval INSERT INTO t1 (c) VALUES ($col_default);
+eval INSERT INTO t1 () VALUES ();
+
+# HEX should be universal for all column types
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/col_null.inc b/mysql-test/suite/leveldb/col_null.inc
new file mode 100644
index 0000000..5723ff8
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_null.inc
@@ -0,0 +1,33 @@
+#
+# NULL attribute and DEFAULT NULL in columns
+#
+# Usage:
+# let $col_type = <column type>;
+# let $col_default = <default non-null value for a column>;
+# --source col_null.inc
+#
+# We will add NULL attribute to the column options.
+#
+
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  c $col_type NULL,
+  c1 $col_type NULL DEFAULT NULL,
+  c2 $col_type NULL DEFAULT $col_default,
+  pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+eval INSERT INTO t1 (c,c1,c2) VALUES ($col_default,$col_default,$col_default);
+INSERT INTO t1 () VALUES ();
+
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/col_opt_default.result b/mysql-test/suite/leveldb/col_opt_default.result
new file mode 100644
index 0000000..dca522f
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_default.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY DEFAULT '0') ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	NO	PRI	0	
+INSERT INTO t1 (a) VALUES (1);
+SELECT a FROM t1;
+a
+1
+ALTER TABLE t1 ADD COLUMN b CHAR(8) DEFAULT '';
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	NO	PRI	0	
+b	char(8)	YES			
+INSERT INTO t1 (b) VALUES ('a');
+SELECT a,b FROM t1 ORDER BY a,b;
+a	b
+0	a
+1	
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/col_opt_default.test b/mysql-test/suite/leveldb/col_opt_default.test
new file mode 100644
index 0000000..01fd96b
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_default.test
@@ -0,0 +1,25 @@
+# 
+# Check whether DEFAULT column attribute 
+# is supported in CREATE and ALTER TABLE.
+# If the attribute is supported at all, it will be covered
+# in more details in col_option_null and col_option_not_null tests.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY DEFAULT '0') ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a) VALUES (1);
+SELECT a FROM t1;
+
+ALTER TABLE t1 ADD COLUMN b CHAR(8) DEFAULT '';
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (b) VALUES ('a');
+SELECT a,b FROM t1 ORDER BY a,b;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/col_opt_not_null.result b/mysql-test/suite/leveldb/col_opt_not_null.result
new file mode 100644
index 0000000..8711ce7
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_not_null.result
@@ -0,0 +1,2612 @@
+########################
+# BINARY columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+b BINARY NOT NULL,
+b0 BINARY(0) NOT NULL,
+b1 BINARY(1) NOT NULL,
+b20 BINARY(20) NOT NULL,
+b255 BINARY(255) NOT NULL,
+pk BINARY PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+b	binary(1)	NO		NULL	
+b0	binary(0)	NO		NULL	
+b1	binary(1)	NO		NULL	
+b20	binary(20)	NO		NULL	
+b255	binary(255)	NO		NULL	
+pk	binary(1)	NO	PRI	NULL	
+INSERT INTO t1 VALUES ('','','','','','');
+INSERT INTO t1 VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.','a');
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+HEX(b)	HEX(b0)	HEX(b1)	HEX(b20)	HEX(b255)	HEX(pk)
+00		00	0000000000000000000000000000000000000000	000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000	00
+61		62	616263646566676869206B6C6D6E6F7071727374	4372656174696E6720616E2061727469636C6520666F7220746865204B6E6F776C65646765626173652069732073696D696C617220746F2061736B696E67207175657374696F6E732E2046697273742C206E6176696761746520746F207468652063617465676F727920776865726520796F75206665656C207468652061727469636C652073686F756C642062652E204F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C726561647920657869737420776869636820776F756C6420776F726B2E00000000000000000000000000000000000000000000000000000000000000	61
+INSERT INTO t1 VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256),'b');
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b0' at row 1
+Warning	1265	Data truncated for column 'b1' at row 1
+Warning	1265	Data truncated for column 'b20' at row 1
+Warning	1265	Data truncated for column 'b255' at row 1
+INSERT INTO t1 SELECT b255, b255, b255, b255, CONCAT('a',b255,b255), 'c' FROM t1;
+ERROR 23000: Duplicate entry 'c' for key 'PRIMARY'
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+HEX(b)	HEX(b0)	HEX(b1)	HEX(b20)	HEX(b255)	HEX(pk)
+00		00	0000000000000000000000000000000000000000	000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000	00
+61		61	6161616161616161616161616161616161616161	787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878	62
+61		62	616263646566676869206B6C6D6E6F7071727374	4372656174696E6720616E2061727469636C6520666F7220746865204B6E6F776C65646765626173652069732073696D696C617220746F2061736B696E67207175657374696F6E732E2046697273742C206E6176696761746520746F207468652063617465676F727920776865726520796F75206665656C207468652061727469636C652073686F756C642062652E204F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C726561647920657869737420776869636820776F756C6420776F726B2E00000000000000000000000000000000000000000000000000000000000000	61
+ALTER TABLE t1 ADD COLUMN b257 BINARY(257) NOT NULL;
+ERROR 42000: Column length too big for column 'b257' (max = 255); use BLOB or TEXT instead
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+b	binary(1)	NO		NULL	
+b0	binary(0)	NO		NULL	
+b1	binary(1)	NO		NULL	
+b20	binary(20)	NO		NULL	
+b255	binary(255)	NO		NULL	
+pk	binary(1)	NO	PRI	NULL	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# BINARY NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c BINARY NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	binary(1)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+SELECT HEX(c) FROM t1;
+HEX(c)
+30
+DROP TABLE t1;
+#----------------------------------
+# BINARY NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c BINARY NOT NULL DEFAULT 0
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	binary(1)	NO		0	
+ALTER TABLE t1 ADD COLUMN err BINARY NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	30
+2	30
+DROP TABLE t1;
+########################
+# VARBINARY columns
+########################
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+v0 VARBINARY(0) NOT NULL,
+v1 VARBINARY(1) NOT NULL,
+v64 VARBINARY(64) NOT NULL,
+v65000 VARBINARY(65000) NOT NULL,
+PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varbinary(0)	NO		NULL	
+v1	varbinary(1)	NO		NULL	
+v64	varbinary(64)	NO	PRI	NULL	
+v65000	varbinary(65000)	NO		NULL	
+CREATE TABLE t2 (v VARBINARY(65532) NOT NULL, PRIMARY KEY(v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+Field	Type	Null	Key	Default	Extra
+v	varbinary(65532)	NO	PRI	NULL	
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+SELECT HEX(v0), HEX(v1), HEX(v64), HEX(v65000) FROM t1;
+HEX(v0)	HEX(v1)	HEX(v64)	HEX(v65000)
+			
+	79	4F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C7265616479206578697374	486572652069732061206C697374206F66207265636F6D6D656E64656420626F6F6B73206F6E204D61726961444220616E64204D7953514C2E2057652776652070726F7669646564206C696E6B7320746F20416D617A6F6E2E636F6D206865726520666F7220636F6E76656E69656E63652C2062757420746865792063616E20626520666F756E64206174206D616E79206F7468657220626F6F6B73746F7265732C20626F7468206F6E6C696E6520616E64206F66662E0A0A2020496620796F752077616E7420746F206861766520796F7572206661766F72697465204D7953514C202F204D61726961444220626F6F6B206C697374656420686572652C20706C65617365206C65617665206120636F6D6D656E742E0A2020466F7220646576656C6F706572732077686F2077616E7420746F20636F6465206F6E204D617269614442206F72204D7953514C0A0A2020202020202A20556E6465727374616E64696E67204D7953514C20496E7465726E616C73206279205361736861205061636865762C20666F726D6572204D7953514C20646576656C6F706572206174204D7953514C2041422E0A2020202020
 20202020
 2020206F205468697320697320746865206F6E6C7920626F6F6B207765206B6E6F772061626F75742074686174206465736372696265732074686520696E7465726E616C73206F66204D617269614442202F204D7953514C2E2041206D757374206861766520666F7220616E796F6E652077686F2077616E747320746F20756E6465727374616E6420616E6420646576656C6F70206F6E204D617269614442210A2020202020202020202020206F204E6F7420616C6C20746F706963732061726520636F766572656420616E6420736F6D652070617274732061726520736C696768746C79206F757464617465642C20627574207374696C6C20746865206265737420626F6F6B206F6E207468697320746F7069632E200A2020202020202A204D7953514C20352E3120506C7567696E20446576656C6F706D656E742062792053657267656920476F6C75626368696B20616E6420416E64726577204875746368696E67730A2020202020202020202020206F2041206D757374207265616420666F7220616E796F6E652077616E74696E6720746F207772697465206120706C7567696E20666F72204D6172696144422C207772697474656E20627920746865205365726765692077686F2064657369676E65642074686520706C7567696E20696E7465726661636520666F72204
 D7953514
 C20616E64204D61726961444221200A0A2020466F72204D617269614442202F204D7953514C20656E642075736572730A0A2020202020202A204D61726961444220437261736820436F757273652062792042656E20466F7274610A2020202020202020202020206F204669727374204D61726961444220626F6F6B210A2020202020202020202020206F20466F722070656F706C652077686F2077616E7420746F206C6561726E2053514C20616E642074686520626173696373206F66204D6172696144422E0A2020202020202020202020206F204E6F77207368697070696E672E20507572636861736520617420416D617A6F6E2E636F6D206F7220796F7572206661766F7269746520626F6F6B73656C6C65722E200A0A2020202020202A2053514C2D393920436F6D706C6574652C205265616C6C792062792050657465722047756C75747A616E20262054727564792050656C7A65722E0A2020202020202020202020206F2045766572797468696E6720796F752077616E74656420746F206B6E6F772061626F7574207468652053514C203939207374616E646172642E20457863656C6C656E74207265666572656E636520626F6F6B210A2020202020202020202020206F204672656520746F207265616420696E20746865204B6E6F776C656467656261736521200A
 0A202020
 2020202A204D7953514C20283474682045646974696F6E29206279205061756C204475426F69730A2020202020202020202020206F20546865202764656661756C742720626F6F6B20746F207265616420696620796F7520776F6E7420746F206C6561726E20746F20757365204D7953514C202F204D6172696144422E200A0A2020202020202A204D7953514C20436F6F6B626F6F6B206279205061756C204475426F69730A2020202020202020202020206F2041206C6F74206F66206578616D706C6573206F6620686F7720746F20757365204D7953514C2E204173207769746820616C6C206F66205061756C277320626F6F6B732C206974277320776F727468206974732077656967687420696E20676F6C6420616E64206576656E20656E6A6F7961626C652072656164696E6720666F7220737563682061202764727927207375626A6563742E200A0A2020202020202A204869676820506572666F726D616E6365204D7953514C2C205365636F6E642045646974696F6E2C204279204261726F6E20536368776172747A2C205065746572205A6169747365762C20566164696D20546B616368656E6B6F2C204A6572656D7920442E205A61776F646E792C2041726A656E204C656E747A2C20446572656B204A2E2042616C6C696E672C20657420616C2E0A20202020202
 02020202
 020206F20224869676820506572666F726D616E6365204D7953514C2069732074686520646566696E697469766520677569646520746F206275696C64696E6720666173742C2072656C6961626C652073797374656D732077697468204D7953514C2E205772697474656E206279206E6F74656420657870657274732077697468207965617273206F66207265616C2D776F726C6420657870657269656E6365206275696C64696E672076657279206C617267652073797374656D732C207468697320626F6F6B20636F7665727320657665727920617370656374206F66204D7953514C20706572666F726D616E636520696E2064657461696C2C20616E6420666F6375736573206F6E20726F627573746E6573732C2073656375726974792C20616E64206461746120696E746567726974792E204C6561726E20616476616E63656420746563686E697175657320696E20646570746820736F20796F752063616E206272696E67206F7574204D7953514C27732066756C6C20706F7765722E22202846726F6D2074686520626F6F6B206465736372697074696F6E206174204F275265696C6C7929200A0A2020202020202A204D7953514C2041646D696E20436F6F6B626F6F6B0A2020202020202020202020206F204120717569636B20737465702D62792D7374657020677569
 64652066
 6F72204D7953514C20757365727320616E642064617461626173652061646D696E6973747261746F727320746F207461636B6C65207265616C2D776F726C64206368616C6C656E6765732077697468204D7953514C20636F6E66696775726174696F6E20616E642061646D696E697374726174696F6E200A0A2020202020202A204D7953514C20352E302043657274696669636174696F6E2053747564792047756964652C204279205061756C204475426F69732C2053746566616E2048696E7A2C204361727374656E20506564657273656E0A2020202020202020202020206F205468697320697320746865206F6666696369616C20677569646520746F20636F766572207468652070617373696E67206F66207468652074776F204D7953514C2043657274696669636174696F6E206578616D696E6174696F6E732E2049742069732076616C69642074696C6C2076657273696F6E20352E30206F6620746865207365727665722C20736F207768696C65206974206D697373657320616C6C2074686520666561747572657320617661696C61626C6520696E204D7953514C20352E3120616E6420677265617465722028696E636C7564696E67204D61726961444220352E3120616E642067726561746572292C2069742070726F7669646573206120676F6F6420626173696
 320756E6
 465727374616E64696E67206F66204D7953514C20666F722074686520656E642D757365722E20
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 1
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'v64' at row 1
+Warning	1265	Data truncated for column 'v65000' at row 1
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 5
+Warning	1265	Data truncated for column 'v1' at row 5
+Warning	1265	Data truncated for column 'v64' at row 5
+Warning	1265	Data truncated for column 'v0' at row 6
+Warning	1265	Data truncated for column 'v1' at row 6
+Warning	1265	Data truncated for column 'v64' at row 6
+Warning	1265	Data truncated for column 'v65000' at row 6
+SELECT HEX(v0), HEX(v1), HEX(v64), LENGTH(HEX(v65000)) FROM t1;
+HEX(v0)	HEX(v1)	HEX(v64)	LENGTH(HEX(v65000))
+			0
+		61	0
+	48	61486572652069732061206C697374206F66207265636F6D6D656E64656420626F6F6B73206F6E204D61726961444220616E64204D7953514C2E205765277665	5932
+	61	61616263646566676869206162636465666768692061626364656667686920616263646566676869206162636465666768692061626364656667686920616263	130000
+	79	4F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C7265616479206578697374	5930
+	79	63636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363	130000
+ALTER TABLE t1 ADD COLUMN v65536 VARBINARY(65536) NOT NULL;
+Warnings:
+Note	1246	Converting column 'v65536' from VARBINARY to BLOB
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varbinary(0)	NO		NULL	
+v1	varbinary(1)	NO		NULL	
+v64	varbinary(64)	NO	PRI	NULL	
+v65000	varbinary(65000)	NO		NULL	
+v65536	mediumblob	NO		NULL	
+DROP TABLE t1, t2;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# VARBINARY(64) NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c VARBINARY(64) NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	varbinary(64)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test');
+SELECT HEX(c) FROM t1;
+HEX(c)
+74657374
+DROP TABLE t1;
+#----------------------------------
+# VARBINARY(64) NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c VARBINARY(64) NOT NULL DEFAULT 'test'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	varbinary(64)	NO		test	
+ALTER TABLE t1 ADD COLUMN err VARBINARY(64) NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	74657374
+2	74657374
+DROP TABLE t1;
+########################
+# BIT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a BIT NOT NULL,
+b BIT(20) NOT NULL,
+c BIT(64) NOT NULL,
+d BIT(1) NOT NULL,
+PRIMARY KEY (c)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	bit(1)	NO		NULL	
+b	bit(20)	NO		NULL	
+c	bit(64)	NO	PRI	NULL	
+d	bit(1)	NO		NULL	
+ALTER TABLE t1 DROP COLUMN d;
+ALTER TABLE t1 ADD COLUMN d BIT(0) NOT NULL;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	bit(1)	NO		NULL	
+b	bit(20)	NO		NULL	
+c	bit(64)	NO	PRI	NULL	
+d	bit(1)	NO		NULL	
+INSERT INTO t1 (a,b,c,d) VALUES (0,POW(2,20)-1,b'1111111111111111111111111111111111111111111111111111111111111111',1);
+SELECT BIN(a), HEX(b), c+0 FROM t1 WHERE d>0;
+BIN(a)	HEX(b)	c+0
+0	FFFFF	18446744073709551615
+INSERT INTO t1 (a,b,c,d) VALUES (1,0,-2,0);
+SELECT a+0, b+0, c+0 FROM t1 WHERE d<100;
+a+0	b+0	c+0
+0	1048575	18446744073709551615
+1	0	18446744073709551614
+INSERT INTO t1 (a,b,c,d) VALUES (b'1', 'f', 0xFF, 0x0);
+SELECT a+0, b+0, c+0 FROM t1 WHERE d IN (0, 2);
+a+0	b+0	c+0
+1	0	18446744073709551614
+1	102	255
+DELETE FROM t1;
+INSERT INTO t1 (a,b,c,d) VALUES (0x10,0,0,1);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+a+0	b+0	c+0	d+0
+1	0	0	1
+INSERT INTO t1 (a,b,c,d) VALUES (0x01,0,0x10000000000000000,0);
+Warnings:
+Warning	1264	Out of range value for column 'c' at row 1
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+a+0	b+0	c+0	d+0
+1	0	0	1
+1	0	18446744073709551615	0
+DROP TABLE t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a BIT(65) NOT NULL) ENGINE=LevelDB;
+ERROR 42000: Display width out of range for column 'a' (max = 64)
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# BIT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c BIT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	bit(1)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1);
+SELECT HEX(c) FROM t1;
+HEX(c)
+1
+DROP TABLE t1;
+#----------------------------------
+# BIT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c BIT NOT NULL DEFAULT 1
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	bit(1)	NO		b'1'	
+ALTER TABLE t1 ADD COLUMN err BIT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	1
+2	1
+DROP TABLE t1;
+########################
+# BLOB columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+b BLOB NOT NULL,
+b0 BLOB(0) NOT NULL,
+b1 BLOB(1) NOT NULL,
+b300 BLOB(300) NOT NULL,
+bm BLOB(65535) NOT NULL,
+b70k BLOB(70000) NOT NULL,
+b17m BLOB(17000000) NOT NULL,
+t TINYBLOB NOT NULL,
+m MEDIUMBLOB NOT NULL,
+l LONGBLOB NOT NULL
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+b	blob	NO		NULL	
+b0	blob	NO		NULL	
+b1	tinyblob	NO		NULL	
+b300	blob	NO		NULL	
+bm	blob	NO		NULL	
+b70k	mediumblob	NO		NULL	
+b17m	longblob	NO		NULL	
+t	tinyblob	NO		NULL	
+m	mediumblob	NO		NULL	
+l	longblob	NO		NULL	
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), HEX(REPEAT('g',1048576)), REPEAT('h',255), REPEAT('i',1048576), HEX(REPEAT('j',1048576)) );
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(b)	LENGTH(b0)	LENGTH(b1)	LENGTH(b300)	LENGTH(bm)	LENGTH(b70k)	LENGTH(b17m)	LENGTH(t)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	2097152	255	1048576	2097152
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b0' at row 1
+Warning	1265	Data truncated for column 'b1' at row 1
+Warning	1265	Data truncated for column 'b300' at row 1
+Warning	1265	Data truncated for column 'bm' at row 1
+Warning	1265	Data truncated for column 't' at row 1
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(b)	LENGTH(b0)	LENGTH(b1)	LENGTH(b300)	LENGTH(bm)	LENGTH(b70k)	LENGTH(b17m)	LENGTH(t)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+65535	65535	255	65535	65535	1048576	2097152	255	1048576	2097152
+ALTER TABLE t1 ADD COLUMN bbb BLOB(4294967296);
+ERROR 42000: Display width out of range for column 'bbb' (max = 4294967295)
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# BLOB NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c BLOB NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	blob	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# BLOB NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c BLOB NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	blob	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err BLOB NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# TINYBLOB NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c TINYBLOB NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinyblob	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# TINYBLOB NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c TINYBLOB NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinyblob	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err TINYBLOB NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# MEDIUMBLOB NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c MEDIUMBLOB NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	mediumblob	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# MEDIUMBLOB NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c MEDIUMBLOB NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	mediumblob	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err MEDIUMBLOB NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# LONGBLOB NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c LONGBLOB NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	longblob	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# LONGBLOB NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c LONGBLOB NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	longblob	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err LONGBLOB NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+########################
+# BOOL columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+b1 BOOL NOT NULL,
+b2 BOOLEAN NOT NULL
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+b1	tinyint(1)	NO		NULL	
+b2	tinyint(1)	NO		NULL	
+INSERT INTO t1 (b1,b2) VALUES (1,TRUE);
+SELECT b1,b2 FROM t1;
+b1	b2
+1	1
+INSERT INTO t1 (b1,b2) VALUES (FALSE,0);
+SELECT b1,b2 FROM t1;
+b1	b2
+0	0
+1	1
+INSERT INTO t1 (b1,b2) VALUES (2,3);
+SELECT b1,b2 FROM t1;
+b1	b2
+0	0
+1	1
+2	3
+INSERT INTO t1 (b1,b2) VALUES (-1,-2);
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+1	1
+2	3
+SELECT IF(b1,'true','false') AS a, IF(b2,'true','false') AS b FROM t1;
+a	b
+false	false
+true	true
+true	true
+true	true
+SELECT b1,b2 FROM t1 WHERE b1 = TRUE;
+b1	b2
+1	1
+SELECT b1,b2 FROM t1 WHERE b2 = FALSE;
+b1	b2
+0	0
+INSERT INTO t1 (b1,b2) VALUES ('a','b');
+Warnings:
+Warning	1366	Incorrect integer value: 'a' for column 'b1' at row 1
+Warning	1366	Incorrect integer value: 'b' for column 'b2' at row 1
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+0	0
+1	1
+2	3
+INSERT INTO t1 (b1,b2) VALUES (128,-129);
+Warnings:
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b2' at row 1
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+0	0
+1	1
+127	-128
+2	3
+ALTER TABLE t1 ADD COLUMN b3 BOOLEAN UNSIGNED NOT NULL;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNSIGNED NOT NULL' at line 1
+ALTER TABLE ADD COLUMN b3 BOOL ZEROFILL NOT NULL;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ADD COLUMN b3 BOOL ZEROFILL NOT NULL' at line 1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# BOOL NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c BOOL NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinyint(1)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('0');
+SELECT HEX(c) FROM t1;
+HEX(c)
+0
+DROP TABLE t1;
+#----------------------------------
+# BOOL NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c BOOL NOT NULL DEFAULT '0'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinyint(1)	NO		0	
+ALTER TABLE t1 ADD COLUMN err BOOL NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('0');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	0
+2	0
+DROP TABLE t1;
+########################
+# CHAR columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c CHAR NOT NULL,
+c0 CHAR(0) NOT NULL,
+c1 CHAR(1) NOT NULL,
+c20 CHAR(20) NOT NULL,
+c255 CHAR(255) NOT NULL,
+PRIMARY KEY (c255)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	char(1)	NO		NULL	
+c0	char(0)	NO		NULL	
+c1	char(1)	NO		NULL	
+c20	char(20)	NO		NULL	
+c255	char(255)	NO	PRI	NULL	
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('','','','','');
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.');
+SELECT c,c0,c1,c20,c255 FROM t1;
+c	c0	c1	c20	c255
+				
+a		b	abcdefghi klmnopqrst	Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256));
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 1
+Warning	1265	Data truncated for column 'c0' at row 1
+Warning	1265	Data truncated for column 'c1' at row 1
+Warning	1265	Data truncated for column 'c20' at row 1
+Warning	1265	Data truncated for column 'c255' at row 1
+INSERT INTO t1 (c,c0,c1,c20,c255) SELECT c255, c255, c255, c255, CONCAT('a',c255,c1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 5
+Warning	1265	Data truncated for column 'c0' at row 5
+Warning	1265	Data truncated for column 'c1' at row 5
+Warning	1265	Data truncated for column 'c20' at row 5
+Warning	1265	Data truncated for column 'c' at row 6
+Warning	1265	Data truncated for column 'c0' at row 6
+Warning	1265	Data truncated for column 'c1' at row 6
+Warning	1265	Data truncated for column 'c20' at row 6
+Warning	1265	Data truncated for column 'c255' at row 6
+SELECT c,c0,c1,c20,c255 FROM t1;
+c	c0	c1	c20	c255
+				
+				a
+C		C	Creating an article	aCreating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.b
+a		a	aaaaaaaaaaaaaaaaaaaa	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+a		b	abcdefghi klmnopqrst	Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.
+x		x	xxxxxxxxxxxxxxxxxxxx	axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+SELECT DISTINCT c20, REPEAT('a',LENGTH(c20)), COUNT(*) FROM t1 GROUP BY c1, c20;
+c20	REPEAT('a',LENGTH(c20))	COUNT(*)
+		2
+Creating an article	aaaaaaaaaaaaaaaaaaa	1
+aaaaaaaaaaaaaaaaaaaa	aaaaaaaaaaaaaaaaaaaa	1
+abcdefghi klmnopqrst	aaaaaaaaaaaaaaaaaaaa	1
+xxxxxxxxxxxxxxxxxxxx	aaaaaaaaaaaaaaaaaaaa	1
+ALTER TABLE t1 ADD COLUMN c257 CHAR(257) NOT NULL;
+ERROR 42000: Column length too big for column 'c257' (max = 255); use BLOB or TEXT instead
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# CHAR NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c CHAR NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	char(1)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('_');
+SELECT HEX(c) FROM t1;
+HEX(c)
+5F
+DROP TABLE t1;
+#----------------------------------
+# CHAR NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c CHAR NOT NULL DEFAULT '_'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	char(1)	NO		_	
+ALTER TABLE t1 ADD COLUMN err CHAR NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('_');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	5F
+2	5F
+DROP TABLE t1;
+########################
+# VARCHAR columns
+########################
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+v0 VARCHAR(0) NOT NULL,
+v1 VARCHAR(1) NOT NULL,
+v64 VARCHAR(64) NOT NULL,
+v65000 VARCHAR(65000) NOT NULL,
+PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varchar(0)	NO		NULL	
+v1	varchar(1)	NO		NULL	
+v64	varchar(64)	NO	PRI	NULL	
+v65000	varchar(65000)	NO		NULL	
+CREATE TABLE t2 (v VARCHAR(65532), PRIMARY KEY (v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+Field	Type	Null	Key	Default	Extra
+v	varchar(65532)	NO	PRI		
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+SELECT v0,v1,v64,v65000 FROM t1;
+v0	v1	v64	v65000
+
+
+
+
+
+
+
+
+
+
+			
+	y	Once there, double check that an article doesn't already exist	Here is a list of recommended books on MariaDB and MySQL. We've provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+            o "High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL's full power." (From the book description at O'Reilly) 
+            o A lot of examples of how to use MySQL. As with all of Paul's books, it's worth its weight in gold and even enjoyable reading for such a 'dry' subject. 
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Free to read in the Knowledgebase! 
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+            o The 'default' book to read if you wont to learn to use MySQL / MariaDB. 
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. 
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+      * MariaDB Crash Course by Ben Forta
+      * MySQL (4th Edition) by Paul DuBois
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+      * MySQL Admin Cookbook
+      * MySQL Cookbook by Paul DuBois
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+  For MariaDB / MySQL end users
+  For developers who want to code on MariaDB or MySQL
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 1
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'v64' at row 1
+Warning	1265	Data truncated for column 'v65000' at row 1
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 5
+Warning	1265	Data truncated for column 'v1' at row 5
+Warning	1265	Data truncated for column 'v64' at row 5
+Warning	1265	Data truncated for column 'v65000' at row 5
+Warning	1265	Data truncated for column 'v0' at row 6
+Warning	1265	Data truncated for column 'v1' at row 6
+Warning	1265	Data truncated for column 'v64' at row 6
+SELECT v0, v1, v64, LENGTH(v65000) FROM t1;
+v0	v1	v64	LENGTH(v65000)
+			0
+		a	0
+	H	aHere is a list of recommended books on MariaDB and MySQL. We've	2966
+	a	aabcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abc	65000
+	y	Once there, double check that an article doesn't already exist	2965
+	y	cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc	65000
+ALTER TABLE t1 ADD COLUMN v65536 VARCHAR(65536) NOT NULL;
+Warnings:
+Note	1246	Converting column 'v65536' from VARCHAR to TEXT
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varchar(0)	NO		NULL	
+v1	varchar(1)	NO		NULL	
+v64	varchar(64)	NO	PRI	NULL	
+v65000	varchar(65000)	NO		NULL	
+v65536	mediumtext	NO		NULL	
+DROP TABLE t1, t2;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# VARCHAR(64) NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c VARCHAR(64) NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	varchar(64)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test default');
+SELECT HEX(c) FROM t1;
+HEX(c)
+746573742064656661756C74
+DROP TABLE t1;
+#----------------------------------
+# VARCHAR(64) NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c VARCHAR(64) NOT NULL DEFAULT 'test default'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	varchar(64)	NO		test default	
+ALTER TABLE t1 ADD COLUMN err VARCHAR(64) NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test default');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	746573742064656661756C74
+2	746573742064656661756C74
+DROP TABLE t1;
+########################
+# date and time columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DATE NOT NULL,
+dt DATETIME NOT NULL,
+ts TIMESTAMP NOT NULL,
+t TIME NOT NULL,
+y YEAR NOT NULL,
+y4 YEAR(4) NOT NULL,
+y2 YEAR(2) NOT NULL,
+pk DATETIME PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	date	NO		NULL	
+dt	datetime	NO		NULL	
+ts	timestamp	NO		NULL	
+t	time	NO		NULL	
+y	year(4)	NO		NULL	
+y4	year(4)	NO		NULL	
+y2	year(4)	NO		NULL	
+pk	datetime	NO	PRI	NULL	
+SET @tm = '2012-04-09 05:27:00';
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('1000-01-01', '1000-01-01 00:00:00', FROM_UNIXTIME(1), '-838:59:59', '1901', '1901', '00','2012-12-12 12:12:12'),
+('9999-12-31', '9999-12-31 23:59:59', FROM_UNIXTIME(2147483647), '838:59:59', '2155', '2155', '99','2012-12-12 12:12:13'),
+('0000-00-00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '00:00:00', '0', '0', '0','2012-12-12 12:12:14'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),YEAR(@tm),YEAR(@tm),'2012-12-12 12:12:15');
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+d	dt	ts	t	y	y4	y2
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	00:00:00	2000	2000	2000
+1000-01-01	1000-01-01 00:00:00	1970-01-01 03:00:01	-838:59:59	1901	1901	2000
+2012-04-09	2012-04-09 05:27:00	2012-04-09 05:27:00	05:27:00	2012	2012	2012
+9999-12-31	9999-12-31 23:59:59	2038-01-19 06:14:07	838:59:59	2155	2155	1999
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('999-13-32', '999-11-31 00:00:00', '0', '-839:00:00', '1900', '1900', '-1','2012-12-12 12:12:16');
+Warnings:
+Warning	1265	Data truncated for column 'd' at row 1
+Warning	1264	Out of range value for column 'dt' at row 1
+Warning	1264	Out of range value for column 'ts' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 'y' at row 1
+Warning	1264	Out of range value for column 'y4' at row 1
+Warning	1264	Out of range value for column 'y2' at row 1
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+d	dt	ts	t	y	y4	y2
+1000-01-01	1000-01-01 00:00:00	1970-01-01 03:00:01	-838:59:59	1901	1901	2000
+9999-12-31	9999-12-31 23:59:59	2038-01-19 06:14:07	838:59:59	2155	2155	1999
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	00:00:00	2000	2000	2000
+2012-04-09	2012-04-09 05:27:00	2012-04-09 05:27:00	05:27:00	2012	2012	2012
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	-838:59:59	0000	0000	0000
+DROP TABLE t1;
+SET TIMESTAMP=UNIX_TIMESTAMP('2013-12-12 12:12:12');
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# DATE NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c DATE NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	date	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012-12-21');
+SELECT HEX(c) FROM t1;
+HEX(c)
+323031322D31322D3231
+DROP TABLE t1;
+#----------------------------------
+# DATE NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c DATE NOT NULL DEFAULT '2012-12-21'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	date	NO		2012-12-21	
+ALTER TABLE t1 ADD COLUMN err DATE NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012-12-21');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	323031322D31322D3231
+2	323031322D31322D3231
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# DATETIME NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c DATETIME NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	datetime	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012-12-21 12:21:12');
+SELECT HEX(c) FROM t1;
+HEX(c)
+323031322D31322D32312031323A32313A3132
+DROP TABLE t1;
+#----------------------------------
+# DATETIME NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c DATETIME NOT NULL DEFAULT '2012-12-21 12:21:12'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	datetime	NO		2012-12-21 12:21:12	
+ALTER TABLE t1 ADD COLUMN err DATETIME NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012-12-21 12:21:12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	323031322D31322D32312031323A32313A3132
+2	323031322D31322D32312031323A32313A3132
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# TIMESTAMP NOT NULL column without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c TIMESTAMP NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	timestamp	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012-12-21 12:21:12');
+SELECT HEX(c) FROM t1;
+HEX(c)
+323031322D31322D32312031323A32313A3132
+DROP TABLE t1;
+#----------------------------------
+# TIMESTAMP NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c TIMESTAMP NOT NULL DEFAULT '2012-12-21 12:21:12'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	timestamp	NO		2012-12-21 12:21:12	
+ALTER TABLE t1 ADD COLUMN err TIMESTAMP NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012-12-21 12:21:12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	323031322D31322D32312031323A32313A3132
+2	323031322D31322D32312031323A32313A3132
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# TIME NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c TIME NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	time	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('12:21:12');
+SELECT HEX(c) FROM t1;
+HEX(c)
+31323A32313A3132
+DROP TABLE t1;
+#----------------------------------
+# TIME NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c TIME NOT NULL DEFAULT '12:21:12'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	time	NO		12:21:12	
+ALTER TABLE t1 ADD COLUMN err TIME NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('12:21:12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	31323A32313A3132
+2	31323A32313A3132
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# YEAR NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c YEAR NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	year(4)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012');
+SELECT HEX(c) FROM t1;
+HEX(c)
+7DC
+DROP TABLE t1;
+#----------------------------------
+# YEAR NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c YEAR NOT NULL DEFAULT '2012'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	year(4)	NO		2012	
+ALTER TABLE t1 ADD COLUMN err YEAR NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('2012');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	7DC
+2	7DC
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# YEAR(2) NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c YEAR(2) NOT NULL) ENGINE=LevelDB;
+Warnings:
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	year(4)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('12');
+SELECT HEX(c) FROM t1;
+HEX(c)
+7DC
+DROP TABLE t1;
+#----------------------------------
+# YEAR(2) NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c YEAR(2) NOT NULL DEFAULT '12'
+) ENGINE=LevelDB;
+Warnings:
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	year(4)	NO		2012	
+ALTER TABLE t1 ADD COLUMN err YEAR(2) NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	7DC
+2	7DC
+DROP TABLE t1;
+########################
+# ENUM columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a ENUM('') NOT NULL,
+b ENUM('test1','test2','test3','test4','test5') NOT NULL,
+c ENUM('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o
 ','5p','
 5q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75') NOT NULL,
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	enum('')	NO		NULL	
+b	enum('test1','test2','test3','test4','test5')	NO	PRI	NULL	
+c	enum('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o'
 ,'5p','5
 q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75')	NO		NULL	
+INSERT INTO t1 (a,b,c) VALUES ('','test2','4'),('',5,2);
+SELECT a,b,c FROM t1;
+a	b	c
+	test2	4
+	test5	2
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+Warnings:
+Warning	1265	Data truncated for column 'a' at row 1
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+		
+	test2	4
+	test5	2
+ALTER TABLE t1 ADD COLUMN e ENUM('a','A') NOT NULL;
+Warnings:
+Note	1291	Column 'e' has duplicated value 'a' in ENUM
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	enum('')	NO		NULL	
+b	enum('test1','test2','test3','test4','test5')	NO	PRI	NULL	
+c	enum('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o'
 ,'5p','5
 q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75')	NO		NULL	
+e	enum('a','A')	NO		NULL	
+INSERT INTO t1 (a,b,c,e) VALUES ('','test3','75','A');
+SELECT a,b,c,e FROM t1;
+a	b	c	e
+			a
+	test2	4	a
+	test3	75	a
+	test5	2	a
+SELECT a,b,c,e FROM t1 WHERE b='test2' OR a != '';
+a	b	c	e
+	test2	4	a
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# ENUM('test1','test2','test3') NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c ENUM('test1','test2','test3') NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	enum('test1','test2','test3')	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test2');
+SELECT HEX(c) FROM t1;
+HEX(c)
+7465737432
+DROP TABLE t1;
+#----------------------------------
+# ENUM('test1','test2','test3') NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c ENUM('test1','test2','test3') NOT NULL DEFAULT 'test2'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	enum('test1','test2','test3')	NO		test2	
+ALTER TABLE t1 ADD COLUMN err ENUM('test1','test2','test3') NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test2');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	7465737432
+2	7465737432
+DROP TABLE t1;
+########################
+# Fixed point columns (NUMERIC, DECIMAL)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DECIMAL NOT NULL,
+d0 DECIMAL(0) NOT NULL,
+d1_1 DECIMAL(1,1) NOT NULL,
+d10_2 DECIMAL(10,2) NOT NULL,
+d60_10 DECIMAL(60,10) NOT NULL,
+n NUMERIC NOT NULL,
+n0_0 NUMERIC(0,0) NOT NULL,
+n1 NUMERIC(1) NOT NULL,
+n20_4 NUMERIC(20,4) NOT NULL,
+n65_4 NUMERIC(65,4) NOT NULL,
+pk NUMERIC NOT NULL PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	decimal(10,0)	NO		NULL	
+d0	decimal(10,0)	NO		NULL	
+d1_1	decimal(1,1)	NO		NULL	
+d10_2	decimal(10,2)	NO		NULL	
+d60_10	decimal(60,10)	NO		NULL	
+n	decimal(10,0)	NO		NULL	
+n0_0	decimal(10,0)	NO		NULL	
+n1	decimal(1,0)	NO		NULL	
+n20_4	decimal(20,4)	NO		NULL	
+n65_4	decimal(65,4)	NO		NULL	
+pk	decimal(10,0)	NO	PRI	NULL	
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (100,123456,0.3,40000.25,123456789123456789.10001,1024,7000.0,8.0,999999.9,9223372036854775807,1);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.0,9999999999.0,0.9,99999999.99,99999999999999999999999999999999999999999999999999.9999999999,9999999999.0,9999999999.0,9.0,9999999999999999.9999,9999999999999999999999999999999999999999999999999999999999999.9999,3);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-100,-123456,-0.3,-40000.25,-123456789123456789.10001,-1024,-7000.0,-8.0,-999999.9,-9223372036854775807,4);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-9999999999.0,-9999999999.0,-0.9,-99999999.99,-99999999999999999999999999999999999999999999999999.9999999999,-9999999999.0,-9999999999.0,-9.0,-9999999999999999.9999,-9999999999999999999999999999999999999999999999999999999999999.9999,5);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1 WHERE n20_4 = 9999999999999999.9999 OR d < 100;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+6
+);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (10000000000.0,10000000000.0,1.1,100000000.99,100000000000000000000000000000000000000000000000000.0,10000000000.0,10000000000.0,10.0,10000000000000000.9999,10000000000000000000000000000000000000000000000000000000000000.9999,7);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.1,9999999999.1,1.9,99999999.001,99999999999999999999999999999999999999999999999999.99999999991,9999999999.1,9999999999.1,9.1,9999999999999999.00001,9999999999999999999999999999999999999999999999999999999999999.11111,8);
+Warnings:
+Note	1265	Data truncated for column 'd' at row 1
+Note	1265	Data truncated for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Note	1265	Data truncated for column 'd10_2' at row 1
+Note	1265	Data truncated for column 'd60_10' at row 1
+Note	1265	Data truncated for column 'n' at row 1
+Note	1265	Data truncated for column 'n0_0' at row 1
+Note	1265	Data truncated for column 'n1' at row 1
+Note	1265	Data truncated for column 'n20_4' at row 1
+Note	1265	Data truncated for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.00	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.0000	9999999999999999999999999999999999999999999999999999999999999.1111
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+ALTER TABLE t1 ADD COLUMN n66 NUMERIC(66) NOT NULL;
+ERROR 42000: Too big precision 66 specified for column 'n66'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(66,6) NOT NULL;
+ERROR 42000: Too big precision 66 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(66,66) NOT NULL;
+ERROR 42000: Too big scale 66 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# DECIMAL NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c DECIMAL NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	decimal(10,0)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1.1);
+Warnings:
+Note	1265	Data truncated for column 'c' at row 1
+SELECT HEX(c) FROM t1;
+HEX(c)
+1
+DROP TABLE t1;
+#----------------------------------
+# DECIMAL NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c DECIMAL NOT NULL DEFAULT 1.1
+) ENGINE=LevelDB;
+Warnings:
+Note	1265	Data truncated for column 'c' at row 1
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	decimal(10,0)	NO		1	
+ALTER TABLE t1 ADD COLUMN err DECIMAL NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1.1);
+Warnings:
+Note	1265	Data truncated for column 'c' at row 1
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	1
+2	1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# NUMERIC NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c NUMERIC NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	decimal(10,0)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+SELECT HEX(c) FROM t1;
+HEX(c)
+0
+DROP TABLE t1;
+#----------------------------------
+# NUMERIC NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c NUMERIC NOT NULL DEFAULT 0
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	decimal(10,0)	NO		0	
+ALTER TABLE t1 ADD COLUMN err NUMERIC NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	0
+2	0
+DROP TABLE t1;
+########################
+# Floating point columns (FLOAT, DOUBLE)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+f FLOAT NOT NULL,
+f0 FLOAT(0) NOT NULL,
+r1_1 REAL(1,1) NOT NULL,
+f23_0 FLOAT(23) NOT NULL,
+f20_3 FLOAT(20,3) NOT NULL,
+d DOUBLE NOT NULL,
+d1_0 DOUBLE(1,0) NOT NULL,
+d10_10 DOUBLE PRECISION (10,10) NOT NULL,
+d53 DOUBLE(53,0) NOT NULL,
+d53_10 DOUBLE(53,10) NOT NULL,
+pk DOUBLE NOT NULL PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+f	float	NO		NULL	
+f0	float	NO		NULL	
+r1_1	double(1,1)	NO		NULL	
+f23_0	float	NO		NULL	
+f20_3	float(20,3)	NO		NULL	
+d	double	NO		NULL	
+d1_0	double(1,0)	NO		NULL	
+d10_10	double(10,10)	NO		NULL	
+d53	double(53,0)	NO		NULL	
+d53_10	double(53,10)	NO		NULL	
+pk	double	NO	PRI	NULL	
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	11111111.111
+d10_10	0.0123456789
+d1_0	8
+d53	1234566789123456800
+d53_10	100000000000000000.0000000000
+f0	12345.1
+f20_3	56789.988
+f23_0	123457000
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+99999999999999999999999999999999999999,
+99999999999999999999999999999999999999.9999999999999999,
+0.9,
+99999999999999999999999999999999999999.9,
+99999999999999999.999,
+999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+9,
+0.9999999999, 
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+3
+);
+Warnings:
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	11111111.111
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	8
+d1_0	9
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	1e38
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+SELECT MAX(f), MAX(f0), MAX(r1_1), MAX(f23_0), MAX(f20_3), MAX(d), MAX(d1_0), MAX(d10_10), MAX(d53), MAX(d53_10) FROM t1;
+MAX(f)	9.999999680285692e37
+MAX(d)	1e81
+MAX(d10_10)	0.9999999999
+MAX(d1_0)	9
+MAX(d53)	100000000000000000000000000000000000000000000000000000
+MAX(d53_10)	10000000000000000000000000000000000000000000.0000000000
+MAX(f0)	9.999999680285692e37
+MAX(f20_3)	99999998430674940.000
+MAX(f23_0)	9.999999680285692e37
+MAX(r1_1)	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+5
+);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e61
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f	3.40282e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+999999999999999999999999999999999999999,
+999999999999999999999999999999999999999.9999999999999999,
+1.9,
+999999999999999999999999999999999999999.9,
+999999999999999999.999,
+9999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+99,
+1.9999999999,
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+6
+);
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e61
+d	1e65
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f	3.40282e38
+f	3.40282e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f0	3.40282e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+f23_0	3.40282e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+ALTER TABLE t1 ADD COLUMN d0_0 DOUBLE(0,0) NOT NULL;
+ERROR 42000: Display width out of range for column 'd0_0' (max = 255)
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(256,1) NOT NULL;
+ERROR 42000: Too big precision 256 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(40,35) NOT NULL;
+ERROR 42000: Too big scale 35 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# FLOAT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c FLOAT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	float	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1.1);
+SELECT HEX(c) FROM t1;
+HEX(c)
+1
+DROP TABLE t1;
+#----------------------------------
+# FLOAT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c FLOAT NOT NULL DEFAULT 1.1
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	float	NO		1.1	
+ALTER TABLE t1 ADD COLUMN err FLOAT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1.1);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	1
+2	1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# DOUBLE NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c DOUBLE NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	double	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+SELECT HEX(c) FROM t1;
+HEX(c)
+0
+DROP TABLE t1;
+#----------------------------------
+# DOUBLE NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c DOUBLE NOT NULL DEFAULT 0
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	double	NO		0	
+ALTER TABLE t1 ADD COLUMN err DOUBLE NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	0
+2	0
+DROP TABLE t1;
+########################
+# INT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+i INT NOT NULL,
+i0 INT(0) NOT NULL,
+i1 INT(1) NOT NULL,
+i20 INT(20) NOT NULL,
+t TINYINT NOT NULL,
+t0 TINYINT(0) NOT NULL,
+t1 TINYINT(1) NOT NULL,
+t20 TINYINT(20) NOT NULL,
+s SMALLINT NOT NULL,
+s0 SMALLINT(0) NOT NULL,
+s1 SMALLINT(1) NOT NULL,
+s20 SMALLINT(20) NOT NULL,
+m MEDIUMINT NOT NULL,
+m0 MEDIUMINT(0) NOT NULL,
+m1 MEDIUMINT(1) NOT NULL,
+m20 MEDIUMINT(20) NOT NULL,
+b BIGINT NOT NULL,
+b0 BIGINT(0) NOT NULL,
+b1 BIGINT(1) NOT NULL,
+b20 BIGINT(20) NOT NULL,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+i	int(11)	NO		NULL	
+i0	int(11)	NO		NULL	
+i1	int(1)	NO		NULL	
+i20	int(20)	NO		NULL	
+t	tinyint(4)	NO		NULL	
+t0	tinyint(4)	NO		NULL	
+t1	tinyint(1)	NO		NULL	
+t20	tinyint(20)	NO		NULL	
+s	smallint(6)	NO		NULL	
+s0	smallint(6)	NO		NULL	
+s1	smallint(1)	NO		NULL	
+s20	smallint(20)	NO		NULL	
+m	mediumint(9)	NO		NULL	
+m0	mediumint(9)	NO		NULL	
+m1	mediumint(1)	NO		NULL	
+m20	mediumint(20)	NO		NULL	
+b	bigint(20)	NO		NULL	
+b0	bigint(20)	NO		NULL	
+b1	bigint(1)	NO		NULL	
+b20	bigint(20)	NO		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (2147483647,2147483647,2147483647,2147483647,127,127,127,127,32767,32767,32767,32767,8388607,8388607,8388607,8388607,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483648,-2147483648,-2147483648,-2147483648,-128,-128,-128,-128,-32768,-32768,-32768,-32768,-8388608,-8388608,-8388608,-8388608,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967295,4294967295,4294967295,4294967295,255,255,255,255,65535,65535,65535,65535,16777215,16777215,16777215,16777215,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483649,-2147483649,-2147483649,-2147483649,-129,-129,-129,-129,-32769,-32769,-32769,-32769,-8388609,-8388609,-8388609,-8388609,-9223372036854775809,-9223372036854775809,-9223372036854775809,-9223372036854775809);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967296,4294967296,4294967296,4294967296,256,256,256,256,65536,65536,65536,65536,16777216,16777216,16777216,16777216,18446744073709551616,18446744073709551616,18446744073709551616,18446744073709551616);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) SELECT b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b FROM t1 WHERE b IN (-9223372036854775808,9223372036854775807,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 8
+Warning	1264	Out of range value for column 'i0' at row 8
+Warning	1264	Out of range value for column 'i1' at row 8
+Warning	1264	Out of range value for column 'i20' at row 8
+Warning	1264	Out of range value for column 't' at row 8
+Warning	1264	Out of range value for column 't0' at row 8
+Warning	1264	Out of range value for column 't1' at row 8
+Warning	1264	Out of range value for column 't20' at row 8
+Warning	1264	Out of range value for column 's' at row 8
+Warning	1264	Out of range value for column 's0' at row 8
+Warning	1264	Out of range value for column 's1' at row 8
+Warning	1264	Out of range value for column 's20' at row 8
+Warning	1264	Out of range value for column 'm' at row 8
+Warning	1264	Out of range value for column 'm0' at row 8
+Warning	1264	Out of range value for column 'm1' at row 8
+Warning	1264	Out of range value for column 'm20' at row 8
+Warning	1264	Out of range value for column 'i' at row 9
+Warning	1264	Out of range value for column 'i0' at row 9
+Warning	1264	Out of range value for column 'i1' at row 9
+Warning	1264	Out of range value for column 'i20' at row 9
+Warning	1264	Out of range value for column 't' at row 9
+Warning	1264	Out of range value for column 't0' at row 9
+Warning	1264	Out of range value for column 't1' at row 9
+Warning	1264	Out of range value for column 't20' at row 9
+Warning	1264	Out of range value for column 's' at row 9
+Warning	1264	Out of range value for column 's0' at row 9
+Warning	1264	Out of range value for column 's1' at row 9
+Warning	1264	Out of range value for column 's20' at row 9
+Warning	1264	Out of range value for column 'm' at row 9
+Warning	1264	Out of range value for column 'm0' at row 9
+Warning	1264	Out of range value for column 'm1' at row 9
+Warning	1264	Out of range value for column 'm20' at row 9
+Warning	1264	Out of range value for column 'i' at row 10
+Warning	1264	Out of range value for column 'i0' at row 10
+Warning	1264	Out of range value for column 'i1' at row 10
+Warning	1264	Out of range value for column 'i20' at row 10
+Warning	1264	Out of range value for column 't' at row 10
+Warning	1264	Out of range value for column 't0' at row 10
+Warning	1264	Out of range value for column 't1' at row 10
+Warning	1264	Out of range value for column 't20' at row 10
+Warning	1264	Out of range value for column 's' at row 10
+Warning	1264	Out of range value for column 's0' at row 10
+Warning	1264	Out of range value for column 's1' at row 10
+Warning	1264	Out of range value for column 's20' at row 10
+Warning	1264	Out of range value for column 'm' at row 10
+Warning	1264	Out of range value for column 'm0' at row 10
+Warning	1264	Out of range value for column 'm1' at row 10
+Warning	1264	Out of range value for column 'm20' at row 10
+Warning	1264	Out of range value for column 'i' at row 11
+Warning	1264	Out of range value for column 'i0' at row 11
+Warning	1264	Out of range value for column 'i1' at row 11
+Warning	1264	Out of range value for column 'i20' at row 11
+Warning	1264	Out of range value for column 't' at row 11
+Warning	1264	Out of range value for column 't0' at row 11
+Warning	1264	Out of range value for column 't1' at row 11
+Warning	1264	Out of range value for column 't20' at row 11
+Warning	1264	Out of range value for column 's' at row 11
+Warning	1264	Out of range value for column 's0' at row 11
+Warning	1264	Out of range value for column 's1' at row 11
+Warning	1264	Out of range value for column 's20' at row 11
+Warning	1264	Out of range value for column 'm' at row 11
+Warning	1264	Out of range value for column 'm0' at row 11
+Warning	1264	Out of range value for column 'm1' at row 11
+Warning	1264	Out of range value for column 'm20' at row 11
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+ALTER TABLE t1 ADD COLUMN i257 INT(257) NOT NULL;
+ERROR 42000: Display width out of range for column 'i257' (max = 255)
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# INT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c INT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	int(11)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (2147483647);
+SELECT HEX(c) FROM t1;
+HEX(c)
+7FFFFFFF
+DROP TABLE t1;
+#----------------------------------
+# INT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c INT NOT NULL DEFAULT 2147483647
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	int(11)	NO		2147483647	
+ALTER TABLE t1 ADD COLUMN err INT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (2147483647);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	7FFFFFFF
+2	7FFFFFFF
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# TINYINT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c TINYINT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinyint(4)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (127);
+SELECT HEX(c) FROM t1;
+HEX(c)
+7F
+DROP TABLE t1;
+#----------------------------------
+# TINYINT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c TINYINT NOT NULL DEFAULT 127
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinyint(4)	NO		127	
+ALTER TABLE t1 ADD COLUMN err TINYINT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (127);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	7F
+2	7F
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# SMALLINT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c SMALLINT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	smallint(6)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+SELECT HEX(c) FROM t1;
+HEX(c)
+0
+DROP TABLE t1;
+#----------------------------------
+# SMALLINT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c SMALLINT NOT NULL DEFAULT 0
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	smallint(6)	NO		0	
+ALTER TABLE t1 ADD COLUMN err SMALLINT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (0);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	0
+2	0
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# MEDIUMINT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c MEDIUMINT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	mediumint(9)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1);
+SELECT HEX(c) FROM t1;
+HEX(c)
+1
+DROP TABLE t1;
+#----------------------------------
+# MEDIUMINT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c MEDIUMINT NOT NULL DEFAULT 1
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	mediumint(9)	NO		1	
+ALTER TABLE t1 ADD COLUMN err MEDIUMINT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (1);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	1
+2	1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# BIGINT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c BIGINT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	bigint(20)	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (9223372036854775807);
+SELECT HEX(c) FROM t1;
+HEX(c)
+7FFFFFFFFFFFFFFF
+DROP TABLE t1;
+#----------------------------------
+# BIGINT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c BIGINT NOT NULL DEFAULT 9223372036854775807
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	bigint(20)	NO		9223372036854775807	
+ALTER TABLE t1 ADD COLUMN err BIGINT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES (9223372036854775807);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	7FFFFFFFFFFFFFFF
+2	7FFFFFFFFFFFFFFF
+DROP TABLE t1;
+########################
+# SET columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a SET('') NOT NULL,
+b SET('test1','test2','test3','test4','test5') NOT NULL,
+c SET('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64') NOT NULL,
+PRIMARY KEY (c)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	set('')	NO		NULL	
+b	set('test1','test2','test3','test4','test5')	NO		NULL	
+c	set('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64')	NO	PRI	NULL	
+INSERT INTO t1 (a,b,c) VALUES 
+('','test2,test3','01,34,44,,23'),
+('',5,2),
+(',','test4,test2','');
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+	test1,test3	02
+	test2,test3	01,23,34,44
+	test2,test4	
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+		01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50'51,52,53,54,55,56,57,58,59,60,61,62,63,64
+	test1,test3	02
+	test2,test3	01,23,34,44
+	test2,test4	
+ALTER TABLE t1 ADD COLUMN e SET('a','A') NOT NULL;
+Warnings:
+Note	1291	Column 'e' has duplicated value 'a' in SET
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	set('')	NO		NULL	
+b	set('test1','test2','test3','test4','test5')	NO		NULL	
+c	set('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64')	NO	PRI	NULL	
+e	set('a','A')	NO		NULL	
+ALTER TABLE t1 ADD COLUMN f SET('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i') NOT NULL;
+ERROR HY000: Too many strings for column f and SET
+SELECT a,b,c,e FROM t1 WHERE FIND_IN_SET('test2',b)>0 OR a != '';
+a	b	c	e
+	test2,test3	01,23,34,44	
+	test2,test4		
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# SET('test1','test2','test3') NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c SET('test1','test2','test3') NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	set('test1','test2','test3')	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test2,test3');
+SELECT HEX(c) FROM t1;
+HEX(c)
+74657374322C7465737433
+DROP TABLE t1;
+#----------------------------------
+# SET('test1','test2','test3') NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c SET('test1','test2','test3') NOT NULL DEFAULT 'test2,test3'
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	set('test1','test2','test3')	NO		test2,test3	
+ALTER TABLE t1 ADD COLUMN err SET('test1','test2','test3') NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('test2,test3');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	74657374322C7465737433
+2	74657374322C7465737433
+DROP TABLE t1;
+########################
+# TEXT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+t TEXT NOT NULL,
+t0 TEXT(0) NOT NULL,
+t1 TEXT(1) NOT NULL,
+t300 TEXT(300) NOT NULL,
+tm TEXT(65535) NOT NULL,
+t70k TEXT(70000) NOT NULL,
+t17m TEXT(17000000) NOT NULL,
+tt TINYTEXT NOT NULL,
+m MEDIUMTEXT NOT NULL,
+l LONGTEXT NOT NULL
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+t	text	NO		NULL	
+t0	text	NO		NULL	
+t1	tinytext	NO		NULL	
+t300	text	NO		NULL	
+tm	text	NO		NULL	
+t70k	mediumtext	NO		NULL	
+t17m	longtext	NO		NULL	
+tt	tinytext	NO		NULL	
+m	mediumtext	NO		NULL	
+l	longtext	NO		NULL	
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',255), REPEAT('i',1048576), REPEAT('j',1048576) );
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(t)	LENGTH(t0)	LENGTH(t1)	LENGTH(t300)	LENGTH(tm)	LENGTH(t70k)	LENGTH(t17m)	LENGTH(tt)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+Warnings:
+Warning	1265	Data truncated for column 't' at row 1
+Warning	1265	Data truncated for column 't0' at row 1
+Warning	1265	Data truncated for column 't1' at row 1
+Warning	1265	Data truncated for column 't300' at row 1
+Warning	1265	Data truncated for column 'tm' at row 1
+Warning	1265	Data truncated for column 'tt' at row 1
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(t)	LENGTH(t0)	LENGTH(t1)	LENGTH(t300)	LENGTH(tm)	LENGTH(t70k)	LENGTH(t17m)	LENGTH(tt)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+ALTER TABLE t1 ADD COLUMN ttt TEXT(4294967296) NOT NULL;
+ERROR 42000: Display width out of range for column 'ttt' (max = 4294967295)
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# TEXT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c TEXT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	text	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# TEXT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c TEXT NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	text	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err TEXT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# TINYTEXT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c TINYTEXT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinytext	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# TINYTEXT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c TINYTEXT NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	tinytext	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err TINYTEXT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# MEDIUMTEXT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c MEDIUMTEXT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	mediumtext	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# MEDIUMTEXT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c MEDIUMTEXT NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	mediumtext	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err MEDIUMTEXT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+#----------------------------------
+# LONGTEXT NOT NULL columns without a default
+#----------------------------------
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, c LONGTEXT NOT NULL) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	longtext	NO		NULL	
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+SELECT HEX(c) FROM t1;
+HEX(c)
+
+DROP TABLE t1;
+#----------------------------------
+# LONGTEXT NOT NULL columns with a default
+#----------------------------------
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+c LONGTEXT NOT NULL DEFAULT ''
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+c	longtext	NO		NULL	
+ALTER TABLE t1 ADD COLUMN err LONGTEXT NOT NULL DEFAULT NULL;
+ERROR 42000: Invalid default value for 'err'
+INSERT INTO t1 (c) VALUES (NULL);
+ERROR 23000: Column 'c' cannot be null
+INSERT INTO t1 (c) VALUES ('');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c) FROM t1 ORDER BY pk;
+pk	HEX(c)
+1	
+2	
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/col_opt_not_null.test b/mysql-test/suite/leveldb/col_opt_not_null.test
new file mode 100644
index 0000000..6aeff1a
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_not_null.test
@@ -0,0 +1,222 @@
+# 
+# NOT NULL column attribute
+#
+
+#########################################
+# TODO:
+# Currently the test produces incorrect (?) result
+# due to bug MySQL:68472. If the bug is ever fixed,
+# the test and result files will need to be updated.
+#########################################
+
+
+let $extra_col_opts = NOT NULL;
+
+--echo ########################
+--echo # BINARY columns
+--echo ########################
+
+--source type_binary.inc
+--let $col_type = BINARY
+--let $col_default = 0
+--source col_not_null.inc
+
+--echo ########################
+--echo # VARBINARY columns
+--echo ########################
+
+--source type_varbinary.inc
+--let $col_type = VARBINARY(64)
+--let $col_default = 'test'
+--source col_not_null.inc
+
+--echo ########################
+--echo # BIT columns
+--echo ########################
+
+--source type_bit.inc
+--let $col_type = BIT
+--let $col_default = 1
+--source col_not_null.inc
+
+--echo ########################
+--echo # BLOB columns
+--echo ########################
+
+--source type_blob.inc
+
+--let $col_default = ''
+
+--let $col_type = BLOB
+--source col_not_null.inc
+
+--let $col_type = TINYBLOB
+--source col_not_null.inc
+
+--let $col_type = MEDIUMBLOB
+--source col_not_null.inc
+
+--let $col_type = LONGBLOB
+--source col_not_null.inc
+
+--echo ########################
+--echo # BOOL columns
+--echo ########################
+
+--source type_bool.inc
+--let $col_type = BOOL
+--let $col_default = '0'
+--source col_not_null.inc
+
+--echo ########################
+--echo # CHAR columns
+--echo ########################
+
+--source type_char.inc
+--let $col_type = CHAR
+--let $col_default = '_'
+--source col_not_null.inc
+
+--echo ########################
+--echo # VARCHAR columns
+--echo ########################
+
+--source type_varchar.inc
+--let $col_type = VARCHAR(64)
+--let $col_default = 'test default'
+--source col_not_null.inc
+
+--echo ########################
+--echo # date and time columns
+--echo ########################
+
+--source type_date_time.inc
+
+SET TIMESTAMP=UNIX_TIMESTAMP('2013-12-12 12:12:12');
+
+--let $col_type = DATE
+--let $col_default = '2012-12-21'
+--source col_not_null.inc
+
+--let $col_type = DATETIME
+--let $col_default = '2012-12-21 12:21:12'
+--source col_not_null.inc
+
+# Even with explicit-defaults-for-timestamps, we still can't use
+# the standard include file, due to bug MySQL:68472
+
+--let $col_type = TIMESTAMP
+--let $col_default = '2012-12-21 12:21:12'
+--source col_not_null_timestamp.inc
+
+--let $col_type = TIME
+--let $col_default = '12:21:12'
+--source col_not_null.inc
+
+--let $col_type = YEAR
+--let $col_default = '2012'
+--source col_not_null.inc
+
+--let $col_type = YEAR(2)
+--let $col_default = '12'
+--source col_not_null.inc
+
+--echo ########################
+--echo # ENUM columns
+--echo ########################
+
+--source type_enum.inc
+
+--let $col_type = ENUM('test1','test2','test3')
+--let $col_default = 'test2'
+--source col_not_null.inc
+
+--echo ########################
+--echo # Fixed point columns (NUMERIC, DECIMAL)
+--echo ########################
+
+--source type_fixed.inc
+
+--let $col_type = DECIMAL
+--let $col_default = 1.1
+--source col_not_null.inc
+
+--let $col_type = NUMERIC
+--let $col_default = 0
+--source col_not_null.inc
+
+--echo ########################
+--echo # Floating point columns (FLOAT, DOUBLE)
+--echo ########################
+
+--source type_float.inc
+  
+--let $col_type = FLOAT
+--let $col_default = 1.1
+--source col_not_null.inc
+
+--let $col_type = DOUBLE
+--let $col_default = 0
+--source col_not_null.inc
+
+--echo ########################
+--echo # INT columns
+--echo ########################
+
+--source type_int.inc
+  
+--let $col_type = INT
+--let $col_default = 2147483647
+--source col_not_null.inc
+
+--let $col_type = TINYINT
+--let $col_default = 127
+--source col_not_null.inc
+
+--let $col_type = SMALLINT
+--let $col_default = 0
+--source col_not_null.inc
+
+--let $col_type = MEDIUMINT
+--let $col_default = 1
+--source col_not_null.inc
+
+--let $col_type = BIGINT
+--let $col_default = 9223372036854775807
+--source col_not_null.inc
+
+--echo ########################
+--echo # SET columns
+--echo ########################
+
+--source type_set.inc
+--let $col_type = SET('test1','test2','test3')
+--let $col_default = 'test2,test3'
+--source col_not_null.inc
+
+--echo ########################
+--echo # TEXT columns
+--echo ########################
+
+--source type_text.inc
+
+--let $col_default = ''
+  
+--let $col_type = TEXT
+--source col_not_null.inc
+
+--let $col_type = TINYTEXT
+--source col_not_null.inc
+
+--let $col_type = MEDIUMTEXT
+--source col_not_null.inc
+
+--let $col_type = LONGTEXT
+--source col_not_null.inc
+
+
+--let $col_type =
+--let $col_default =
+--let $extra_col_opts =
+
+
diff --git a/mysql-test/suite/leveldb/col_opt_null.result b/mysql-test/suite/leveldb/col_opt_null.result
new file mode 100644
index 0000000..2af83ee
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_null.result
@@ -0,0 +1,2115 @@
+########################
+# BINARY columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+b BINARY NULL,
+b0 BINARY(0) NULL,
+b1 BINARY(1) NULL,
+b20 BINARY(20) NULL,
+b255 BINARY(255) NULL,
+pk BINARY PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+b	binary(1)	YES		NULL	
+b0	binary(0)	YES		NULL	
+b1	binary(1)	YES		NULL	
+b20	binary(20)	YES		NULL	
+b255	binary(255)	YES		NULL	
+pk	binary(1)	NO	PRI	NULL	
+INSERT INTO t1 VALUES ('','','','','','');
+INSERT INTO t1 VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.','a');
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+HEX(b)	HEX(b0)	HEX(b1)	HEX(b20)	HEX(b255)	HEX(pk)
+00		00	0000000000000000000000000000000000000000	000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000	00
+61		62	616263646566676869206B6C6D6E6F7071727374	4372656174696E6720616E2061727469636C6520666F7220746865204B6E6F776C65646765626173652069732073696D696C617220746F2061736B696E67207175657374696F6E732E2046697273742C206E6176696761746520746F207468652063617465676F727920776865726520796F75206665656C207468652061727469636C652073686F756C642062652E204F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C726561647920657869737420776869636820776F756C6420776F726B2E00000000000000000000000000000000000000000000000000000000000000	61
+INSERT INTO t1 VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256),'b');
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b0' at row 1
+Warning	1265	Data truncated for column 'b1' at row 1
+Warning	1265	Data truncated for column 'b20' at row 1
+Warning	1265	Data truncated for column 'b255' at row 1
+INSERT INTO t1 SELECT b255, b255, b255, b255, CONCAT('a',b255,b255), 'c' FROM t1;
+ERROR 23000: Duplicate entry 'c' for key 'PRIMARY'
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+HEX(b)	HEX(b0)	HEX(b1)	HEX(b20)	HEX(b255)	HEX(pk)
+00		00	0000000000000000000000000000000000000000	000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000	00
+61		61	6161616161616161616161616161616161616161	787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878	62
+61		62	616263646566676869206B6C6D6E6F7071727374	4372656174696E6720616E2061727469636C6520666F7220746865204B6E6F776C65646765626173652069732073696D696C617220746F2061736B696E67207175657374696F6E732E2046697273742C206E6176696761746520746F207468652063617465676F727920776865726520796F75206665656C207468652061727469636C652073686F756C642062652E204F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C726561647920657869737420776869636820776F756C6420776F726B2E00000000000000000000000000000000000000000000000000000000000000	61
+ALTER TABLE t1 ADD COLUMN b257 BINARY(257) NULL;
+ERROR 42000: Column length too big for column 'b257' (max = 255); use BLOB or TEXT instead
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+b	binary(1)	YES		NULL	
+b0	binary(0)	YES		NULL	
+b1	binary(1)	YES		NULL	
+b20	binary(20)	YES		NULL	
+b255	binary(255)	YES		NULL	
+pk	binary(1)	NO	PRI	NULL	
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c BINARY NULL,
+c1 BINARY NULL DEFAULT NULL,
+c2 BINARY NULL DEFAULT 0,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	binary(1)	YES		NULL	
+c1	binary(1)	YES		NULL	
+c2	binary(1)	YES		0	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (0,0,0);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	30	30	30
+3	NULL	NULL	30
+DROP TABLE t1;
+########################
+# VARBINARY columns
+########################
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+v0 VARBINARY(0) NULL,
+v1 VARBINARY(1) NULL,
+v64 VARBINARY(64) NULL,
+v65000 VARBINARY(65000) NULL,
+PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varbinary(0)	YES		NULL	
+v1	varbinary(1)	YES		NULL	
+v64	varbinary(64)	NO	PRI		
+v65000	varbinary(65000)	YES		NULL	
+CREATE TABLE t2 (v VARBINARY(65532) NULL, PRIMARY KEY(v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+Field	Type	Null	Key	Default	Extra
+v	varbinary(65532)	NO	PRI		
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+SELECT HEX(v0), HEX(v1), HEX(v64), HEX(v65000) FROM t1;
+HEX(v0)	HEX(v1)	HEX(v64)	HEX(v65000)
+			
+	79	4F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C7265616479206578697374	486572652069732061206C697374206F66207265636F6D6D656E64656420626F6F6B73206F6E204D61726961444220616E64204D7953514C2E2057652776652070726F7669646564206C696E6B7320746F20416D617A6F6E2E636F6D206865726520666F7220636F6E76656E69656E63652C2062757420746865792063616E20626520666F756E64206174206D616E79206F7468657220626F6F6B73746F7265732C20626F7468206F6E6C696E6520616E64206F66662E0A0A2020496620796F752077616E7420746F206861766520796F7572206661766F72697465204D7953514C202F204D61726961444220626F6F6B206C697374656420686572652C20706C65617365206C65617665206120636F6D6D656E742E0A2020466F7220646576656C6F706572732077686F2077616E7420746F20636F6465206F6E204D617269614442206F72204D7953514C0A0A2020202020202A20556E6465727374616E64696E67204D7953514C20496E7465726E616C73206279205361736861205061636865762C20666F726D6572204D7953514C20646576656C6F706572206174204D7953514C2041422E0A2020202020
 20202020
 2020206F205468697320697320746865206F6E6C7920626F6F6B207765206B6E6F772061626F75742074686174206465736372696265732074686520696E7465726E616C73206F66204D617269614442202F204D7953514C2E2041206D757374206861766520666F7220616E796F6E652077686F2077616E747320746F20756E6465727374616E6420616E6420646576656C6F70206F6E204D617269614442210A2020202020202020202020206F204E6F7420616C6C20746F706963732061726520636F766572656420616E6420736F6D652070617274732061726520736C696768746C79206F757464617465642C20627574207374696C6C20746865206265737420626F6F6B206F6E207468697320746F7069632E200A2020202020202A204D7953514C20352E3120506C7567696E20446576656C6F706D656E742062792053657267656920476F6C75626368696B20616E6420416E64726577204875746368696E67730A2020202020202020202020206F2041206D757374207265616420666F7220616E796F6E652077616E74696E6720746F207772697465206120706C7567696E20666F72204D6172696144422C207772697474656E20627920746865205365726765692077686F2064657369676E65642074686520706C7567696E20696E7465726661636520666F72204
 D7953514
 C20616E64204D61726961444221200A0A2020466F72204D617269614442202F204D7953514C20656E642075736572730A0A2020202020202A204D61726961444220437261736820436F757273652062792042656E20466F7274610A2020202020202020202020206F204669727374204D61726961444220626F6F6B210A2020202020202020202020206F20466F722070656F706C652077686F2077616E7420746F206C6561726E2053514C20616E642074686520626173696373206F66204D6172696144422E0A2020202020202020202020206F204E6F77207368697070696E672E20507572636861736520617420416D617A6F6E2E636F6D206F7220796F7572206661766F7269746520626F6F6B73656C6C65722E200A0A2020202020202A2053514C2D393920436F6D706C6574652C205265616C6C792062792050657465722047756C75747A616E20262054727564792050656C7A65722E0A2020202020202020202020206F2045766572797468696E6720796F752077616E74656420746F206B6E6F772061626F7574207468652053514C203939207374616E646172642E20457863656C6C656E74207265666572656E636520626F6F6B210A2020202020202020202020206F204672656520746F207265616420696E20746865204B6E6F776C656467656261736521200A
 0A202020
 2020202A204D7953514C20283474682045646974696F6E29206279205061756C204475426F69730A2020202020202020202020206F20546865202764656661756C742720626F6F6B20746F207265616420696620796F7520776F6E7420746F206C6561726E20746F20757365204D7953514C202F204D6172696144422E200A0A2020202020202A204D7953514C20436F6F6B626F6F6B206279205061756C204475426F69730A2020202020202020202020206F2041206C6F74206F66206578616D706C6573206F6620686F7720746F20757365204D7953514C2E204173207769746820616C6C206F66205061756C277320626F6F6B732C206974277320776F727468206974732077656967687420696E20676F6C6420616E64206576656E20656E6A6F7961626C652072656164696E6720666F7220737563682061202764727927207375626A6563742E200A0A2020202020202A204869676820506572666F726D616E6365204D7953514C2C205365636F6E642045646974696F6E2C204279204261726F6E20536368776172747A2C205065746572205A6169747365762C20566164696D20546B616368656E6B6F2C204A6572656D7920442E205A61776F646E792C2041726A656E204C656E747A2C20446572656B204A2E2042616C6C696E672C20657420616C2E0A20202020202
 02020202
 020206F20224869676820506572666F726D616E6365204D7953514C2069732074686520646566696E697469766520677569646520746F206275696C64696E6720666173742C2072656C6961626C652073797374656D732077697468204D7953514C2E205772697474656E206279206E6F74656420657870657274732077697468207965617273206F66207265616C2D776F726C6420657870657269656E6365206275696C64696E672076657279206C617267652073797374656D732C207468697320626F6F6B20636F7665727320657665727920617370656374206F66204D7953514C20706572666F726D616E636520696E2064657461696C2C20616E6420666F6375736573206F6E20726F627573746E6573732C2073656375726974792C20616E64206461746120696E746567726974792E204C6561726E20616476616E63656420746563686E697175657320696E20646570746820736F20796F752063616E206272696E67206F7574204D7953514C27732066756C6C20706F7765722E22202846726F6D2074686520626F6F6B206465736372697074696F6E206174204F275265696C6C7929200A0A2020202020202A204D7953514C2041646D696E20436F6F6B626F6F6B0A2020202020202020202020206F204120717569636B20737465702D62792D7374657020677569
 64652066
 6F72204D7953514C20757365727320616E642064617461626173652061646D696E6973747261746F727320746F207461636B6C65207265616C2D776F726C64206368616C6C656E6765732077697468204D7953514C20636F6E66696775726174696F6E20616E642061646D696E697374726174696F6E200A0A2020202020202A204D7953514C20352E302043657274696669636174696F6E2053747564792047756964652C204279205061756C204475426F69732C2053746566616E2048696E7A2C204361727374656E20506564657273656E0A2020202020202020202020206F205468697320697320746865206F6666696369616C20677569646520746F20636F766572207468652070617373696E67206F66207468652074776F204D7953514C2043657274696669636174696F6E206578616D696E6174696F6E732E2049742069732076616C69642074696C6C2076657273696F6E20352E30206F6620746865207365727665722C20736F207768696C65206974206D697373657320616C6C2074686520666561747572657320617661696C61626C6520696E204D7953514C20352E3120616E6420677265617465722028696E636C7564696E67204D61726961444220352E3120616E642067726561746572292C2069742070726F7669646573206120676F6F6420626173696
 320756E6
 465727374616E64696E67206F66204D7953514C20666F722074686520656E642D757365722E20
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 1
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'v64' at row 1
+Warning	1265	Data truncated for column 'v65000' at row 1
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 5
+Warning	1265	Data truncated for column 'v1' at row 5
+Warning	1265	Data truncated for column 'v64' at row 5
+Warning	1265	Data truncated for column 'v0' at row 6
+Warning	1265	Data truncated for column 'v1' at row 6
+Warning	1265	Data truncated for column 'v64' at row 6
+Warning	1265	Data truncated for column 'v65000' at row 6
+SELECT HEX(v0), HEX(v1), HEX(v64), LENGTH(HEX(v65000)) FROM t1;
+HEX(v0)	HEX(v1)	HEX(v64)	LENGTH(HEX(v65000))
+			0
+		61	0
+	48	61486572652069732061206C697374206F66207265636F6D6D656E64656420626F6F6B73206F6E204D61726961444220616E64204D7953514C2E205765277665	5932
+	61	61616263646566676869206162636465666768692061626364656667686920616263646566676869206162636465666768692061626364656667686920616263	130000
+	79	4F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C7265616479206578697374	5930
+	79	63636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363	130000
+ALTER TABLE t1 ADD COLUMN v65536 VARBINARY(65536) NULL;
+Warnings:
+Note	1246	Converting column 'v65536' from VARBINARY to BLOB
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varbinary(0)	YES		NULL	
+v1	varbinary(1)	YES		NULL	
+v64	varbinary(64)	NO	PRI		
+v65000	varbinary(65000)	YES		NULL	
+v65536	mediumblob	YES		NULL	
+DROP TABLE t1, t2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c VARBINARY(64) NULL,
+c1 VARBINARY(64) NULL DEFAULT NULL,
+c2 VARBINARY(64) NULL DEFAULT 'test',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	varbinary(64)	YES		NULL	
+c1	varbinary(64)	YES		NULL	
+c2	varbinary(64)	YES		test	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('test','test','test');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	74657374	74657374	74657374
+3	NULL	NULL	74657374
+DROP TABLE t1;
+########################
+# BIT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a BIT NULL,
+b BIT(20) NULL,
+c BIT(64) NULL,
+d BIT(1) NULL,
+PRIMARY KEY (c)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	bit(1)	YES		NULL	
+b	bit(20)	YES		NULL	
+c	bit(64)	NO	PRI	b'0'	
+d	bit(1)	YES		NULL	
+ALTER TABLE t1 DROP COLUMN d;
+ALTER TABLE t1 ADD COLUMN d BIT(0) NULL;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	bit(1)	YES		NULL	
+b	bit(20)	YES		NULL	
+c	bit(64)	NO	PRI	b'0'	
+d	bit(1)	YES		NULL	
+INSERT INTO t1 (a,b,c,d) VALUES (0,POW(2,20)-1,b'1111111111111111111111111111111111111111111111111111111111111111',1);
+SELECT BIN(a), HEX(b), c+0 FROM t1 WHERE d>0;
+BIN(a)	HEX(b)	c+0
+0	FFFFF	18446744073709551615
+INSERT INTO t1 (a,b,c,d) VALUES (1,0,-2,0);
+SELECT a+0, b+0, c+0 FROM t1 WHERE d<100;
+a+0	b+0	c+0
+0	1048575	18446744073709551615
+1	0	18446744073709551614
+INSERT INTO t1 (a,b,c,d) VALUES (b'1', 'f', 0xFF, 0x0);
+SELECT a+0, b+0, c+0 FROM t1 WHERE d IN (0, 2);
+a+0	b+0	c+0
+1	0	18446744073709551614
+1	102	255
+DELETE FROM t1;
+INSERT INTO t1 (a,b,c,d) VALUES (0x10,0,0,1);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+a+0	b+0	c+0	d+0
+1	0	0	1
+INSERT INTO t1 (a,b,c,d) VALUES (0x01,0,0x10000000000000000,0);
+Warnings:
+Warning	1264	Out of range value for column 'c' at row 1
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+a+0	b+0	c+0	d+0
+1	0	0	1
+1	0	18446744073709551615	0
+DROP TABLE t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a BIT(65) NULL) ENGINE=LevelDB;
+ERROR 42000: Display width out of range for column 'a' (max = 64)
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c BIT NULL,
+c1 BIT NULL DEFAULT NULL,
+c2 BIT NULL DEFAULT 1,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	bit(1)	YES		NULL	
+c1	bit(1)	YES		NULL	
+c2	bit(1)	YES		b'1'	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (1,1,1);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	1	1	1
+3	NULL	NULL	1
+DROP TABLE t1;
+########################
+# BLOB columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+b BLOB NULL,
+b0 BLOB(0) NULL,
+b1 BLOB(1) NULL,
+b300 BLOB(300) NULL,
+bm BLOB(65535) NULL,
+b70k BLOB(70000) NULL,
+b17m BLOB(17000000) NULL,
+t TINYBLOB NULL,
+m MEDIUMBLOB NULL,
+l LONGBLOB NULL
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+b	blob	YES		NULL	
+b0	blob	YES		NULL	
+b1	tinyblob	YES		NULL	
+b300	blob	YES		NULL	
+bm	blob	YES		NULL	
+b70k	mediumblob	YES		NULL	
+b17m	longblob	YES		NULL	
+t	tinyblob	YES		NULL	
+m	mediumblob	YES		NULL	
+l	longblob	YES		NULL	
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), HEX(REPEAT('g',1048576)), REPEAT('h',255), REPEAT('i',1048576), HEX(REPEAT('j',1048576)) );
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(b)	LENGTH(b0)	LENGTH(b1)	LENGTH(b300)	LENGTH(bm)	LENGTH(b70k)	LENGTH(b17m)	LENGTH(t)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	2097152	255	1048576	2097152
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b0' at row 1
+Warning	1265	Data truncated for column 'b1' at row 1
+Warning	1265	Data truncated for column 'b300' at row 1
+Warning	1265	Data truncated for column 'bm' at row 1
+Warning	1265	Data truncated for column 't' at row 1
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(b)	LENGTH(b0)	LENGTH(b1)	LENGTH(b300)	LENGTH(bm)	LENGTH(b70k)	LENGTH(b17m)	LENGTH(t)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+65535	65535	255	65535	65535	1048576	2097152	255	1048576	2097152
+ALTER TABLE t1 ADD COLUMN bbb BLOB(4294967296);
+ERROR 42000: Display width out of range for column 'bbb' (max = 4294967295)
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c BLOB NULL,
+c1 BLOB NULL DEFAULT NULL,
+c2 BLOB NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	blob	YES		NULL	
+c1	blob	YES		NULL	
+c2	blob	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c TINYBLOB NULL,
+c1 TINYBLOB NULL DEFAULT NULL,
+c2 TINYBLOB NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	tinyblob	YES		NULL	
+c1	tinyblob	YES		NULL	
+c2	tinyblob	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c MEDIUMBLOB NULL,
+c1 MEDIUMBLOB NULL DEFAULT NULL,
+c2 MEDIUMBLOB NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	mediumblob	YES		NULL	
+c1	mediumblob	YES		NULL	
+c2	mediumblob	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c LONGBLOB NULL,
+c1 LONGBLOB NULL DEFAULT NULL,
+c2 LONGBLOB NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	longblob	YES		NULL	
+c1	longblob	YES		NULL	
+c2	longblob	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+########################
+# BOOL columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+b1 BOOL NULL,
+b2 BOOLEAN NULL
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+b1	tinyint(1)	YES		NULL	
+b2	tinyint(1)	YES		NULL	
+INSERT INTO t1 (b1,b2) VALUES (1,TRUE);
+SELECT b1,b2 FROM t1;
+b1	b2
+1	1
+INSERT INTO t1 (b1,b2) VALUES (FALSE,0);
+SELECT b1,b2 FROM t1;
+b1	b2
+0	0
+1	1
+INSERT INTO t1 (b1,b2) VALUES (2,3);
+SELECT b1,b2 FROM t1;
+b1	b2
+0	0
+1	1
+2	3
+INSERT INTO t1 (b1,b2) VALUES (-1,-2);
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+1	1
+2	3
+SELECT IF(b1,'true','false') AS a, IF(b2,'true','false') AS b FROM t1;
+a	b
+false	false
+true	true
+true	true
+true	true
+SELECT b1,b2 FROM t1 WHERE b1 = TRUE;
+b1	b2
+1	1
+SELECT b1,b2 FROM t1 WHERE b2 = FALSE;
+b1	b2
+0	0
+INSERT INTO t1 (b1,b2) VALUES ('a','b');
+Warnings:
+Warning	1366	Incorrect integer value: 'a' for column 'b1' at row 1
+Warning	1366	Incorrect integer value: 'b' for column 'b2' at row 1
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+0	0
+1	1
+2	3
+INSERT INTO t1 (b1,b2) VALUES (128,-129);
+Warnings:
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b2' at row 1
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+0	0
+1	1
+127	-128
+2	3
+ALTER TABLE t1 ADD COLUMN b3 BOOLEAN UNSIGNED NULL;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNSIGNED NULL' at line 1
+ALTER TABLE ADD COLUMN b3 BOOL ZEROFILL NULL;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ADD COLUMN b3 BOOL ZEROFILL NULL' at line 1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c BOOL NULL,
+c1 BOOL NULL DEFAULT NULL,
+c2 BOOL NULL DEFAULT '0',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	tinyint(1)	YES		NULL	
+c1	tinyint(1)	YES		NULL	
+c2	tinyint(1)	YES		0	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('0','0','0');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	0	0	0
+3	NULL	NULL	0
+DROP TABLE t1;
+########################
+# CHAR columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c CHAR NULL,
+c0 CHAR(0) NULL,
+c1 CHAR(1) NULL,
+c20 CHAR(20) NULL,
+c255 CHAR(255) NULL,
+PRIMARY KEY (c255)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	char(1)	YES		NULL	
+c0	char(0)	YES		NULL	
+c1	char(1)	YES		NULL	
+c20	char(20)	YES		NULL	
+c255	char(255)	NO	PRI		
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('','','','','');
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.');
+SELECT c,c0,c1,c20,c255 FROM t1;
+c	c0	c1	c20	c255
+				
+a		b	abcdefghi klmnopqrst	Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256));
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 1
+Warning	1265	Data truncated for column 'c0' at row 1
+Warning	1265	Data truncated for column 'c1' at row 1
+Warning	1265	Data truncated for column 'c20' at row 1
+Warning	1265	Data truncated for column 'c255' at row 1
+INSERT INTO t1 (c,c0,c1,c20,c255) SELECT c255, c255, c255, c255, CONCAT('a',c255,c1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 5
+Warning	1265	Data truncated for column 'c0' at row 5
+Warning	1265	Data truncated for column 'c1' at row 5
+Warning	1265	Data truncated for column 'c20' at row 5
+Warning	1265	Data truncated for column 'c' at row 6
+Warning	1265	Data truncated for column 'c0' at row 6
+Warning	1265	Data truncated for column 'c1' at row 6
+Warning	1265	Data truncated for column 'c20' at row 6
+Warning	1265	Data truncated for column 'c255' at row 6
+SELECT c,c0,c1,c20,c255 FROM t1;
+c	c0	c1	c20	c255
+				
+				a
+C		C	Creating an article	aCreating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.b
+a		a	aaaaaaaaaaaaaaaaaaaa	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+a		b	abcdefghi klmnopqrst	Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.
+x		x	xxxxxxxxxxxxxxxxxxxx	axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+SELECT DISTINCT c20, REPEAT('a',LENGTH(c20)), COUNT(*) FROM t1 GROUP BY c1, c20;
+c20	REPEAT('a',LENGTH(c20))	COUNT(*)
+		2
+Creating an article	aaaaaaaaaaaaaaaaaaa	1
+aaaaaaaaaaaaaaaaaaaa	aaaaaaaaaaaaaaaaaaaa	1
+abcdefghi klmnopqrst	aaaaaaaaaaaaaaaaaaaa	1
+xxxxxxxxxxxxxxxxxxxx	aaaaaaaaaaaaaaaaaaaa	1
+ALTER TABLE t1 ADD COLUMN c257 CHAR(257) NULL;
+ERROR 42000: Column length too big for column 'c257' (max = 255); use BLOB or TEXT instead
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c CHAR NULL,
+c1 CHAR NULL DEFAULT NULL,
+c2 CHAR NULL DEFAULT '_',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	char(1)	YES		NULL	
+c1	char(1)	YES		NULL	
+c2	char(1)	YES		_	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('_','_','_');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	5F	5F	5F
+3	NULL	NULL	5F
+DROP TABLE t1;
+########################
+# VARCHAR columns
+########################
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+v0 VARCHAR(0) NULL,
+v1 VARCHAR(1) NULL,
+v64 VARCHAR(64) NULL,
+v65000 VARCHAR(65000) NULL,
+PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varchar(0)	YES		NULL	
+v1	varchar(1)	YES		NULL	
+v64	varchar(64)	NO	PRI		
+v65000	varchar(65000)	YES		NULL	
+CREATE TABLE t2 (v VARCHAR(65532), PRIMARY KEY (v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+Field	Type	Null	Key	Default	Extra
+v	varchar(65532)	NO	PRI		
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+SELECT v0,v1,v64,v65000 FROM t1;
+v0	v1	v64	v65000
+
+
+
+
+
+
+
+
+
+
+			
+	y	Once there, double check that an article doesn't already exist	Here is a list of recommended books on MariaDB and MySQL. We've provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+            o "High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL's full power." (From the book description at O'Reilly) 
+            o A lot of examples of how to use MySQL. As with all of Paul's books, it's worth its weight in gold and even enjoyable reading for such a 'dry' subject. 
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Free to read in the Knowledgebase! 
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+            o The 'default' book to read if you wont to learn to use MySQL / MariaDB. 
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. 
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+      * MariaDB Crash Course by Ben Forta
+      * MySQL (4th Edition) by Paul DuBois
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+      * MySQL Admin Cookbook
+      * MySQL Cookbook by Paul DuBois
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+  For MariaDB / MySQL end users
+  For developers who want to code on MariaDB or MySQL
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 1
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'v64' at row 1
+Warning	1265	Data truncated for column 'v65000' at row 1
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 5
+Warning	1265	Data truncated for column 'v1' at row 5
+Warning	1265	Data truncated for column 'v64' at row 5
+Warning	1265	Data truncated for column 'v65000' at row 5
+Warning	1265	Data truncated for column 'v0' at row 6
+Warning	1265	Data truncated for column 'v1' at row 6
+Warning	1265	Data truncated for column 'v64' at row 6
+SELECT v0, v1, v64, LENGTH(v65000) FROM t1;
+v0	v1	v64	LENGTH(v65000)
+			0
+		a	0
+	H	aHere is a list of recommended books on MariaDB and MySQL. We've	2966
+	a	aabcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abc	65000
+	y	Once there, double check that an article doesn't already exist	2965
+	y	cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc	65000
+ALTER TABLE t1 ADD COLUMN v65536 VARCHAR(65536) NULL;
+Warnings:
+Note	1246	Converting column 'v65536' from VARCHAR to TEXT
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varchar(0)	YES		NULL	
+v1	varchar(1)	YES		NULL	
+v64	varchar(64)	NO	PRI		
+v65000	varchar(65000)	YES		NULL	
+v65536	mediumtext	YES		NULL	
+DROP TABLE t1, t2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c VARCHAR(64) NULL,
+c1 VARCHAR(64) NULL DEFAULT NULL,
+c2 VARCHAR(64) NULL DEFAULT 'test default',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	varchar(64)	YES		NULL	
+c1	varchar(64)	YES		NULL	
+c2	varchar(64)	YES		test default	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('test default','test default','test default');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	746573742064656661756C74	746573742064656661756C74	746573742064656661756C74
+3	NULL	NULL	746573742064656661756C74
+DROP TABLE t1;
+########################
+# date and time columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DATE NULL,
+dt DATETIME NULL,
+ts TIMESTAMP NULL,
+t TIME NULL,
+y YEAR NULL,
+y4 YEAR(4) NULL,
+y2 YEAR(2) NULL,
+pk DATETIME PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	date	YES		NULL	
+dt	datetime	YES		NULL	
+ts	timestamp	YES		NULL	
+t	time	YES		NULL	
+y	year(4)	YES		NULL	
+y4	year(4)	YES		NULL	
+y2	year(4)	YES		NULL	
+pk	datetime	NO	PRI	NULL	
+SET @tm = '2012-04-09 05:27:00';
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('1000-01-01', '1000-01-01 00:00:00', FROM_UNIXTIME(1), '-838:59:59', '1901', '1901', '00','2012-12-12 12:12:12'),
+('9999-12-31', '9999-12-31 23:59:59', FROM_UNIXTIME(2147483647), '838:59:59', '2155', '2155', '99','2012-12-12 12:12:13'),
+('0000-00-00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '00:00:00', '0', '0', '0','2012-12-12 12:12:14'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),YEAR(@tm),YEAR(@tm),'2012-12-12 12:12:15');
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+d	dt	ts	t	y	y4	y2
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	00:00:00	2000	2000	2000
+1000-01-01	1000-01-01 00:00:00	1970-01-01 03:00:01	-838:59:59	1901	1901	2000
+2012-04-09	2012-04-09 05:27:00	2012-04-09 05:27:00	05:27:00	2012	2012	2012
+9999-12-31	9999-12-31 23:59:59	2038-01-19 06:14:07	838:59:59	2155	2155	1999
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('999-13-32', '999-11-31 00:00:00', '0', '-839:00:00', '1900', '1900', '-1','2012-12-12 12:12:16');
+Warnings:
+Warning	1265	Data truncated for column 'd' at row 1
+Warning	1264	Out of range value for column 'dt' at row 1
+Warning	1264	Out of range value for column 'ts' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 'y' at row 1
+Warning	1264	Out of range value for column 'y4' at row 1
+Warning	1264	Out of range value for column 'y2' at row 1
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+d	dt	ts	t	y	y4	y2
+1000-01-01	1000-01-01 00:00:00	1970-01-01 03:00:01	-838:59:59	1901	1901	2000
+9999-12-31	9999-12-31 23:59:59	2038-01-19 06:14:07	838:59:59	2155	2155	1999
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	00:00:00	2000	2000	2000
+2012-04-09	2012-04-09 05:27:00	2012-04-09 05:27:00	05:27:00	2012	2012	2012
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	-838:59:59	0000	0000	0000
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c DATE NULL,
+c1 DATE NULL DEFAULT NULL,
+c2 DATE NULL DEFAULT '2012-12-21',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	date	YES		NULL	
+c1	date	YES		NULL	
+c2	date	YES		2012-12-21	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('2012-12-21','2012-12-21','2012-12-21');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	323031322D31322D3231	323031322D31322D3231	323031322D31322D3231
+3	NULL	NULL	323031322D31322D3231
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c DATETIME NULL,
+c1 DATETIME NULL DEFAULT NULL,
+c2 DATETIME NULL DEFAULT '2012-12-21 12:21:12',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	datetime	YES		NULL	
+c1	datetime	YES		NULL	
+c2	datetime	YES		2012-12-21 12:21:12	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('2012-12-21 12:21:12','2012-12-21 12:21:12','2012-12-21 12:21:12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	323031322D31322D32312031323A32313A3132	323031322D31322D32312031323A32313A3132	323031322D31322D32312031323A32313A3132
+3	NULL	NULL	323031322D31322D32312031323A32313A3132
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c TIMESTAMP NULL,
+c1 TIMESTAMP NULL DEFAULT NULL,
+c2 TIMESTAMP NULL DEFAULT '2012-12-21 12:21:12',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	timestamp	YES		NULL	
+c1	timestamp	YES		NULL	
+c2	timestamp	YES		2012-12-21 12:21:12	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('2012-12-21 12:21:12','2012-12-21 12:21:12','2012-12-21 12:21:12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	323031322D31322D32312031323A32313A3132	323031322D31322D32312031323A32313A3132	323031322D31322D32312031323A32313A3132
+3	NULL	NULL	323031322D31322D32312031323A32313A3132
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c TIME NULL,
+c1 TIME NULL DEFAULT NULL,
+c2 TIME NULL DEFAULT '12:21:12',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	time	YES		NULL	
+c1	time	YES		NULL	
+c2	time	YES		12:21:12	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('12:21:12','12:21:12','12:21:12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	31323A32313A3132	31323A32313A3132	31323A32313A3132
+3	NULL	NULL	31323A32313A3132
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c YEAR NULL,
+c1 YEAR NULL DEFAULT NULL,
+c2 YEAR NULL DEFAULT '2012',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	year(4)	YES		NULL	
+c1	year(4)	YES		NULL	
+c2	year(4)	YES		2012	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('2012','2012','2012');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	7DC	7DC	7DC
+3	NULL	NULL	7DC
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c YEAR(2) NULL,
+c1 YEAR(2) NULL DEFAULT NULL,
+c2 YEAR(2) NULL DEFAULT '12',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	year(4)	YES		NULL	
+c1	year(4)	YES		NULL	
+c2	year(4)	YES		2012	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('12','12','12');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	7DC	7DC	7DC
+3	NULL	NULL	7DC
+DROP TABLE t1;
+########################
+# ENUM columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a ENUM('') NULL,
+b ENUM('test1','test2','test3','test4','test5') NULL,
+c ENUM('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o
 ','5p','
 5q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75') NULL,
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	enum('')	YES		NULL	
+b	enum('test1','test2','test3','test4','test5')	NO	PRI	test1	
+c	enum('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o'
 ,'5p','5
 q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75')	YES		NULL	
+INSERT INTO t1 (a,b,c) VALUES ('','test2','4'),('',5,2);
+SELECT a,b,c FROM t1;
+a	b	c
+	test2	4
+	test5	2
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+Warnings:
+Warning	1265	Data truncated for column 'a' at row 1
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+		
+	test2	4
+	test5	2
+ALTER TABLE t1 ADD COLUMN e ENUM('a','A') NULL;
+Warnings:
+Note	1291	Column 'e' has duplicated value 'a' in ENUM
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	enum('')	YES		NULL	
+b	enum('test1','test2','test3','test4','test5')	NO	PRI	test1	
+c	enum('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o'
 ,'5p','5
 q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75')	YES		NULL	
+e	enum('a','A')	YES		NULL	
+INSERT INTO t1 (a,b,c,e) VALUES ('','test3','75','A');
+SELECT a,b,c,e FROM t1;
+a	b	c	e
+			NULL
+	test2	4	NULL
+	test3	75	a
+	test5	2	NULL
+SELECT a,b,c,e FROM t1 WHERE b='test2' OR a != '';
+a	b	c	e
+	test2	4	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c ENUM('test1','test2','test3') NULL,
+c1 ENUM('test1','test2','test3') NULL DEFAULT NULL,
+c2 ENUM('test1','test2','test3') NULL DEFAULT 'test2',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	enum('test1','test2','test3')	YES		NULL	
+c1	enum('test1','test2','test3')	YES		NULL	
+c2	enum('test1','test2','test3')	YES		test2	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('test2','test2','test2');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	7465737432	7465737432	7465737432
+3	NULL	NULL	7465737432
+DROP TABLE t1;
+########################
+# Fixed point columns (NUMERIC, DECIMAL)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DECIMAL NULL,
+d0 DECIMAL(0) NULL,
+d1_1 DECIMAL(1,1) NULL,
+d10_2 DECIMAL(10,2) NULL,
+d60_10 DECIMAL(60,10) NULL,
+n NUMERIC NULL,
+n0_0 NUMERIC(0,0) NULL,
+n1 NUMERIC(1) NULL,
+n20_4 NUMERIC(20,4) NULL,
+n65_4 NUMERIC(65,4) NULL,
+pk NUMERIC NULL PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	decimal(10,0)	YES		NULL	
+d0	decimal(10,0)	YES		NULL	
+d1_1	decimal(1,1)	YES		NULL	
+d10_2	decimal(10,2)	YES		NULL	
+d60_10	decimal(60,10)	YES		NULL	
+n	decimal(10,0)	YES		NULL	
+n0_0	decimal(10,0)	YES		NULL	
+n1	decimal(1,0)	YES		NULL	
+n20_4	decimal(20,4)	YES		NULL	
+n65_4	decimal(65,4)	YES		NULL	
+pk	decimal(10,0)	NO	PRI	NULL	
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (100,123456,0.3,40000.25,123456789123456789.10001,1024,7000.0,8.0,999999.9,9223372036854775807,1);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.0,9999999999.0,0.9,99999999.99,99999999999999999999999999999999999999999999999999.9999999999,9999999999.0,9999999999.0,9.0,9999999999999999.9999,9999999999999999999999999999999999999999999999999999999999999.9999,3);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-100,-123456,-0.3,-40000.25,-123456789123456789.10001,-1024,-7000.0,-8.0,-999999.9,-9223372036854775807,4);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-9999999999.0,-9999999999.0,-0.9,-99999999.99,-99999999999999999999999999999999999999999999999999.9999999999,-9999999999.0,-9999999999.0,-9.0,-9999999999999999.9999,-9999999999999999999999999999999999999999999999999999999999999.9999,5);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1 WHERE n20_4 = 9999999999999999.9999 OR d < 100;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+6
+);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (10000000000.0,10000000000.0,1.1,100000000.99,100000000000000000000000000000000000000000000000000.0,10000000000.0,10000000000.0,10.0,10000000000000000.9999,10000000000000000000000000000000000000000000000000000000000000.9999,7);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.1,9999999999.1,1.9,99999999.001,99999999999999999999999999999999999999999999999999.99999999991,9999999999.1,9999999999.1,9.1,9999999999999999.00001,9999999999999999999999999999999999999999999999999999999999999.11111,8);
+Warnings:
+Note	1265	Data truncated for column 'd' at row 1
+Note	1265	Data truncated for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Note	1265	Data truncated for column 'd10_2' at row 1
+Note	1265	Data truncated for column 'd60_10' at row 1
+Note	1265	Data truncated for column 'n' at row 1
+Note	1265	Data truncated for column 'n0_0' at row 1
+Note	1265	Data truncated for column 'n1' at row 1
+Note	1265	Data truncated for column 'n20_4' at row 1
+Note	1265	Data truncated for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.00	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.0000	9999999999999999999999999999999999999999999999999999999999999.1111
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+ALTER TABLE t1 ADD COLUMN n66 NUMERIC(66) NULL;
+ERROR 42000: Too big precision 66 specified for column 'n66'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(66,6) NULL;
+ERROR 42000: Too big precision 66 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(66,66) NULL;
+ERROR 42000: Too big scale 66 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c DECIMAL NULL,
+c1 DECIMAL NULL DEFAULT NULL,
+c2 DECIMAL NULL DEFAULT 1.1,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Note	1265	Data truncated for column 'c2' at row 1
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	decimal(10,0)	YES		NULL	
+c1	decimal(10,0)	YES		NULL	
+c2	decimal(10,0)	YES		1	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (1.1,1.1,1.1);
+Warnings:
+Note	1265	Data truncated for column 'c' at row 1
+Note	1265	Data truncated for column 'c1' at row 1
+Note	1265	Data truncated for column 'c2' at row 1
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	1	1	1
+3	NULL	NULL	1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c NUMERIC NULL,
+c1 NUMERIC NULL DEFAULT NULL,
+c2 NUMERIC NULL DEFAULT 0 ,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	decimal(10,0)	YES		NULL	
+c1	decimal(10,0)	YES		NULL	
+c2	decimal(10,0)	YES		0	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (0 ,0 ,0 );
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	0	0	0
+3	NULL	NULL	0
+DROP TABLE t1;
+########################
+# Floating point columns (FLOAT, DOUBLE)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+f FLOAT NULL,
+f0 FLOAT(0) NULL,
+r1_1 REAL(1,1) NULL,
+f23_0 FLOAT(23) NULL,
+f20_3 FLOAT(20,3) NULL,
+d DOUBLE NULL,
+d1_0 DOUBLE(1,0) NULL,
+d10_10 DOUBLE PRECISION (10,10) NULL,
+d53 DOUBLE(53,0) NULL,
+d53_10 DOUBLE(53,10) NULL,
+pk DOUBLE NULL PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+f	float	YES		NULL	
+f0	float	YES		NULL	
+r1_1	double(1,1)	YES		NULL	
+f23_0	float	YES		NULL	
+f20_3	float(20,3)	YES		NULL	
+d	double	YES		NULL	
+d1_0	double(1,0)	YES		NULL	
+d10_10	double(10,10)	YES		NULL	
+d53	double(53,0)	YES		NULL	
+d53_10	double(53,10)	YES		NULL	
+pk	double	NO	PRI	NULL	
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	11111111.111
+d10_10	0.0123456789
+d1_0	8
+d53	1234566789123456800
+d53_10	100000000000000000.0000000000
+f0	12345.1
+f20_3	56789.988
+f23_0	123457000
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+99999999999999999999999999999999999999,
+99999999999999999999999999999999999999.9999999999999999,
+0.9,
+99999999999999999999999999999999999999.9,
+99999999999999999.999,
+999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+9,
+0.9999999999, 
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+3
+);
+Warnings:
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	11111111.111
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	8
+d1_0	9
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	1e38
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+SELECT MAX(f), MAX(f0), MAX(r1_1), MAX(f23_0), MAX(f20_3), MAX(d), MAX(d1_0), MAX(d10_10), MAX(d53), MAX(d53_10) FROM t1;
+MAX(f)	9.999999680285692e37
+MAX(d)	1e81
+MAX(d10_10)	0.9999999999
+MAX(d1_0)	9
+MAX(d53)	100000000000000000000000000000000000000000000000000000
+MAX(d53_10)	10000000000000000000000000000000000000000000.0000000000
+MAX(f0)	9.999999680285692e37
+MAX(f20_3)	99999998430674940.000
+MAX(f23_0)	9.999999680285692e37
+MAX(r1_1)	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+5
+);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e61
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f	3.40282e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+999999999999999999999999999999999999999,
+999999999999999999999999999999999999999.9999999999999999,
+1.9,
+999999999999999999999999999999999999999.9,
+999999999999999999.999,
+9999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+99,
+1.9999999999,
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+6
+);
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e61
+d	1e65
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f	3.40282e38
+f	3.40282e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f0	3.40282e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+f23_0	3.40282e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+ALTER TABLE t1 ADD COLUMN d0_0 DOUBLE(0,0) NULL;
+ERROR 42000: Display width out of range for column 'd0_0' (max = 255)
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(256,1) NULL;
+ERROR 42000: Too big precision 256 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(40,35) NULL;
+ERROR 42000: Too big scale 35 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c FLOAT NULL,
+c1 FLOAT NULL DEFAULT NULL,
+c2 FLOAT NULL DEFAULT 1.1 ,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	float	YES		NULL	
+c1	float	YES		NULL	
+c2	float	YES		1.1	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (1.1 ,1.1 ,1.1 );
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	1	1	1
+3	NULL	NULL	1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c DOUBLE NULL,
+c1 DOUBLE NULL DEFAULT NULL,
+c2 DOUBLE NULL DEFAULT 0  ,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	double	YES		NULL	
+c1	double	YES		NULL	
+c2	double	YES		0	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (0  ,0  ,0  );
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	0	0	0
+3	NULL	NULL	0
+DROP TABLE t1;
+########################
+# INT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+i INT NULL,
+i0 INT(0) NULL,
+i1 INT(1) NULL,
+i20 INT(20) NULL,
+t TINYINT NULL,
+t0 TINYINT(0) NULL,
+t1 TINYINT(1) NULL,
+t20 TINYINT(20) NULL,
+s SMALLINT NULL,
+s0 SMALLINT(0) NULL,
+s1 SMALLINT(1) NULL,
+s20 SMALLINT(20) NULL,
+m MEDIUMINT NULL,
+m0 MEDIUMINT(0) NULL,
+m1 MEDIUMINT(1) NULL,
+m20 MEDIUMINT(20) NULL,
+b BIGINT NULL,
+b0 BIGINT(0) NULL,
+b1 BIGINT(1) NULL,
+b20 BIGINT(20) NULL,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+i	int(11)	YES		NULL	
+i0	int(11)	YES		NULL	
+i1	int(1)	YES		NULL	
+i20	int(20)	YES		NULL	
+t	tinyint(4)	YES		NULL	
+t0	tinyint(4)	YES		NULL	
+t1	tinyint(1)	YES		NULL	
+t20	tinyint(20)	YES		NULL	
+s	smallint(6)	YES		NULL	
+s0	smallint(6)	YES		NULL	
+s1	smallint(1)	YES		NULL	
+s20	smallint(20)	YES		NULL	
+m	mediumint(9)	YES		NULL	
+m0	mediumint(9)	YES		NULL	
+m1	mediumint(1)	YES		NULL	
+m20	mediumint(20)	YES		NULL	
+b	bigint(20)	YES		NULL	
+b0	bigint(20)	YES		NULL	
+b1	bigint(1)	YES		NULL	
+b20	bigint(20)	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (2147483647,2147483647,2147483647,2147483647,127,127,127,127,32767,32767,32767,32767,8388607,8388607,8388607,8388607,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483648,-2147483648,-2147483648,-2147483648,-128,-128,-128,-128,-32768,-32768,-32768,-32768,-8388608,-8388608,-8388608,-8388608,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967295,4294967295,4294967295,4294967295,255,255,255,255,65535,65535,65535,65535,16777215,16777215,16777215,16777215,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483649,-2147483649,-2147483649,-2147483649,-129,-129,-129,-129,-32769,-32769,-32769,-32769,-8388609,-8388609,-8388609,-8388609,-9223372036854775809,-9223372036854775809,-9223372036854775809,-9223372036854775809);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967296,4294967296,4294967296,4294967296,256,256,256,256,65536,65536,65536,65536,16777216,16777216,16777216,16777216,18446744073709551616,18446744073709551616,18446744073709551616,18446744073709551616);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) SELECT b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b FROM t1 WHERE b IN (-9223372036854775808,9223372036854775807,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 8
+Warning	1264	Out of range value for column 'i0' at row 8
+Warning	1264	Out of range value for column 'i1' at row 8
+Warning	1264	Out of range value for column 'i20' at row 8
+Warning	1264	Out of range value for column 't' at row 8
+Warning	1264	Out of range value for column 't0' at row 8
+Warning	1264	Out of range value for column 't1' at row 8
+Warning	1264	Out of range value for column 't20' at row 8
+Warning	1264	Out of range value for column 's' at row 8
+Warning	1264	Out of range value for column 's0' at row 8
+Warning	1264	Out of range value for column 's1' at row 8
+Warning	1264	Out of range value for column 's20' at row 8
+Warning	1264	Out of range value for column 'm' at row 8
+Warning	1264	Out of range value for column 'm0' at row 8
+Warning	1264	Out of range value for column 'm1' at row 8
+Warning	1264	Out of range value for column 'm20' at row 8
+Warning	1264	Out of range value for column 'i' at row 9
+Warning	1264	Out of range value for column 'i0' at row 9
+Warning	1264	Out of range value for column 'i1' at row 9
+Warning	1264	Out of range value for column 'i20' at row 9
+Warning	1264	Out of range value for column 't' at row 9
+Warning	1264	Out of range value for column 't0' at row 9
+Warning	1264	Out of range value for column 't1' at row 9
+Warning	1264	Out of range value for column 't20' at row 9
+Warning	1264	Out of range value for column 's' at row 9
+Warning	1264	Out of range value for column 's0' at row 9
+Warning	1264	Out of range value for column 's1' at row 9
+Warning	1264	Out of range value for column 's20' at row 9
+Warning	1264	Out of range value for column 'm' at row 9
+Warning	1264	Out of range value for column 'm0' at row 9
+Warning	1264	Out of range value for column 'm1' at row 9
+Warning	1264	Out of range value for column 'm20' at row 9
+Warning	1264	Out of range value for column 'i' at row 10
+Warning	1264	Out of range value for column 'i0' at row 10
+Warning	1264	Out of range value for column 'i1' at row 10
+Warning	1264	Out of range value for column 'i20' at row 10
+Warning	1264	Out of range value for column 't' at row 10
+Warning	1264	Out of range value for column 't0' at row 10
+Warning	1264	Out of range value for column 't1' at row 10
+Warning	1264	Out of range value for column 't20' at row 10
+Warning	1264	Out of range value for column 's' at row 10
+Warning	1264	Out of range value for column 's0' at row 10
+Warning	1264	Out of range value for column 's1' at row 10
+Warning	1264	Out of range value for column 's20' at row 10
+Warning	1264	Out of range value for column 'm' at row 10
+Warning	1264	Out of range value for column 'm0' at row 10
+Warning	1264	Out of range value for column 'm1' at row 10
+Warning	1264	Out of range value for column 'm20' at row 10
+Warning	1264	Out of range value for column 'i' at row 11
+Warning	1264	Out of range value for column 'i0' at row 11
+Warning	1264	Out of range value for column 'i1' at row 11
+Warning	1264	Out of range value for column 'i20' at row 11
+Warning	1264	Out of range value for column 't' at row 11
+Warning	1264	Out of range value for column 't0' at row 11
+Warning	1264	Out of range value for column 't1' at row 11
+Warning	1264	Out of range value for column 't20' at row 11
+Warning	1264	Out of range value for column 's' at row 11
+Warning	1264	Out of range value for column 's0' at row 11
+Warning	1264	Out of range value for column 's1' at row 11
+Warning	1264	Out of range value for column 's20' at row 11
+Warning	1264	Out of range value for column 'm' at row 11
+Warning	1264	Out of range value for column 'm0' at row 11
+Warning	1264	Out of range value for column 'm1' at row 11
+Warning	1264	Out of range value for column 'm20' at row 11
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+ALTER TABLE t1 ADD COLUMN i257 INT(257) NULL;
+ERROR 42000: Display width out of range for column 'i257' (max = 255)
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c INT NULL,
+c1 INT NULL DEFAULT NULL,
+c2 INT NULL DEFAULT 2147483647,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	int(11)	YES		NULL	
+c1	int(11)	YES		NULL	
+c2	int(11)	YES		2147483647	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (2147483647,2147483647,2147483647);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	7FFFFFFF	7FFFFFFF	7FFFFFFF
+3	NULL	NULL	7FFFFFFF
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c TINYINT NULL,
+c1 TINYINT NULL DEFAULT NULL,
+c2 TINYINT NULL DEFAULT 127  ,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	tinyint(4)	YES		NULL	
+c1	tinyint(4)	YES		NULL	
+c2	tinyint(4)	YES		127	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (127  ,127  ,127  );
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	7F	7F	7F
+3	NULL	NULL	7F
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c SMALLINT NULL,
+c1 SMALLINT NULL DEFAULT NULL,
+c2 SMALLINT NULL DEFAULT 0,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	smallint(6)	YES		NULL	
+c1	smallint(6)	YES		NULL	
+c2	smallint(6)	YES		0	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (0,0,0);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	0	0	0
+3	NULL	NULL	0
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c MEDIUMINT NULL,
+c1 MEDIUMINT NULL DEFAULT NULL,
+c2 MEDIUMINT NULL DEFAULT 1,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	mediumint(9)	YES		NULL	
+c1	mediumint(9)	YES		NULL	
+c2	mediumint(9)	YES		1	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (1,1,1);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	1	1	1
+3	NULL	NULL	1
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c BIGINT NULL,
+c1 BIGINT NULL DEFAULT NULL,
+c2 BIGINT NULL DEFAULT 9223372036854775807,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	bigint(20)	YES		NULL	
+c1	bigint(20)	YES		NULL	
+c2	bigint(20)	YES		9223372036854775807	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES (9223372036854775807,9223372036854775807,9223372036854775807);
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	7FFFFFFFFFFFFFFF	7FFFFFFFFFFFFFFF	7FFFFFFFFFFFFFFF
+3	NULL	NULL	7FFFFFFFFFFFFFFF
+DROP TABLE t1;
+########################
+# SET columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a SET('') NULL,
+b SET('test1','test2','test3','test4','test5') NULL,
+c SET('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64') NULL,
+PRIMARY KEY (c)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	set('')	YES		NULL	
+b	set('test1','test2','test3','test4','test5')	YES		NULL	
+c	set('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64')	NO	PRI		
+INSERT INTO t1 (a,b,c) VALUES 
+('','test2,test3','01,34,44,,23'),
+('',5,2),
+(',','test4,test2','');
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+	test1,test3	02
+	test2,test3	01,23,34,44
+	test2,test4	
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+		01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50'51,52,53,54,55,56,57,58,59,60,61,62,63,64
+	test1,test3	02
+	test2,test3	01,23,34,44
+	test2,test4	
+ALTER TABLE t1 ADD COLUMN e SET('a','A') NULL;
+Warnings:
+Note	1291	Column 'e' has duplicated value 'a' in SET
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	set('')	YES		NULL	
+b	set('test1','test2','test3','test4','test5')	YES		NULL	
+c	set('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64')	NO	PRI		
+e	set('a','A')	YES		NULL	
+ALTER TABLE t1 ADD COLUMN f SET('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i') NULL;
+ERROR HY000: Too many strings for column f and SET
+SELECT a,b,c,e FROM t1 WHERE FIND_IN_SET('test2',b)>0 OR a != '';
+a	b	c	e
+	test2,test3	01,23,34,44	NULL
+	test2,test4		NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c SET('test1','test2','test3') NULL,
+c1 SET('test1','test2','test3') NULL DEFAULT NULL,
+c2 SET('test1','test2','test3') NULL DEFAULT 'test2,test3',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	set('test1','test2','test3')	YES		NULL	
+c1	set('test1','test2','test3')	YES		NULL	
+c2	set('test1','test2','test3')	YES		test2,test3	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('test2,test3','test2,test3','test2,test3');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2	74657374322C7465737433	74657374322C7465737433	74657374322C7465737433
+3	NULL	NULL	74657374322C7465737433
+DROP TABLE t1;
+########################
+# TEXT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+t TEXT NULL,
+t0 TEXT(0) NULL,
+t1 TEXT(1) NULL,
+t300 TEXT(300) NULL,
+tm TEXT(65535) NULL,
+t70k TEXT(70000) NULL,
+t17m TEXT(17000000) NULL,
+tt TINYTEXT NULL,
+m MEDIUMTEXT NULL,
+l LONGTEXT NULL
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+t	text	YES		NULL	
+t0	text	YES		NULL	
+t1	tinytext	YES		NULL	
+t300	text	YES		NULL	
+tm	text	YES		NULL	
+t70k	mediumtext	YES		NULL	
+t17m	longtext	YES		NULL	
+tt	tinytext	YES		NULL	
+m	mediumtext	YES		NULL	
+l	longtext	YES		NULL	
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',255), REPEAT('i',1048576), REPEAT('j',1048576) );
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(t)	LENGTH(t0)	LENGTH(t1)	LENGTH(t300)	LENGTH(tm)	LENGTH(t70k)	LENGTH(t17m)	LENGTH(tt)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+Warnings:
+Warning	1265	Data truncated for column 't' at row 1
+Warning	1265	Data truncated for column 't0' at row 1
+Warning	1265	Data truncated for column 't1' at row 1
+Warning	1265	Data truncated for column 't300' at row 1
+Warning	1265	Data truncated for column 'tm' at row 1
+Warning	1265	Data truncated for column 'tt' at row 1
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(t)	LENGTH(t0)	LENGTH(t1)	LENGTH(t300)	LENGTH(tm)	LENGTH(t70k)	LENGTH(t17m)	LENGTH(tt)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+ALTER TABLE t1 ADD COLUMN ttt TEXT(4294967296) NULL;
+ERROR 42000: Display width out of range for column 'ttt' (max = 4294967295)
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c TEXT NULL,
+c1 TEXT NULL DEFAULT NULL,
+c2 TEXT NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	text	YES		NULL	
+c1	text	YES		NULL	
+c2	text	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c TINYTEXT NULL,
+c1 TINYTEXT NULL DEFAULT NULL,
+c2 TINYTEXT NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	tinytext	YES		NULL	
+c1	tinytext	YES		NULL	
+c2	tinytext	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c MEDIUMTEXT NULL,
+c1 MEDIUMTEXT NULL DEFAULT NULL,
+c2 MEDIUMTEXT NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	mediumtext	YES		NULL	
+c1	mediumtext	YES		NULL	
+c2	mediumtext	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c LONGTEXT NULL,
+c1 LONGTEXT NULL DEFAULT NULL,
+c2 LONGTEXT NULL DEFAULT '',
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1101	BLOB/TEXT column 'c2' can't have a default value
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	longtext	YES		NULL	
+c1	longtext	YES		NULL	
+c2	longtext	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (c,c1,c2) VALUES (NULL,NULL,NULL);
+INSERT INTO t1 (c,c1,c2) VALUES ('','','');
+INSERT INTO t1 () VALUES ();
+SELECT pk, HEX(c), HEX(c1), HEX(c2) FROM t1 ORDER BY pk;
+pk	HEX(c)	HEX(c1)	HEX(c2)
+1	NULL	NULL	NULL
+2			
+3	NULL	NULL	NULL
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/col_opt_null.test b/mysql-test/suite/leveldb/col_opt_null.test
new file mode 100644
index 0000000..3af91ff
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_null.test
@@ -0,0 +1,214 @@
+# 
+# NULL column attribute
+#
+
+let $extra_col_opts = NULL;
+
+
+--echo ########################
+--echo # BINARY columns
+--echo ########################
+
+--source type_binary.inc
+--let $col_type = BINARY
+--let $col_default = 0
+--source col_null.inc
+
+--echo ########################
+--echo # VARBINARY columns
+--echo ########################
+
+--source type_varbinary.inc
+--let $col_type = VARBINARY(64)
+--let $col_default = 'test'
+--source col_null.inc
+
+--echo ########################
+--echo # BIT columns
+--echo ########################
+
+--source type_bit.inc
+--let $col_type = BIT
+--let $col_default = 1
+--source col_null.inc
+
+--echo ########################
+--echo # BLOB columns
+--echo ########################
+
+--source type_blob.inc
+
+--let $col_default = ''
+
+--let $col_type = BLOB
+--source col_null.inc
+
+--let $col_type = TINYBLOB
+--source col_null.inc
+
+--let $col_type = MEDIUMBLOB
+--source col_null.inc
+
+--let $col_type = LONGBLOB
+--source col_null.inc
+
+--echo ########################
+--echo # BOOL columns
+--echo ########################
+
+--source type_bool.inc
+--let $col_type = BOOL
+--let $col_default = '0'
+--source col_null.inc
+
+
+--echo ########################
+--echo # CHAR columns
+--echo ########################
+
+--source type_char.inc
+--let $col_type = CHAR
+--let $col_default = '_'
+--source col_null.inc
+
+--echo ########################
+--echo # VARCHAR columns
+--echo ########################
+
+
+--source type_varchar.inc
+--let $col_type = VARCHAR(64)
+--let $col_default = 'test default'
+--source col_null.inc
+
+
+--echo ########################
+--echo # date and time columns
+--echo ########################
+
+--source type_date_time.inc
+
+--let $col_type = DATE
+--let $col_default = '2012-12-21'
+--source col_null.inc
+
+--let $col_type = DATETIME
+--let $col_default = '2012-12-21 12:21:12'
+--source col_null.inc
+
+--let $col_type = TIMESTAMP
+--let $col_default = '2012-12-21 12:21:12'
+--source col_null.inc
+
+--let $col_type = TIME
+--let $col_default = '12:21:12'
+--source col_null.inc
+
+--let $col_type = YEAR
+--let $col_default = '2012'
+--source col_null.inc
+
+--let $col_type = YEAR(2)
+--let $col_default = '12'
+--source col_null.inc
+
+
+--echo ########################
+--echo # ENUM columns
+--echo ########################
+
+--source type_enum.inc
+--let $col_type = ENUM('test1','test2','test3')
+--let $col_default = 'test2'
+--source col_null.inc
+
+--echo ########################
+--echo # Fixed point columns (NUMERIC, DECIMAL)
+--echo ########################
+
+--source type_fixed.inc
+
+--let $col_type = DECIMAL
+--let $col_default = 1.1
+--source col_null.inc
+
+--let $col_type = NUMERIC
+--let $col_default = 0 
+--source col_null.inc
+
+--echo ########################
+--echo # Floating point columns (FLOAT, DOUBLE)
+--echo ########################
+
+--source type_float.inc
+  
+--let $col_type = FLOAT
+--let $col_default = 1.1 
+--source col_null.inc
+
+--let $col_type = DOUBLE
+--let $col_default = 0  
+--source col_null.inc
+
+--echo ########################
+--echo # INT columns
+--echo ########################
+
+--source type_int.inc
+  
+--let $col_type = INT
+--let $col_default = 2147483647
+--source col_null.inc
+
+--let $col_type = TINYINT
+--let $col_default = 127  
+--source col_null.inc
+
+--let $col_type = SMALLINT
+--let $col_default = 0
+--source col_null.inc
+
+--let $col_type = MEDIUMINT
+--let $col_default = 1
+--source col_null.inc
+
+--let $col_type = BIGINT
+--let $col_default = 9223372036854775807
+--source col_null.inc
+
+--echo ########################
+--echo # SET columns
+--echo ########################
+
+--source type_set.inc
+--let $col_type = SET('test1','test2','test3')
+--let $col_default = 'test2,test3'
+--source col_null.inc
+
+
+--echo ########################
+--echo # TEXT columns
+--echo ########################
+
+--source type_text.inc
+ 
+--let $col_default = ''
+
+--let $col_type = TEXT
+--source col_null.inc
+
+--let $col_type = TINYTEXT
+--source col_null.inc
+
+--let $col_type = MEDIUMTEXT
+--source col_null.inc
+
+--let $col_type = LONGTEXT
+--source col_null.inc
+
+
+--let $col_type =
+--let $col_default =
+--let $extra_col_opts =
+
+
diff --git a/mysql-test/suite/leveldb/col_opt_unsigned.result b/mysql-test/suite/leveldb/col_opt_unsigned.result
new file mode 100644
index 0000000..764860f
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_unsigned.result
@@ -0,0 +1,741 @@
+########################
+# Fixed point columns (NUMERIC, DECIMAL)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DECIMAL UNSIGNED,
+d0 DECIMAL(0) UNSIGNED,
+d1_1 DECIMAL(1,1) UNSIGNED,
+d10_2 DECIMAL(10,2) UNSIGNED,
+d60_10 DECIMAL(60,10) UNSIGNED,
+n NUMERIC UNSIGNED,
+n0_0 NUMERIC(0,0) UNSIGNED,
+n1 NUMERIC(1) UNSIGNED,
+n20_4 NUMERIC(20,4) UNSIGNED,
+n65_4 NUMERIC(65,4) UNSIGNED,
+pk NUMERIC UNSIGNED PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	decimal(10,0) unsigned	YES		NULL	
+d0	decimal(10,0) unsigned	YES		NULL	
+d1_1	decimal(1,1) unsigned	YES		NULL	
+d10_2	decimal(10,2) unsigned	YES		NULL	
+d60_10	decimal(60,10) unsigned	YES		NULL	
+n	decimal(10,0) unsigned	YES		NULL	
+n0_0	decimal(10,0) unsigned	YES		NULL	
+n1	decimal(1,0) unsigned	YES		NULL	
+n20_4	decimal(20,4) unsigned	YES		NULL	
+n65_4	decimal(65,4) unsigned	YES		NULL	
+pk	decimal(10,0) unsigned	NO	PRI	NULL	
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (100,123456,0.3,40000.25,123456789123456789.10001,1024,7000.0,8.0,999999.9,9223372036854775807,1);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.0,9999999999.0,0.9,99999999.99,99999999999999999999999999999999999999999999999999.9999999999,9999999999.0,9999999999.0,9.0,9999999999999999.9999,9999999999999999999999999999999999999999999999999999999999999.9999,3);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-100,-123456,-0.3,-40000.25,-123456789123456789.10001,-1024,-7000.0,-8.0,-999999.9,-9223372036854775807,4);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-9999999999.0,-9999999999.0,-0.9,-99999999.99,-99999999999999999999999999999999999999999999999999.9999999999,-9999999999.0,-9999999999.0,-9.0,-9999999999999999.9999,-9999999999999999999999999999999999999999999999999999999999999.9999,5);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1 WHERE n20_4 = 9999999999999999.9999 OR d < 100;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+6
+);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (10000000000.0,10000000000.0,1.1,100000000.99,100000000000000000000000000000000000000000000000000.0,10000000000.0,10000000000.0,10.0,10000000000000000.9999,10000000000000000000000000000000000000000000000000000000000000.9999,7);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.1,9999999999.1,1.9,99999999.001,99999999999999999999999999999999999999999999999999.99999999991,9999999999.1,9999999999.1,9.1,9999999999999999.00001,9999999999999999999999999999999999999999999999999999999999999.11111,8);
+Warnings:
+Note	1265	Data truncated for column 'd' at row 1
+Note	1265	Data truncated for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Note	1265	Data truncated for column 'd10_2' at row 1
+Note	1265	Data truncated for column 'd60_10' at row 1
+Note	1265	Data truncated for column 'n' at row 1
+Note	1265	Data truncated for column 'n0_0' at row 1
+Note	1265	Data truncated for column 'n1' at row 1
+Note	1265	Data truncated for column 'n20_4' at row 1
+Note	1265	Data truncated for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.00	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.0000	9999999999999999999999999999999999999999999999999999999999999.1111
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+ALTER TABLE t1 ADD COLUMN n66 NUMERIC(66) UNSIGNED;
+ERROR 42000: Too big precision 66 specified for column 'n66'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(66,6) UNSIGNED;
+ERROR 42000: Too big precision 66 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(66,66) UNSIGNED;
+ERROR 42000: Too big scale 66 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+CREATE TABLE t1 (
+a DECIMAL UNSIGNED,
+b NUMERIC UNSIGNED,
+PRIMARY KEY (a)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	decimal(10,0) unsigned	NO	PRI	0	
+b	decimal(10,0) unsigned	YES		NULL	
+INSERT INTO t1 (a,b) VALUES (1.0,-1.0);
+Warnings:
+Warning	1264	Out of range value for column 'b' at row 1
+INSERT INTO t1 (a,b) VALUES (-100,100);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT a,b FROM t1;
+a	b
+0	100
+1	0
+DROP TABLE t1;
+########################
+# Floating point columns (FLOAT, DOUBLE)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+f FLOAT UNSIGNED,
+f0 FLOAT(0) UNSIGNED,
+r1_1 REAL(1,1) UNSIGNED,
+f23_0 FLOAT(23) UNSIGNED,
+f20_3 FLOAT(20,3) UNSIGNED,
+d DOUBLE UNSIGNED,
+d1_0 DOUBLE(1,0) UNSIGNED,
+d10_10 DOUBLE PRECISION (10,10) UNSIGNED,
+d53 DOUBLE(53,0) UNSIGNED,
+d53_10 DOUBLE(53,10) UNSIGNED,
+pk DOUBLE UNSIGNED PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+f	float unsigned	YES		NULL	
+f0	float unsigned	YES		NULL	
+r1_1	double(1,1) unsigned	YES		NULL	
+f23_0	float unsigned	YES		NULL	
+f20_3	float(20,3) unsigned	YES		NULL	
+d	double unsigned	YES		NULL	
+d1_0	double(1,0) unsigned	YES		NULL	
+d10_10	double(10,10) unsigned	YES		NULL	
+d53	double(53,0) unsigned	YES		NULL	
+d53_10	double(53,10) unsigned	YES		NULL	
+pk	double unsigned	NO	PRI	NULL	
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	11111111.111
+d10_10	0.0123456789
+d1_0	8
+d53	1234566789123456800
+d53_10	100000000000000000.0000000000
+f0	12345.1
+f20_3	56789.988
+f23_0	123457000
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+99999999999999999999999999999999999999,
+99999999999999999999999999999999999999.9999999999999999,
+0.9,
+99999999999999999999999999999999999999.9,
+99999999999999999.999,
+999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+9,
+0.9999999999, 
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+3
+);
+Warnings:
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	11111111.111
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	8
+d1_0	9
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	1e38
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	0
+d	11111111.111
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	0
+d1_0	8
+d1_0	9
+d53	0
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	0
+f	1e38
+f0	0
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	0.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	0.0
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+SELECT MAX(f), MAX(f0), MAX(r1_1), MAX(f23_0), MAX(f20_3), MAX(d), MAX(d1_0), MAX(d10_10), MAX(d53), MAX(d53_10) FROM t1;
+MAX(f)	9.999999680285692e37
+MAX(d)	1e81
+MAX(d10_10)	0.9999999999
+MAX(d1_0)	9
+MAX(d53)	100000000000000000000000000000000000000000000000000000
+MAX(d53_10)	10000000000000000000000000000000000000000000.0000000000
+MAX(f0)	9.999999680285692e37
+MAX(f20_3)	99999998430674940.000
+MAX(f23_0)	9.999999680285692e37
+MAX(r1_1)	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+5
+);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	0
+d	11111111.111
+d	1e61
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	0
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d53	0
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	0
+f	1e38
+f	3.40282e38
+f0	0
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f20_3	0.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+r1_1	0.0
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+999999999999999999999999999999999999999,
+999999999999999999999999999999999999999.9999999999999999,
+1.9,
+999999999999999999999999999999999999999.9,
+999999999999999999.999,
+9999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+99,
+1.9999999999,
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+6
+);
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	0
+d	11111111.111
+d	1e61
+d	1e65
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	0
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d1_0	9
+d53	0
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	0
+f	1e38
+f	3.40282e38
+f	3.40282e38
+f0	0
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f0	3.40282e38
+f20_3	0.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+f23_0	3.40282e38
+r1_1	0.0
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+ALTER TABLE t1 ADD COLUMN d0_0 DOUBLE(0,0) UNSIGNED;
+ERROR 42000: Display width out of range for column 'd0_0' (max = 255)
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(256,1) UNSIGNED;
+ERROR 42000: Too big precision 256 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(40,35) UNSIGNED;
+ERROR 42000: Too big scale 35 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+CREATE TABLE t1 (
+a DOUBLE UNSIGNED,
+b FLOAT UNSIGNED,
+PRIMARY KEY (b) 
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	double unsigned	YES		NULL	
+b	float unsigned	NO	PRI	0	
+INSERT INTO t1 (a,b) VALUES (1.0,-1.0);
+Warnings:
+Warning	1264	Out of range value for column 'b' at row 1
+INSERT INTO t1 (a,b) VALUES (-100,100);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT a,b FROM t1;
+a	b
+0	100
+1	0
+DROP TABLE t1;
+########################
+# INT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+i INT UNSIGNED,
+i0 INT(0) UNSIGNED,
+i1 INT(1) UNSIGNED,
+i20 INT(20) UNSIGNED,
+t TINYINT UNSIGNED,
+t0 TINYINT(0) UNSIGNED,
+t1 TINYINT(1) UNSIGNED,
+t20 TINYINT(20) UNSIGNED,
+s SMALLINT UNSIGNED,
+s0 SMALLINT(0) UNSIGNED,
+s1 SMALLINT(1) UNSIGNED,
+s20 SMALLINT(20) UNSIGNED,
+m MEDIUMINT UNSIGNED,
+m0 MEDIUMINT(0) UNSIGNED,
+m1 MEDIUMINT(1) UNSIGNED,
+m20 MEDIUMINT(20) UNSIGNED,
+b BIGINT UNSIGNED,
+b0 BIGINT(0) UNSIGNED,
+b1 BIGINT(1) UNSIGNED,
+b20 BIGINT(20) UNSIGNED,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+i	int(10) unsigned	YES		NULL	
+i0	int(10) unsigned	YES		NULL	
+i1	int(1) unsigned	YES		NULL	
+i20	int(20) unsigned	YES		NULL	
+t	tinyint(3) unsigned	YES		NULL	
+t0	tinyint(3) unsigned	YES		NULL	
+t1	tinyint(1) unsigned	YES		NULL	
+t20	tinyint(20) unsigned	YES		NULL	
+s	smallint(5) unsigned	YES		NULL	
+s0	smallint(5) unsigned	YES		NULL	
+s1	smallint(1) unsigned	YES		NULL	
+s20	smallint(20) unsigned	YES		NULL	
+m	mediumint(8) unsigned	YES		NULL	
+m0	mediumint(8) unsigned	YES		NULL	
+m1	mediumint(1) unsigned	YES		NULL	
+m20	mediumint(20) unsigned	YES		NULL	
+b	bigint(20) unsigned	YES		NULL	
+b0	bigint(20) unsigned	YES		NULL	
+b1	bigint(1) unsigned	YES		NULL	
+b20	bigint(20) unsigned	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (2147483647,2147483647,2147483647,2147483647,127,127,127,127,32767,32767,32767,32767,8388607,8388607,8388607,8388607,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483648,-2147483648,-2147483648,-2147483648,-128,-128,-128,-128,-32768,-32768,-32768,-32768,-8388608,-8388608,-8388608,-8388608,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967295,4294967295,4294967295,4294967295,255,255,255,255,65535,65535,65535,65535,16777215,16777215,16777215,16777215,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+4294967295	4294967295	4294967295	4294967295	255	255	255	255	65535	65535	65535	65535	16777215	16777215	16777215	16777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483649,-2147483649,-2147483649,-2147483649,-129,-129,-129,-129,-32769,-32769,-32769,-32769,-8388609,-8388609,-8388609,-8388609,-9223372036854775809,-9223372036854775809,-9223372036854775809,-9223372036854775809);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967296,4294967296,4294967296,4294967296,256,256,256,256,65536,65536,65536,65536,16777216,16777216,16777216,16777216,18446744073709551616,18446744073709551616,18446744073709551616,18446744073709551616);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) SELECT b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b FROM t1 WHERE b IN (-9223372036854775808,9223372036854775807,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 8
+Warning	1264	Out of range value for column 'i0' at row 8
+Warning	1264	Out of range value for column 'i1' at row 8
+Warning	1264	Out of range value for column 'i20' at row 8
+Warning	1264	Out of range value for column 't' at row 8
+Warning	1264	Out of range value for column 't0' at row 8
+Warning	1264	Out of range value for column 't1' at row 8
+Warning	1264	Out of range value for column 't20' at row 8
+Warning	1264	Out of range value for column 's' at row 8
+Warning	1264	Out of range value for column 's0' at row 8
+Warning	1264	Out of range value for column 's1' at row 8
+Warning	1264	Out of range value for column 's20' at row 8
+Warning	1264	Out of range value for column 'm' at row 8
+Warning	1264	Out of range value for column 'm0' at row 8
+Warning	1264	Out of range value for column 'm1' at row 8
+Warning	1264	Out of range value for column 'm20' at row 8
+Warning	1264	Out of range value for column 'i' at row 9
+Warning	1264	Out of range value for column 'i0' at row 9
+Warning	1264	Out of range value for column 'i1' at row 9
+Warning	1264	Out of range value for column 'i20' at row 9
+Warning	1264	Out of range value for column 't' at row 9
+Warning	1264	Out of range value for column 't0' at row 9
+Warning	1264	Out of range value for column 't1' at row 9
+Warning	1264	Out of range value for column 't20' at row 9
+Warning	1264	Out of range value for column 's' at row 9
+Warning	1264	Out of range value for column 's0' at row 9
+Warning	1264	Out of range value for column 's1' at row 9
+Warning	1264	Out of range value for column 's20' at row 9
+Warning	1264	Out of range value for column 'm' at row 9
+Warning	1264	Out of range value for column 'm0' at row 9
+Warning	1264	Out of range value for column 'm1' at row 9
+Warning	1264	Out of range value for column 'm20' at row 9
+Warning	1264	Out of range value for column 'i' at row 10
+Warning	1264	Out of range value for column 'i0' at row 10
+Warning	1264	Out of range value for column 'i1' at row 10
+Warning	1264	Out of range value for column 'i20' at row 10
+Warning	1264	Out of range value for column 't' at row 10
+Warning	1264	Out of range value for column 't0' at row 10
+Warning	1264	Out of range value for column 't1' at row 10
+Warning	1264	Out of range value for column 't20' at row 10
+Warning	1264	Out of range value for column 's' at row 10
+Warning	1264	Out of range value for column 's0' at row 10
+Warning	1264	Out of range value for column 's1' at row 10
+Warning	1264	Out of range value for column 's20' at row 10
+Warning	1264	Out of range value for column 'm' at row 10
+Warning	1264	Out of range value for column 'm0' at row 10
+Warning	1264	Out of range value for column 'm1' at row 10
+Warning	1264	Out of range value for column 'm20' at row 10
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+4294967295	4294967295	4294967295	4294967295	255	255	255	255	65535	65535	65535	65535	16777215	16777215	16777215	16777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	4294967295	255	255	255	255	65535	65535	65535	65535	16777215	16777215	16777215	16777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	4294967295	255	255	255	255	65535	65535	65535	65535	16777215	16777215	16777215	16777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	4294967295	255	255	255	255	65535	65535	65535	65535	16777215	16777215	16777215	16777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	4294967295	255	255	255	255	65535	65535	65535	65535	16777215	16777215	16777215	16777215	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+ALTER TABLE t1 ADD COLUMN i257 INT(257) UNSIGNED;
+ERROR 42000: Display width out of range for column 'i257' (max = 255)
+DROP TABLE t1;
+CREATE TABLE t1 (
+t TINYINT UNSIGNED,
+s SMALLINT UNSIGNED,
+m MEDIUMINT UNSIGNED,
+i INT UNSIGNED,
+b BIGINT UNSIGNED,
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+t	tinyint(3) unsigned	YES		NULL	
+s	smallint(5) unsigned	YES		NULL	
+m	mediumint(8) unsigned	YES		NULL	
+i	int(10) unsigned	YES		NULL	
+b	bigint(20) unsigned	NO	PRI	0	
+INSERT INTO t1 (t,s,m,i,b) VALUES (255,65535,16777215,4294967295,18446744073709551615);
+INSERT INTO t1 (t,s,m,i,b) VALUES (-1,-1,-1,-1,-1);
+Warnings:
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+SELECT t,s,m,i,b FROM t1;
+t	s	m	i	b
+0	0	0	0	0
+255	65535	16777215	4294967295	18446744073709551615
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/col_opt_unsigned.test b/mysql-test/suite/leveldb/col_opt_unsigned.test
new file mode 100644
index 0000000..e69fc25
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_unsigned.test
@@ -0,0 +1,72 @@
+# 
+# UNSIGNED column attribute 
+#
+
+--let $extra_col_opts = UNSIGNED
+
+--echo ########################
+--echo # Fixed point columns (NUMERIC, DECIMAL)
+--echo ########################
+
+--source type_fixed.inc
+
+CREATE TABLE t1 (
+  a DECIMAL UNSIGNED,
+  b NUMERIC UNSIGNED,
+  PRIMARY KEY (a)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b) VALUES (1.0,-1.0);
+INSERT INTO t1 (a,b) VALUES (-100,100);
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+--echo ########################
+--echo # Floating point columns (FLOAT, DOUBLE)
+--echo ########################
+
+--source type_float.inc
+
+CREATE TABLE t1 (
+  a DOUBLE UNSIGNED,
+  b FLOAT UNSIGNED,
+  PRIMARY KEY (b) 
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b) VALUES (1.0,-1.0);
+INSERT INTO t1 (a,b) VALUES (-100,100);
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+--echo ########################
+--echo # INT columns
+--echo ########################
+
+--source type_int.inc
+
+CREATE TABLE t1 (
+  t TINYINT UNSIGNED,
+  s SMALLINT UNSIGNED,
+  m MEDIUMINT UNSIGNED,
+  i INT UNSIGNED,
+  b BIGINT UNSIGNED,
+  PRIMARY KEY (b)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (t,s,m,i,b) VALUES (255,65535,16777215,4294967295,18446744073709551615);
+INSERT INTO t1 (t,s,m,i,b) VALUES (-1,-1,-1,-1,-1);
+--sorted_result
+SELECT t,s,m,i,b FROM t1;
+
+DROP TABLE t1;
+  
+--let $extra_col_opts =
+
diff --git a/mysql-test/suite/leveldb/col_opt_zerofill.result b/mysql-test/suite/leveldb/col_opt_zerofill.result
new file mode 100644
index 0000000..97be89a
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_zerofill.result
@@ -0,0 +1,723 @@
+########################
+# Fixed point columns (NUMERIC, DECIMAL)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DECIMAL ZEROFILL,
+d0 DECIMAL(0) ZEROFILL,
+d1_1 DECIMAL(1,1) ZEROFILL,
+d10_2 DECIMAL(10,2) ZEROFILL,
+d60_10 DECIMAL(60,10) ZEROFILL,
+n NUMERIC ZEROFILL,
+n0_0 NUMERIC(0,0) ZEROFILL,
+n1 NUMERIC(1) ZEROFILL,
+n20_4 NUMERIC(20,4) ZEROFILL,
+n65_4 NUMERIC(65,4) ZEROFILL,
+pk NUMERIC ZEROFILL PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	decimal(10,0) unsigned zerofill	YES		NULL	
+d0	decimal(10,0) unsigned zerofill	YES		NULL	
+d1_1	decimal(1,1) unsigned zerofill	YES		NULL	
+d10_2	decimal(10,2) unsigned zerofill	YES		NULL	
+d60_10	decimal(60,10) unsigned zerofill	YES		NULL	
+n	decimal(10,0) unsigned zerofill	YES		NULL	
+n0_0	decimal(10,0) unsigned zerofill	YES		NULL	
+n1	decimal(1,0) unsigned zerofill	YES		NULL	
+n20_4	decimal(20,4) unsigned zerofill	YES		NULL	
+n65_4	decimal(65,4) unsigned zerofill	YES		NULL	
+pk	decimal(10,0) unsigned zerofill	NO	PRI	NULL	
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (100,123456,0.3,40000.25,123456789123456789.10001,1024,7000.0,8.0,999999.9,9223372036854775807,1);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.0,9999999999.0,0.9,99999999.99,99999999999999999999999999999999999999999999999999.9999999999,9999999999.0,9999999999.0,9.0,9999999999999999.9999,9999999999999999999999999999999999999999999999999999999999999.9999,3);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000100	0000123456	0.3	00040000.25	00000000000000000000000000000000123456789123456789.1000100000	0000001024	0000007000	8	0000000000999999.9000	0000000000000000000000000000000000000000009223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-100,-123456,-0.3,-40000.25,-123456789123456789.10001,-1024,-7000.0,-8.0,-999999.9,-9223372036854775807,4);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-9999999999.0,-9999999999.0,-0.9,-99999999.99,-99999999999999999999999999999999999999999999999999.9999999999,-9999999999.0,-9999999999.0,-9.0,-9999999999999999.9999,-9999999999999999999999999999999999999999999999999999999999999.9999,5);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000100	0000123456	0.3	00040000.25	00000000000000000000000000000000123456789123456789.1000100000	0000001024	0000007000	8	0000000000999999.9000	0000000000000000000000000000000000000000009223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1 WHERE n20_4 = 9999999999999999.9999 OR d < 100;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+6
+);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000100	0000123456	0.3	00040000.25	00000000000000000000000000000000123456789123456789.1000100000	0000001024	0000007000	8	0000000000999999.9000	0000000000000000000000000000000000000000009223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (10000000000.0,10000000000.0,1.1,100000000.99,100000000000000000000000000000000000000000000000000.0,10000000000.0,10000000000.0,10.0,10000000000000000.9999,10000000000000000000000000000000000000000000000000000000000000.9999,7);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000100	0000123456	0.3	00040000.25	00000000000000000000000000000000123456789123456789.1000100000	0000001024	0000007000	8	0000000000999999.9000	0000000000000000000000000000000000000000009223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.1,9999999999.1,1.9,99999999.001,99999999999999999999999999999999999999999999999999.99999999991,9999999999.1,9999999999.1,9.1,9999999999999999.00001,9999999999999999999999999999999999999999999999999999999999999.11111,8);
+Warnings:
+Note	1265	Data truncated for column 'd' at row 1
+Note	1265	Data truncated for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Note	1265	Data truncated for column 'd10_2' at row 1
+Note	1265	Data truncated for column 'd60_10' at row 1
+Note	1265	Data truncated for column 'n' at row 1
+Note	1265	Data truncated for column 'n0_0' at row 1
+Note	1265	Data truncated for column 'n1' at row 1
+Note	1265	Data truncated for column 'n20_4' at row 1
+Note	1265	Data truncated for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000000	0000000000	0.0	00000000.00	00000000000000000000000000000000000000000000000000.0000000000	0000000000	0000000000	0	0000000000000000.0000	0000000000000000000000000000000000000000000000000000000000000.0000
+0000000100	0000123456	0.3	00040000.25	00000000000000000000000000000000123456789123456789.1000100000	0000001024	0000007000	8	0000000000999999.9000	0000000000000000000000000000000000000000009223372036854775807.0000
+9999999999	9999999999	0.9	99999999.00	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.0000	9999999999999999999999999999999999999999999999999999999999999.1111
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+ALTER TABLE t1 ADD COLUMN n66 NUMERIC(66) ZEROFILL;
+ERROR 42000: Too big precision 66 specified for column 'n66'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(66,6) ZEROFILL;
+ERROR 42000: Too big precision 66 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(66,66) ZEROFILL;
+ERROR 42000: Too big scale 66 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+CREATE TABLE t1 (
+a DECIMAL ZEROFILL,
+b NUMERIC ZEROFILL,
+PRIMARY KEY (a)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	decimal(10,0) unsigned zerofill	NO	PRI	0000000000	
+b	decimal(10,0) unsigned zerofill	YES		NULL	
+INSERT INTO t1 (a,b) VALUES (1.1,1234);
+Warnings:
+Note	1265	Data truncated for column 'a' at row 1
+SELECT a,b FROM t1;
+a	b
+0000000001	0000001234
+DROP TABLE t1;
+########################
+# Floating point columns (FLOAT, DOUBLE)
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+f FLOAT ZEROFILL,
+f0 FLOAT(0) ZEROFILL,
+r1_1 REAL(1,1) ZEROFILL,
+f23_0 FLOAT(23) ZEROFILL,
+f20_3 FLOAT(20,3) ZEROFILL,
+d DOUBLE ZEROFILL,
+d1_0 DOUBLE(1,0) ZEROFILL,
+d10_10 DOUBLE PRECISION (10,10) ZEROFILL,
+d53 DOUBLE(53,0) ZEROFILL,
+d53_10 DOUBLE(53,10) ZEROFILL,
+pk DOUBLE ZEROFILL PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+f	float unsigned zerofill	YES		NULL	
+f0	float unsigned zerofill	YES		NULL	
+r1_1	double(1,1) unsigned zerofill	YES		NULL	
+f23_0	float unsigned zerofill	YES		NULL	
+f20_3	float(20,3) unsigned zerofill	YES		NULL	
+d	double unsigned zerofill	YES		NULL	
+d1_0	double(1,0) unsigned zerofill	YES		NULL	
+d10_10	double(10,10) unsigned zerofill	YES		NULL	
+d53	double(53,0) unsigned zerofill	YES		NULL	
+d53_10	double(53,10) unsigned zerofill	YES		NULL	
+pk	double unsigned zerofill	NO	PRI	NULL	
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	0000012345.1
+d	000000000011111111.111
+d10_10	0.0123456789
+d1_0	8
+d53	00000000000000000000000000000000001234566789123456800
+d53_10	000000000000000000000000100000000000000000.0000000000
+f0	0000012345.1
+f20_3	0000000000056789.988
+f23_0	000123457000
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+99999999999999999999999999999999999999,
+99999999999999999999999999999999999999.9999999999999999,
+0.9,
+99999999999999999999999999999999999999.9,
+99999999999999999.999,
+999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+9,
+0.9999999999, 
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+3
+);
+Warnings:
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	0000012345.1
+d	0000000000000000000000
+d	0000000000000000001e81
+d	000000000011111111.111
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	8
+d1_0	9
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000001234566789123456800
+d53	100000000000000000000000000000000000000000000000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	000000000000
+f	000000001e38
+f0	000000000000
+f0	000000001e38
+f0	0000012345.1
+f20_3	0000000000000000.000
+f20_3	0000000000056789.988
+f20_3	99999998430674940.000
+f23_0	000000000000
+f23_0	000000001e38
+f23_0	000123457000
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	0000012345.1
+d	0000000000000000000000
+d	0000000000000000000000
+d	0000000000000000001e81
+d	000000000011111111.111
+d10_10	0.0000000000
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	0
+d1_0	8
+d1_0	9
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000001234566789123456800
+d53	100000000000000000000000000000000000000000000000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	000000000000
+f	000000000000
+f	000000001e38
+f0	000000000000
+f0	000000000000
+f0	000000001e38
+f0	0000012345.1
+f20_3	0000000000000000.000
+f20_3	0000000000000000.000
+f20_3	0000000000056789.988
+f20_3	99999998430674940.000
+f23_0	000000000000
+f23_0	000000000000
+f23_0	000000001e38
+f23_0	000123457000
+r1_1	0.0
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+SELECT MAX(f), MAX(f0), MAX(r1_1), MAX(f23_0), MAX(f20_3), MAX(d), MAX(d1_0), MAX(d10_10), MAX(d53), MAX(d53_10) FROM t1;
+MAX(f)	9.999999680285692e37
+MAX(d)	1e81
+MAX(d10_10)	0.9999999999
+MAX(d1_0)	9
+MAX(d53)	100000000000000000000000000000000000000000000000000000
+MAX(d53_10)	10000000000000000000000000000000000000000000.0000000000
+MAX(f0)	9.999999680285692e37
+MAX(f20_3)	99999998430674940.000
+MAX(f23_0)	9.999999680285692e37
+MAX(r1_1)	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+5
+);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	0000012345.1
+d	0000000000000000000000
+d	0000000000000000000000
+d	0000000000000000001e61
+d	0000000000000000001e81
+d	000000000011111111.111
+d10_10	0.0000000000
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	0
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000001234566789123456800
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	000000000000
+f	000000000000
+f	000000001e38
+f	003.40282e38
+f0	000000000000
+f0	000000000000
+f0	000000001e38
+f0	0000012345.1
+f0	003.40282e38
+f20_3	0000000000000000.000
+f20_3	0000000000000000.000
+f20_3	0000000000056789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	000000000000
+f23_0	000000000000
+f23_0	000000001e38
+f23_0	000123457000
+f23_0	003.40282e38
+r1_1	0.0
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+999999999999999999999999999999999999999,
+999999999999999999999999999999999999999.9999999999999999,
+1.9,
+999999999999999999999999999999999999999.9,
+999999999999999999.999,
+9999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+99,
+1.9999999999,
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+6
+);
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	0000012345.1
+d	0000000000000000000000
+d	0000000000000000000000
+d	0000000000000000001e61
+d	0000000000000000001e65
+d	0000000000000000001e81
+d	000000000011111111.111
+d10_10	0.0000000000
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	0
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d1_0	9
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000000000000000000000000
+d53	00000000000000000000000000000000001234566789123456800
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000000000000000000000.0000000000
+d53_10	000000000000000000000000100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	000000000000
+f	000000000000
+f	000000001e38
+f	003.40282e38
+f	003.40282e38
+f0	000000000000
+f0	000000000000
+f0	000000001e38
+f0	0000012345.1
+f0	003.40282e38
+f0	003.40282e38
+f20_3	0000000000000000.000
+f20_3	0000000000000000.000
+f20_3	0000000000056789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	000000000000
+f23_0	000000000000
+f23_0	000000001e38
+f23_0	000123457000
+f23_0	003.40282e38
+f23_0	003.40282e38
+r1_1	0.0
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+ALTER TABLE t1 ADD COLUMN d0_0 DOUBLE(0,0) ZEROFILL;
+ERROR 42000: Display width out of range for column 'd0_0' (max = 255)
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(256,1) ZEROFILL;
+ERROR 42000: Too big precision 256 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(40,35) ZEROFILL;
+ERROR 42000: Too big scale 35 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
+CREATE TABLE t1 (
+a DOUBLE ZEROFILL,
+b FLOAT ZEROFILL,
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	double unsigned zerofill	YES		NULL	
+b	float unsigned zerofill	NO	PRI	000000000000	
+INSERT INTO t1 (a,b) VALUES (1,1234.5);
+SELECT a,b FROM t1;
+a	b
+0000000000000000000001	0000001234.5
+DROP TABLE t1;
+########################
+# INT columns
+########################
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+i INT ZEROFILL,
+i0 INT(0) ZEROFILL,
+i1 INT(1) ZEROFILL,
+i20 INT(20) ZEROFILL,
+t TINYINT ZEROFILL,
+t0 TINYINT(0) ZEROFILL,
+t1 TINYINT(1) ZEROFILL,
+t20 TINYINT(20) ZEROFILL,
+s SMALLINT ZEROFILL,
+s0 SMALLINT(0) ZEROFILL,
+s1 SMALLINT(1) ZEROFILL,
+s20 SMALLINT(20) ZEROFILL,
+m MEDIUMINT ZEROFILL,
+m0 MEDIUMINT(0) ZEROFILL,
+m1 MEDIUMINT(1) ZEROFILL,
+m20 MEDIUMINT(20) ZEROFILL,
+b BIGINT ZEROFILL,
+b0 BIGINT(0) ZEROFILL,
+b1 BIGINT(1) ZEROFILL,
+b20 BIGINT(20) ZEROFILL,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+i	int(10) unsigned zerofill	YES		NULL	
+i0	int(10) unsigned zerofill	YES		NULL	
+i1	int(1) unsigned zerofill	YES		NULL	
+i20	int(20) unsigned zerofill	YES		NULL	
+t	tinyint(3) unsigned zerofill	YES		NULL	
+t0	tinyint(3) unsigned zerofill	YES		NULL	
+t1	tinyint(1) unsigned zerofill	YES		NULL	
+t20	tinyint(20) unsigned zerofill	YES		NULL	
+s	smallint(5) unsigned zerofill	YES		NULL	
+s0	smallint(5) unsigned zerofill	YES		NULL	
+s1	smallint(1) unsigned zerofill	YES		NULL	
+s20	smallint(20) unsigned zerofill	YES		NULL	
+m	mediumint(8) unsigned zerofill	YES		NULL	
+m0	mediumint(8) unsigned zerofill	YES		NULL	
+m1	mediumint(1) unsigned zerofill	YES		NULL	
+m20	mediumint(20) unsigned zerofill	YES		NULL	
+b	bigint(20) unsigned zerofill	YES		NULL	
+b0	bigint(20) unsigned zerofill	YES		NULL	
+b1	bigint(1) unsigned zerofill	YES		NULL	
+b20	bigint(20) unsigned zerofill	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (2147483647,2147483647,2147483647,2147483647,127,127,127,127,32767,32767,32767,32767,8388607,8388607,8388607,8388607,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0000000000	0000000000	0	00000000000000000000	000	000	0	00000000000000000000	00000	00000	0	00000000000000000000	00000000	00000000	0	00000000000000000000	00000000000000000000	00000000000000000000	0	00000000000000000000
+0000000001	0000000002	3	00000000000000000004	005	006	7	00000000000000000008	00009	00010	11	00000000000000000012	00000013	00000014	15	00000000000000000016	00000000000000000017	00000000000000000018	19	00000000000000000020
+2147483647	2147483647	2147483647	00000000002147483647	127	127	127	00000000000000000127	32767	32767	32767	00000000000000032767	08388607	08388607	8388607	00000000000008388607	09223372036854775807	09223372036854775807	9223372036854775807	09223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483648,-2147483648,-2147483648,-2147483648,-128,-128,-128,-128,-32768,-32768,-32768,-32768,-8388608,-8388608,-8388608,-8388608,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967295,4294967295,4294967295,4294967295,255,255,255,255,65535,65535,65535,65535,16777215,16777215,16777215,16777215,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0000000000	0000000000	0	00000000000000000000	000	000	0	00000000000000000000	00000	00000	0	00000000000000000000	00000000	00000000	0	00000000000000000000	00000000000000000000	00000000000000000000	0	00000000000000000000
+0000000000	0000000000	0	00000000000000000000	000	000	0	00000000000000000000	00000	00000	0	00000000000000000000	00000000	00000000	0	00000000000000000000	00000000000000000000	00000000000000000000	0	00000000000000000000
+0000000001	0000000002	3	00000000000000000004	005	006	7	00000000000000000008	00009	00010	11	00000000000000000012	00000013	00000014	15	00000000000000000016	00000000000000000017	00000000000000000018	19	00000000000000000020
+2147483647	2147483647	2147483647	00000000002147483647	127	127	127	00000000000000000127	32767	32767	32767	00000000000000032767	08388607	08388607	8388607	00000000000008388607	09223372036854775807	09223372036854775807	9223372036854775807	09223372036854775807
+4294967295	4294967295	4294967295	00000000004294967295	255	255	255	00000000000000000255	65535	65535	65535	00000000000000065535	16777215	16777215	16777215	00000000000016777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483649,-2147483649,-2147483649,-2147483649,-129,-129,-129,-129,-32769,-32769,-32769,-32769,-8388609,-8388609,-8388609,-8388609,-9223372036854775809,-9223372036854775809,-9223372036854775809,-9223372036854775809);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967296,4294967296,4294967296,4294967296,256,256,256,256,65536,65536,65536,65536,16777216,16777216,16777216,16777216,18446744073709551616,18446744073709551616,18446744073709551616,18446744073709551616);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) SELECT b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b FROM t1 WHERE b IN (-9223372036854775808,9223372036854775807,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 8
+Warning	1264	Out of range value for column 'i0' at row 8
+Warning	1264	Out of range value for column 'i1' at row 8
+Warning	1264	Out of range value for column 'i20' at row 8
+Warning	1264	Out of range value for column 't' at row 8
+Warning	1264	Out of range value for column 't0' at row 8
+Warning	1264	Out of range value for column 't1' at row 8
+Warning	1264	Out of range value for column 't20' at row 8
+Warning	1264	Out of range value for column 's' at row 8
+Warning	1264	Out of range value for column 's0' at row 8
+Warning	1264	Out of range value for column 's1' at row 8
+Warning	1264	Out of range value for column 's20' at row 8
+Warning	1264	Out of range value for column 'm' at row 8
+Warning	1264	Out of range value for column 'm0' at row 8
+Warning	1264	Out of range value for column 'm1' at row 8
+Warning	1264	Out of range value for column 'm20' at row 8
+Warning	1264	Out of range value for column 'i' at row 9
+Warning	1264	Out of range value for column 'i0' at row 9
+Warning	1264	Out of range value for column 'i1' at row 9
+Warning	1264	Out of range value for column 'i20' at row 9
+Warning	1264	Out of range value for column 't' at row 9
+Warning	1264	Out of range value for column 't0' at row 9
+Warning	1264	Out of range value for column 't1' at row 9
+Warning	1264	Out of range value for column 't20' at row 9
+Warning	1264	Out of range value for column 's' at row 9
+Warning	1264	Out of range value for column 's0' at row 9
+Warning	1264	Out of range value for column 's1' at row 9
+Warning	1264	Out of range value for column 's20' at row 9
+Warning	1264	Out of range value for column 'm' at row 9
+Warning	1264	Out of range value for column 'm0' at row 9
+Warning	1264	Out of range value for column 'm1' at row 9
+Warning	1264	Out of range value for column 'm20' at row 9
+Warning	1264	Out of range value for column 'i' at row 10
+Warning	1264	Out of range value for column 'i0' at row 10
+Warning	1264	Out of range value for column 'i1' at row 10
+Warning	1264	Out of range value for column 'i20' at row 10
+Warning	1264	Out of range value for column 't' at row 10
+Warning	1264	Out of range value for column 't0' at row 10
+Warning	1264	Out of range value for column 't1' at row 10
+Warning	1264	Out of range value for column 't20' at row 10
+Warning	1264	Out of range value for column 's' at row 10
+Warning	1264	Out of range value for column 's0' at row 10
+Warning	1264	Out of range value for column 's1' at row 10
+Warning	1264	Out of range value for column 's20' at row 10
+Warning	1264	Out of range value for column 'm' at row 10
+Warning	1264	Out of range value for column 'm0' at row 10
+Warning	1264	Out of range value for column 'm1' at row 10
+Warning	1264	Out of range value for column 'm20' at row 10
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0000000000	0000000000	0	00000000000000000000	000	000	0	00000000000000000000	00000	00000	0	00000000000000000000	00000000	00000000	0	00000000000000000000	00000000000000000000	00000000000000000000	0	00000000000000000000
+0000000000	0000000000	0	00000000000000000000	000	000	0	00000000000000000000	00000	00000	0	00000000000000000000	00000000	00000000	0	00000000000000000000	00000000000000000000	00000000000000000000	0	00000000000000000000
+0000000000	0000000000	0	00000000000000000000	000	000	0	00000000000000000000	00000	00000	0	00000000000000000000	00000000	00000000	0	00000000000000000000	00000000000000000000	00000000000000000000	0	00000000000000000000
+0000000001	0000000002	3	00000000000000000004	005	006	7	00000000000000000008	00009	00010	11	00000000000000000012	00000013	00000014	15	00000000000000000016	00000000000000000017	00000000000000000018	19	00000000000000000020
+2147483647	2147483647	2147483647	00000000002147483647	127	127	127	00000000000000000127	32767	32767	32767	00000000000000032767	08388607	08388607	8388607	00000000000008388607	09223372036854775807	09223372036854775807	9223372036854775807	09223372036854775807
+4294967295	4294967295	4294967295	00000000004294967295	255	255	255	00000000000000000255	65535	65535	65535	00000000000000065535	16777215	16777215	16777215	00000000000016777215	09223372036854775807	09223372036854775807	9223372036854775807	09223372036854775807
+4294967295	4294967295	4294967295	00000000004294967295	255	255	255	00000000000000000255	65535	65535	65535	00000000000000065535	16777215	16777215	16777215	00000000000016777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	00000000004294967295	255	255	255	00000000000000000255	65535	65535	65535	00000000000000065535	16777215	16777215	16777215	00000000000016777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	00000000004294967295	255	255	255	00000000000000000255	65535	65535	65535	00000000000000065535	16777215	16777215	16777215	00000000000016777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+4294967295	4294967295	4294967295	00000000004294967295	255	255	255	00000000000000000255	65535	65535	65535	00000000000000065535	16777215	16777215	16777215	00000000000016777215	18446744073709551615	18446744073709551615	18446744073709551615	18446744073709551615
+ALTER TABLE t1 ADD COLUMN i257 INT(257) ZEROFILL;
+ERROR 42000: Display width out of range for column 'i257' (max = 255)
+DROP TABLE t1;
+CREATE TABLE t1 (
+t TINYINT ZEROFILL,
+s SMALLINT ZEROFILL,
+m MEDIUMINT ZEROFILL,
+i INT ZEROFILL,
+b BIGINT ZEROFILL,
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+t	tinyint(3) unsigned zerofill	YES		NULL	
+s	smallint(5) unsigned zerofill	YES		NULL	
+m	mediumint(8) unsigned zerofill	YES		NULL	
+i	int(10) unsigned zerofill	YES		NULL	
+b	bigint(20) unsigned zerofill	NO	PRI	00000000000000000000	
+INSERT INTO t1 (t,s,m,i,b) VALUES (1,10,100,1000,0);
+SELECT t,s,m,i,b FROM t1;
+t	s	m	i	b
+001	00010	00000100	0000001000	00000000000000000000
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/col_opt_zerofill.test b/mysql-test/suite/leveldb/col_opt_zerofill.test
new file mode 100644
index 0000000..395d174
--- /dev/null
+++ b/mysql-test/suite/leveldb/col_opt_zerofill.test
@@ -0,0 +1,65 @@
+# 
+# ZEROFILL column attribute 
+#
+
+let $extra_col_opts = ZEROFILL;
+
+--echo ########################
+--echo # Fixed point columns (NUMERIC, DECIMAL)
+--echo ########################
+
+--source type_fixed.inc
+
+CREATE TABLE t1 (
+  a DECIMAL ZEROFILL,
+  b NUMERIC ZEROFILL,
+  PRIMARY KEY (a)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b) VALUES (1.1,1234);
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+--echo ########################
+--echo # Floating point columns (FLOAT, DOUBLE)
+--echo ########################
+
+--source type_float.inc
+
+CREATE TABLE t1 (
+  a DOUBLE ZEROFILL,
+  b FLOAT ZEROFILL,
+  PRIMARY KEY (b)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b) VALUES (1,1234.5);
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+--echo ########################
+--echo # INT columns
+--echo ########################
+
+--source type_int.inc
+
+CREATE TABLE t1 (
+  t TINYINT ZEROFILL,
+  s SMALLINT ZEROFILL,
+  m MEDIUMINT ZEROFILL,
+  i INT ZEROFILL,
+  b BIGINT ZEROFILL,
+  PRIMARY KEY (b)
+) ENGINE=LevelDB; 
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (t,s,m,i,b) VALUES (1,10,100,1000,0);
+SELECT t,s,m,i,b FROM t1;
+DROP TABLE t1;
+
+--let $extra_col_opts =
+
diff --git a/mysql-test/suite/leveldb/cons_snapshot_repeatable_read.result b/mysql-test/suite/leveldb/cons_snapshot_repeatable_read.result
new file mode 100644
index 0000000..f37ede1
--- /dev/null
+++ b/mysql-test/suite/leveldb/cons_snapshot_repeatable_read.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+connect  con2,localhost,root,,;
+connection con1;
+CREATE TABLE t1 (a INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection con2;
+INSERT INTO t1 (a) VALUES (1);
+connection con1;
+# If consistent read works on this isolation level (REPEATABLE READ), the following SELECT should not return the value we inserted (1)
+SELECT a FROM t1;
+a
+COMMIT;
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/cons_snapshot_repeatable_read.test b/mysql-test/suite/leveldb/cons_snapshot_repeatable_read.test
new file mode 100644
index 0000000..7b12f73
--- /dev/null
+++ b/mysql-test/suite/leveldb/cons_snapshot_repeatable_read.test
@@ -0,0 +1,4 @@
+let $trx_isolation = REPEATABLE READ;
+
+--source consistent_snapshot.inc
+
diff --git a/mysql-test/suite/leveldb/cons_snapshot_serializable.result b/mysql-test/suite/leveldb/cons_snapshot_serializable.result
new file mode 100644
index 0000000..4d8d5c0
--- /dev/null
+++ b/mysql-test/suite/leveldb/cons_snapshot_serializable.result
@@ -0,0 +1,24 @@
+# -- WARNING ----------------------------------------------------------------
+# According to I_S.ENGINES,  does not support transactions.
+# If it is true, the test will most likely fail; you can 
+# either create an rdiff file, or add the test to disabled.def.
+# If transactions should be supported, check the data in Information Schema.
+# ---------------------------------------------------------------------------
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+connect  con2,localhost,root,,;
+connection con1;
+CREATE TABLE t1 (a INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection con2;
+INSERT INTO t1 (a) VALUES (1);
+connection con1;
+# If consistent read works on this isolation level (SERIALIZABLE), the following SELECT should not return the value we inserted (1)
+SELECT a FROM t1;
+a
+COMMIT;
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/cons_snapshot_serializable.test b/mysql-test/suite/leveldb/cons_snapshot_serializable.test
new file mode 100644
index 0000000..4018e2b
--- /dev/null
+++ b/mysql-test/suite/leveldb/cons_snapshot_serializable.test
@@ -0,0 +1,4 @@
+let $trx_isolation = SERIALIZABLE;
+
+--source consistent_snapshot.inc
+
diff --git a/mysql-test/suite/leveldb/consistent_snapshot.inc b/mysql-test/suite/leveldb/consistent_snapshot.inc
new file mode 100644
index 0000000..5f7cb7c
--- /dev/null
+++ b/mysql-test/suite/leveldb/consistent_snapshot.inc
@@ -0,0 +1,42 @@
+#
+# TRANSACTION WITH CONSISTENT SNAPSHOT
+#
+
+--enable_connect_log
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+
+CREATE TABLE t1 (a INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+eval SET SESSION TRANSACTION ISOLATION LEVEL $trx_isolation;
+
+# While a consistent snapshot transaction is executed,
+# no external inserts should be visible to the transaction.
+# But it should only work this way for REPEATABLE-READ and SERIALIZABLE
+
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+
+connection con2;
+INSERT INTO t1 (a) VALUES (1);
+
+connection con1;
+--echo # If consistent read works on this isolation level ($trx_isolation), the following SELECT should not return the value we inserted (1)
+SELECT a FROM t1; 
+COMMIT;
+
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/suite/leveldb/create_table.result b/mysql-test/suite/leveldb/create_table.result
new file mode 100644
index 0000000..b5d1c45
--- /dev/null
+++ b/mysql-test/suite/leveldb/create_table.result
@@ -0,0 +1,44 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=LevelDB;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+CREATE TABLE IF NOT EXISTS t1 (a INT PRIMARY KEY) ENGINE=LevelDB;
+Warnings:
+Note	1050	Table 't1' already exists
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY) ENGINE=LevelDB;
+ERROR HY000: Table storage engine 'LEVELDB' does not support the create option 'TEMPORARY'
+DROP TABLE t2;
+DROP TABLE IF EXISTS t1;
+SET default_storage_engine = LevelDB;
+CREATE TABLE t1 (a INT PRIMARY KEY);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT PRIMARY KEY) AS SELECT 1 AS a UNION SELECT 2 AS a;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a
+1
+2
+FLUSH LOGS;
+DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/suite/leveldb/create_table.test b/mysql-test/suite/leveldb/create_table.test
new file mode 100644
index 0000000..c6b451f
--- /dev/null
+++ b/mysql-test/suite/leveldb/create_table.test
@@ -0,0 +1,67 @@
+# 
+# Basic CREATE TABLE statements
+#
+
+#############################################
+# TODO:
+# A part of the test is currently disabled 
+# because temporary tables are not supported
+#############################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+# Simple create table with minimal table options
+# which are defined in have_engine.inc
+# (default empty) plus ENGINE=
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=LevelDB;
+SHOW CREATE TABLE t1;
+
+# IF NOT EXISTS
+CREATE TABLE IF NOT EXISTS t1 (a INT PRIMARY KEY) ENGINE=LevelDB;
+
+# CREATE .. LIKE
+
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+
+--error ER_ILLEGAL_HA_CREATE_OPTION 
+CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY) ENGINE=LevelDB;
+
+--disable_parsing
+
+DROP TABLE t2;
+
+CREATE TEMPORARY TABLE t2 LIKE t1;
+
+SHOW CREATE TABLE t2;
+DROP TEMPORARY TABLE t2;
+
+--enable_parsing
+
+DROP TABLE t2;
+
+DROP TABLE IF EXISTS t1;
+
+# CREATE .. AS SELECT
+
+# Use the engine as default
+
+SET default_storage_engine = LevelDB;
+
+CREATE TABLE t1 (a INT PRIMARY KEY);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT PRIMARY KEY) AS SELECT 1 AS a UNION SELECT 2 AS a;
+SHOW CREATE TABLE t1;
+--sorted_result
+SELECT * FROM t1;
+
+# Just to add FLUSH LOGS into the mix while we are in the most common test
+FLUSH LOGS;
+
+DROP TABLE IF EXISTS t1;
+
diff --git a/mysql-test/suite/leveldb/delete.result b/mysql-test/suite/leveldb/delete.result
new file mode 100644
index 0000000..1ee6101
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete.result
@@ -0,0 +1,123 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (10000,'foobar'),(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+DELETE FROM t1 WHERE b IN ('c');
+SELECT a,b FROM t1;
+a	b
+1	a
+1	a
+10000	foobar
+10000	foobar
+2	b
+2	b
+4	d
+4	d
+5	e
+5	e
+DELETE FROM t1 WHERE a < 0 OR b = 'a';
+SELECT a,b FROM t1;
+a	b
+10000	foobar
+10000	foobar
+2	b
+2	b
+4	d
+4	d
+5	e
+5	e
+DELETE FROM t1 WHERE a <= 4 ORDER BY b DESC LIMIT 1;
+SELECT a,b FROM t1;
+a	b
+10000	foobar
+10000	foobar
+2	b
+2	b
+4	d
+5	e
+5	e
+CREATE TABLE t2 (c CHAR(8), d INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+SELECT c,d FROM t2;
+c	d
+b	2
+b	2
+d	4
+e	5
+e	5
+foobar	10000
+foobar	10000
+DELETE t2.* FROM t1, t2 WHERE c < b AND a + d != 1;
+SELECT a,b FROM t1;
+a	b
+10000	foobar
+10000	foobar
+2	b
+2	b
+4	d
+5	e
+5	e
+SELECT c,d FROM t2;
+c	d
+foobar	10000
+foobar	10000
+DELETE FROM t2, t1.* USING t2, t1 WHERE c = 'foobar' and b = c;
+SELECT a,b FROM t1;
+a	b
+2	b
+2	b
+4	d
+5	e
+5	e
+SELECT c,d FROM t2;
+c	d
+DELETE FROM t1;
+SELECT a,b FROM t1;
+a	b
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+BEGIN;
+DELETE FROM t1 WHERE b IN ('c');
+SELECT a,b FROM t1;
+a	b
+1	a
+1	a
+10000	foobar
+10000	foobar
+2	b
+2	b
+4	d
+4	d
+5	e
+5	e
+6	f
+6	f
+7	g
+7	g
+8	h
+8	h
+DELETE FROM t1 WHERE a < 0 OR b = 'a';
+COMMIT;
+SELECT a,b FROM t1;
+a	b
+10000	foobar
+10000	foobar
+2	b
+2	b
+4	d
+4	d
+5	e
+5	e
+6	f
+6	f
+7	g
+7	g
+8	h
+8	h
+BEGIN;
+DELETE FROM t1 WHERE a <= 4 ORDER BY b DESC LIMIT 1;
+SAVEPOINT spt1;
+ERROR 42000: The storage engine for the table doesn't support SAVEPOINT
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/delete.test b/mysql-test/suite/leveldb/delete.test
new file mode 100644
index 0000000..c3187c0
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete.test
@@ -0,0 +1,100 @@
+# 
+# Basic DELETE statements.
+# DELETE LOW_PRIORITY is covered in delete_low_prio test
+# DELETE QUICK is covered in delete_quick test (syntax only)
+# DELETE IGNORE is covered in delete_ignore test
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (10000,'foobar'),(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+# Single-table DELETE
+
+DELETE FROM t1 WHERE b IN ('c');
+--sorted_result
+SELECT a,b FROM t1;
+
+DELETE FROM t1 WHERE a < 0 OR b = 'a';
+--sorted_result
+SELECT a,b FROM t1;
+
+# ORDER BY and LIMIT
+DELETE FROM t1 WHERE a <= 4 ORDER BY b DESC LIMIT 1;
+--sorted_result
+SELECT a,b FROM t1;
+
+# Multi-table DELETE
+
+CREATE TABLE t2 (c CHAR(8), d INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+DELETE t2.* FROM t1, t2 WHERE c < b AND a + d != 1;
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+DELETE FROM t2, t1.* USING t2, t1 WHERE c = 'foobar' and b = c;
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+DELETE FROM t1;
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1, t2;
+
+
+# 
+# Transactional DELETE
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+BEGIN;
+DELETE FROM t1 WHERE b IN ('c');
+--sorted_result
+SELECT a,b FROM t1;
+DELETE FROM t1 WHERE a < 0 OR b = 'a';
+COMMIT;
+--sorted_result
+SELECT a,b FROM t1;
+
+# Savepoints
+
+BEGIN;
+DELETE FROM t1 WHERE a <= 4 ORDER BY b DESC LIMIT 1;
+--error ER_CHECK_NOT_IMPLEMENTED
+SAVEPOINT spt1;
+
+--disable_parsing
+
+DELETE FROM t1;
+RELEASE SAVEPOINT spt1;
+ROLLBACK;
+--sorted_result
+SELECT a,b FROM t1;
+
+BEGIN;
+DELETE FROM t1 WHERE a <= 4 ORDER BY b DESC LIMIT 1;
+SAVEPOINT spt1;
+DELETE FROM t1;
+INSERT INTO t1 (a,b) VALUES (1,'a');
+ROLLBACK TO SAVEPOINT spt1;
+COMMIT;
+
+--enable_parsing
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/delete_ignore.result b/mysql-test/suite/leveldb/delete_ignore.result
new file mode 100644
index 0000000..bd6b595
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete_ignore.result
@@ -0,0 +1,59 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (10000,'foobar'),(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+CREATE TABLE t2 (pk INT AUTO_INCREMENT PRIMARY KEY, c CHAR(8), d INT) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+SELECT a,b FROM t1;
+a	b
+1	a
+1	a
+10000	foobar
+10000	foobar
+2	b
+2	b
+3	c
+3	c
+4	d
+4	d
+5	e
+5	e
+SELECT c,d FROM t2;
+c	d
+a	1
+a	1
+b	2
+b	2
+c	3
+c	3
+d	4
+d	4
+e	5
+e	5
+foobar	10000
+foobar	10000
+DELETE IGNORE FROM t1 WHERE b IS NOT NULL ORDER BY a LIMIT 1;
+SELECT a,b FROM t1;
+a	b
+1	a
+10000	foobar
+10000	foobar
+2	b
+2	b
+3	c
+3	c
+4	d
+4	d
+5	e
+5	e
+DELETE IGNORE t1.*, t2.* FROM t1, t2 WHERE c < b OR a != ( SELECT 1 UNION SELECT 2 );
+Warnings:
+Error	1242	Subquery returns more than 1 row
+SELECT a,b FROM t1;
+a	b
+1	a
+SELECT c,d FROM t2;
+c	d
+foobar	10000
+foobar	10000
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/delete_ignore.test b/mysql-test/suite/leveldb/delete_ignore.test
new file mode 100644
index 0000000..a349c6d
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete_ignore.test
@@ -0,0 +1,35 @@
+# 
+# DELETE IGNORE
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b) VALUES (10000,'foobar'),(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+CREATE TABLE t2 (pk INT AUTO_INCREMENT PRIMARY KEY, c CHAR(8), d INT) ENGINE=LevelDB;
+
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+DELETE IGNORE FROM t1 WHERE b IS NOT NULL ORDER BY a LIMIT 1;
+--sorted_result
+SELECT a,b FROM t1;
+
+DELETE IGNORE t1.*, t2.* FROM t1, t2 WHERE c < b OR a != ( SELECT 1 UNION SELECT 2 );
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+# Cleanup
+DROP TABLE t1, t2;
+
+
diff --git a/mysql-test/suite/leveldb/delete_quick.result b/mysql-test/suite/leveldb/delete_quick.result
new file mode 100644
index 0000000..02ba43f
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete_quick.result
@@ -0,0 +1,24 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY (a)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+DELETE QUICK FROM t1 WHERE a = 1 OR b > 'foo';
+SELECT a,b FROM t1;
+a	b
+2	b
+3	c
+4	d
+5	e
+CREATE TABLE t2 (c CHAR(8), d INT, PRIMARY KEY (c)) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+SELECT c,d FROM t2;
+c	d
+b	2
+c	3
+d	4
+e	5
+DELETE QUICK FROM t2, t1.* USING t2, t1 WHERE c IS NULL OR a = d;
+SELECT a,b FROM t1;
+a	b
+SELECT c,d FROM t2;
+c	d
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/delete_quick.test b/mysql-test/suite/leveldb/delete_quick.test
new file mode 100644
index 0000000..a8d085a
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete_quick.test
@@ -0,0 +1,30 @@
+# 
+# DELETE QUICK syntax.
+# For now we only check that the keyword is accepted,
+# without actually checking whether the feature works.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY (a)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+
+DELETE QUICK FROM t1 WHERE a = 1 OR b > 'foo';
+--sorted_result
+SELECT a,b FROM t1;
+
+CREATE TABLE t2 (c CHAR(8), d INT, PRIMARY KEY (c)) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+DELETE QUICK FROM t2, t1.* USING t2, t1 WHERE c IS NULL OR a = d;
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/delete_with_keys.result b/mysql-test/suite/leveldb/delete_with_keys.result
new file mode 100644
index 0000000..859b47b
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete_with_keys.result
@@ -0,0 +1,38 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, KEY(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'x'),(7,'y'),(8,'z');
+DELETE FROM t1 WHERE b > 'y';
+DELETE FROM t1 WHERE a=2;
+SELECT a,b FROM t1;
+a	b
+1	a
+3	c
+4	d
+5	e
+6	x
+7	y
+DELETE FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'x'),(7,'y'),(8,'z');
+DELETE FROM t1 WHERE b > 'y';
+DELETE FROM t1 WHERE a=2;
+SELECT a,b FROM t1;
+a	b
+1	a
+3	c
+4	d
+5	e
+6	x
+7	y
+DELETE FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT, c INT, pk INT AUTO_INCREMENT PRIMARY KEY, KEY(a), KEY (b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6),(7,8,9);
+DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
+SELECT a,b,c FROM t1;
+a	b	c
+1	2	3
+4	5	6
+7	8	9
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/delete_with_keys.test b/mysql-test/suite/leveldb/delete_with_keys.test
new file mode 100644
index 0000000..e96a29d
--- /dev/null
+++ b/mysql-test/suite/leveldb/delete_with_keys.test
@@ -0,0 +1,37 @@
+# 
+# DELETE statements for tables with keys
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, KEY(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'x'),(7,'y'),(8,'z');
+DELETE FROM t1 WHERE b > 'y';
+DELETE FROM t1 WHERE a=2;
+
+--sorted_result
+SELECT a,b FROM t1;
+DELETE FROM t1;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'x'),(7,'y'),(8,'z');
+DELETE FROM t1 WHERE b > 'y';
+DELETE FROM t1 WHERE a=2;
+
+--sorted_result
+SELECT a,b FROM t1;
+DELETE FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT, b INT, c INT, pk INT AUTO_INCREMENT PRIMARY KEY, KEY(a), KEY (b)) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6),(7,8,9);
+DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
+--sorted_result
+SELECT a,b,c FROM t1;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/describe.result b/mysql-test/suite/leveldb/describe.result
new file mode 100644
index 0000000..7156dee
--- /dev/null
+++ b/mysql-test/suite/leveldb/describe.result
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY (a)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'foo'),(2, 'b');
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY (b)) ENGINE=LevelDB CHARACTER SET utf8;
+INSERT INTO t2 (a,b) VALUES (1, 'bar');
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB CHARACTER SET utf8;
+DESCRIBE t1;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	NO	PRI	0	
+b	char(8)	YES		NULL	
+DESC t2 a;
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+DESCRIBE t3 '%';
+Field	Type	Null	Key	Default	Extra
+a	int(11)	YES		NULL	
+b	char(8)	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/leveldb/describe.test b/mysql-test/suite/leveldb/describe.test
new file mode 100644
index 0000000..b32e0be
--- /dev/null
+++ b/mysql-test/suite/leveldb/describe.test
@@ -0,0 +1,22 @@
+# 
+# DESCRIBE statement
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY (a)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'foo'),(2, 'b');
+
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY (b)) ENGINE=LevelDB CHARACTER SET utf8;
+INSERT INTO t2 (a,b) VALUES (1, 'bar');
+
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB CHARACTER SET utf8;
+
+DESCRIBE t1;
+DESC t2 a;
+DESCRIBE t3 '%';
+
+DROP TABLE t1, t2, t3;
+
diff --git a/mysql-test/suite/leveldb/disabled.def b/mysql-test/suite/leveldb/disabled.def
new file mode 100644
index 0000000..fea7093
--- /dev/null
+++ b/mysql-test/suite/leveldb/disabled.def
@@ -0,0 +1,11 @@
+type_blob_indexes : MDEV-4097 (Indexes on text/blob fields are not allowed)
+type_text_indexes : MDEV-4097 (Indexes on text/blob fields are not allowed)
+cons_snapshot_repeatable_read : Consistent read does not work
+cons_snapshot_serializable : Consistent read does not work
+select_for_update : Not supported?
+select_lock_in_share_mode : Not supported?
+level_read_committed : Not supported?
+level_read_uncommitted : Not supported?
+level_serializable: Not supported?
+level_repeatable_read: Can't seen own changes
+
diff --git a/mysql-test/suite/leveldb/index.inc b/mysql-test/suite/leveldb/index.inc
new file mode 100644
index 0000000..1d1b92b
--- /dev/null
+++ b/mysql-test/suite/leveldb/index.inc
@@ -0,0 +1,113 @@
+# 
+# Basic syntax related to indexes: 
+#   unique and non-unique keys,
+#   single- and multi-column keys,
+#   index option COMMENT.
+#   
+# See other index* tests for operations 
+# which are less likely to be supported
+#
+# PRIMARY KEY syntax is covered in index_primary test.
+# Index types BTREE|HASH -- in index_type_btree|hash tests.
+# SPATIAL -- in type_spatial_indexes test.
+# FULLTEXT -- in fulltext_search test.
+# KEY_BLOCK_SIZE -- in index_key_block_size test.
+#
+# Usage to call the test from another test:
+#
+# A calling test may define $index_type, in which case
+#   USING clause will be added to the syntax.
+# 
+
+################################################
+# TODO:
+# A part of the test is disabled because unique indexes
+# are not currently supported
+################################################
+
+
+let $using_index_type = ;
+if ($index_type)
+{
+  let $using_index_type = USING $index_type;
+}
+
+
+eval CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT PRIMARY KEY,
+  KEY $using_index_type (a)
+) ENGINE=LevelDB;
+
+SHOW KEYS IN t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT PRIMARY KEY,
+  KEY a_b $using_index_type (a,b) COMMENT 'a_b index'
+) ENGINE=LevelDB;
+
+SHOW KEYS IN t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT PRIMARY KEY,
+  KEY $using_index_type (a),
+  KEY $using_index_type (b)
+) ENGINE=LevelDB;
+
+SHOW KEYS IN t1;
+DROP TABLE t1;
+
+--disable_parsing
+
+eval CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT PRIMARY KEY,
+  UNIQUE INDEX $using_index_type (a)
+) ENGINE=LevelDB;
+
+SHOW KEYS IN t1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+--error ER_DUP_ENTRY,ER_DUP_KEY
+INSERT INTO t1 (a,b) VALUES (1,'c');
+
+DROP TABLE t1;
+
+--enable_parsing
+
+#
+# ALTER TABLE
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'z');
+
+eval ALTER TABLE t1 ADD KEY (a) $using_index_type COMMENT 'simple index on a';
+SHOW INDEX FROM t1;
+ALTER TABLE t1 DROP KEY a;
+DROP TABLE t1;
+
+--disable_parsing
+
+eval CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  UNIQUE INDEX $using_index_type (a)
+) ENGINE=LevelDB;
+
+SHOW KEYS IN t1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+--error ER_DUP_ENTRY,ER_DUP_KEY
+INSERT INTO t1 (a,b) VALUES (1,'c');
+
+ALTER TABLE t1 DROP INDEX a;
+INSERT INTO t1 (a,b) VALUES (1,'c');
+--error ER_DUP_ENTRY
+eval ALTER TABLE t1 ADD UNIQUE INDEX a(a) $using_index_type;
+DROP TABLE t1;
+
+--enable_parsing
+
diff --git a/mysql-test/suite/leveldb/index.result b/mysql-test/suite/leveldb/index.result
new file mode 100644
index 0000000..1db6959
--- /dev/null
+++ b/mysql-test/suite/leveldb/index.result
@@ -0,0 +1,42 @@
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY  (a)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY a_b  (a,b) COMMENT 'a_b index'
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a_b	1	a	A	NULL	NULL	NULL	YES	BTREE		a_b index
+t1	1	a_b	2	b	A	NULL	NULL	NULL	YES	BTREE		a_b index
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY  (a),
+KEY  (b)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'z');
+ALTER TABLE t1 ADD KEY (a)  COMMENT 'simple index on a';
+SHOW INDEX FROM t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		simple index on a
+ALTER TABLE t1 DROP KEY a;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/index.test b/mysql-test/suite/leveldb/index.test
new file mode 100644
index 0000000..86b6464
--- /dev/null
+++ b/mysql-test/suite/leveldb/index.test
@@ -0,0 +1,21 @@
+# 
+# Basic syntax related to indexes: 
+#   unique and non-unique keys,
+#   single- and multi-column keys,
+#   index option COMMENT.
+#   
+# See other index* tests for operations 
+# which are less likely to be supported
+#
+# PRIMARY KEY syntax is covered in index_primary test.
+# Index types BTREE|HASH -- in index_type_btree|hash tests.
+# SPATIAL -- in type_spatial_indexes test.
+# FULLTEXT -- in fulltext_search test.
+# KEY_BLOCK_SIZE -- in index_key_block_size test.
+#
+
+# (Default index type)
+
+--source index.inc
+
+
diff --git a/mysql-test/suite/leveldb/index_key_block_size.result b/mysql-test/suite/leveldb/index_key_block_size.result
new file mode 100644
index 0000000..7655509
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_key_block_size.result
@@ -0,0 +1,51 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY (a) KEY_BLOCK_SIZE=8
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY ind1(b ASC) KEY_BLOCK_SIZE=0
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	ind1	1	b	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+PRIMARY KEY ind2(b(1) DESC) KEY_BLOCK_SIZE=32768 COMMENT 'big key_block_size value'
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b	A	NULL	1	NULL		BTREE		big key_block_size value
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT AUTO_INCREMENT PRIMARY KEY,
+KEY a_b(a,b) KEY_BLOCK_SIZE=8192
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a_b	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	1	a_b	2	b	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'z');
+ALTER TABLE t1 ADD KEY(a) KEY_BLOCK_SIZE 8192;
+SHOW INDEX FROM t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/index_key_block_size.test b/mysql-test/suite/leveldb/index_key_block_size.test
new file mode 100644
index 0000000..14e56e6
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_key_block_size.test
@@ -0,0 +1,65 @@
+# 
+# KEY_BLOCK_SIZE index option.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT PRIMARY KEY,
+  KEY (a) KEY_BLOCK_SIZE=8
+) ENGINE=LevelDB;
+
+#--replace_column 6 # 7 # 10 # 11 #
+SHOW KEYS IN t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT PRIMARY KEY,
+  KEY ind1(b ASC) KEY_BLOCK_SIZE=0
+) ENGINE=LevelDB;
+
+# --replace_column 6 # 7 # 10 # 11 #
+SHOW INDEX IN t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  PRIMARY KEY ind2(b(1) DESC) KEY_BLOCK_SIZE=32768 COMMENT 'big key_block_size value'
+) ENGINE=LevelDB;
+
+#--replace_column 6 # 7 # 10 # 11 # 
+SHOW INDEX IN t1;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  KEY a_b(a,b) KEY_BLOCK_SIZE=8192
+) ENGINE=LevelDB;
+
+#--replace_column 6 # 7 # 10 # 11 #
+SHOW INDEX IN t1;
+  
+DROP TABLE t1;
+
+#
+# ALTER TABLE
+#
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  PRIMARY KEY (b)
+) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b) VALUES (100,'z');
+
+ALTER TABLE t1 ADD KEY(a) KEY_BLOCK_SIZE 8192;
+SHOW INDEX FROM t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/index_primary.result b/mysql-test/suite/leveldb/index_primary.result
new file mode 100644
index 0000000..e12c97c
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_primary.result
@@ -0,0 +1,52 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY,
+b CHAR(8)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	a	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+INSERT INTO t1 (a,b) VALUES (1,'c');
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+DROP TABLE t1;
+CREATE TABLE t1 (a INT PRIMARY KEY,
+b CHAR(8) PRIMARY KEY
+) ENGINE=LevelDB;
+ERROR 42000: Multiple primary key defined
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+PRIMARY KEY (a,b)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	a	A	NULL	NULL	NULL		BTREE		
+t1	0	PRIMARY	2	b	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (a,b) VALUES (1,'a'),(1,'b'),(2,'a'),(2,'b');
+INSERT INTO t1 (a,b) VALUES (1,'b');
+ERROR 23000: Duplicate entry '1-b' for key 'PRIMARY'
+DROP TABLE t1;
+CREATE TABLE t1 (a INT KEY,
+b CHAR(8),
+KEY (b)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	a	A	NULL	NULL	NULL		BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8) PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b	A	NULL	NULL	NULL		BTREE		
+ALTER TABLE t1 DROP INDEX `PRIMARY`;
+ERROR 42000: This table type requires a primary key
+ALTER TABLE t1 ADD CONSTRAINT PRIMARY KEY pk (a);
+ERROR 42000: Multiple primary key defined
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b	A	NULL	NULL	NULL		BTREE		
+ALTER TABLE t1 DROP PRIMARY KEY;
+ERROR 42000: This table type requires a primary key
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/index_primary.test b/mysql-test/suite/leveldb/index_primary.test
new file mode 100644
index 0000000..4c3acbf
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_primary.test
@@ -0,0 +1,61 @@
+# 
+# Basic syntax related to primary keys 
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY,
+  b CHAR(8)
+) ENGINE=LevelDB;
+
+SHOW KEYS IN t1;
+
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (1,'c');
+
+DROP TABLE t1;
+
+--error ER_MULTIPLE_PRI_KEY
+CREATE TABLE t1 (a INT PRIMARY KEY,
+  b CHAR(8) PRIMARY KEY
+) ENGINE=LevelDB;
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8),
+  PRIMARY KEY (a,b)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(1,'b'),(2,'a'),(2,'b');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (1,'b');
+  DROP TABLE t1;
+
+# KEY in a column definition means PK!
+
+CREATE TABLE t1 (a INT KEY,
+  b CHAR(8),
+  KEY (b)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT,
+  b CHAR(8) PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+--error ER_REQUIRES_PRIMARY_KEY
+ALTER TABLE t1 DROP INDEX `PRIMARY`;
+--error ER_MULTIPLE_PRI_KEY
+ALTER TABLE t1 ADD CONSTRAINT PRIMARY KEY pk (a);
+SHOW KEYS IN t1;
+--error ER_REQUIRES_PRIMARY_KEY
+ALTER TABLE t1 DROP PRIMARY KEY;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/index_type_btree.result b/mysql-test/suite/leveldb/index_type_btree.result
new file mode 100644
index 0000000..812042f
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_type_btree.result
@@ -0,0 +1,42 @@
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY USING BTREE (a)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY a_b USING BTREE (a,b) COMMENT 'a_b index'
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a_b	1	a	A	NULL	NULL	NULL	YES	BTREE		a_b index
+t1	1	a_b	2	b	A	NULL	NULL	NULL	YES	BTREE		a_b index
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY USING BTREE (a),
+KEY USING BTREE (b)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'z');
+ALTER TABLE t1 ADD KEY (a) USING BTREE COMMENT 'simple index on a';
+SHOW INDEX FROM t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		simple index on a
+ALTER TABLE t1 DROP KEY a;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/index_type_btree.test b/mysql-test/suite/leveldb/index_type_btree.test
new file mode 100644
index 0000000..a5de672
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_type_btree.test
@@ -0,0 +1,10 @@
+#
+# Index type BTREE
+#
+
+let $index_type = BTREE;
+
+--source index.inc
+
+let $index_type =;
+
diff --git a/mysql-test/suite/leveldb/index_type_hash.result b/mysql-test/suite/leveldb/index_type_hash.result
new file mode 100644
index 0000000..3d60951
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_type_hash.result
@@ -0,0 +1,42 @@
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY USING HASH (a)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY a_b USING HASH (a,b) COMMENT 'a_b index'
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a_b	1	a	A	NULL	NULL	NULL	YES	BTREE		a_b index
+t1	1	a_b	2	b	A	NULL	NULL	NULL	YES	BTREE		a_b index
+DROP TABLE t1;
+CREATE TABLE t1 (a INT,
+b CHAR(8),
+pk INT PRIMARY KEY,
+KEY USING HASH (a),
+KEY USING HASH (b)
+) ENGINE=LevelDB;
+SHOW KEYS IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'z');
+ALTER TABLE t1 ADD KEY (a) USING HASH COMMENT 'simple index on a';
+SHOW INDEX FROM t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		simple index on a
+ALTER TABLE t1 DROP KEY a;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/index_type_hash.test b/mysql-test/suite/leveldb/index_type_hash.test
new file mode 100644
index 0000000..f67f248
--- /dev/null
+++ b/mysql-test/suite/leveldb/index_type_hash.test
@@ -0,0 +1,10 @@
+#
+# Index type HASH
+#
+
+let $index_type = HASH;
+
+--source index.inc
+
+let $index_type =;
+
diff --git a/mysql-test/suite/leveldb/insert.result b/mysql-test/suite/leveldb/insert.result
new file mode 100644
index 0000000..21a12f2
--- /dev/null
+++ b/mysql-test/suite/leveldb/insert.result
@@ -0,0 +1,209 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (100,'foobar',100),(1,'a',101),(2,'b',103),(3,'c',104),(4,'d',105),(5,'e',106);
+SELECT a,b FROM t1;
+a	b
+1	a
+100	foobar
+2	b
+3	c
+4	d
+5	e
+INSERT t1 VALUE (10,'foo',107),(11,'abc',108);
+SELECT a,b FROM t1;
+a	b
+1	a
+10	foo
+100	foobar
+11	abc
+2	b
+3	c
+4	d
+5	e
+INSERT INTO t1 (b,a) VALUES ('test',0);
+SELECT a,b FROM t1;
+a	b
+0	test
+1	a
+10	foo
+100	foobar
+11	abc
+2	b
+3	c
+4	d
+5	e
+INSERT INTO t1 VALUES (DEFAULT,DEFAULT,NULL);
+SELECT a,b FROM t1;
+a	b
+0	test
+1	a
+10	foo
+100	foobar
+11	abc
+2	b
+3	c
+4	d
+5	e
+NULL	NULL
+INSERT t1 (a) VALUE (10),(20);
+SELECT a,b FROM t1;
+a	b
+0	test
+1	a
+10	NULL
+10	foo
+100	foobar
+11	abc
+2	b
+20	NULL
+3	c
+4	d
+5	e
+NULL	NULL
+INSERT INTO t1 SET a = 11, b = 'f';
+SELECT a,b FROM t1;
+a	b
+0	test
+1	a
+10	NULL
+10	foo
+100	foobar
+11	abc
+11	f
+2	b
+20	NULL
+3	c
+4	d
+5	e
+NULL	NULL
+INSERT t1 SET b = DEFAULT;
+SELECT a,b FROM t1;
+a	b
+0	test
+1	a
+10	NULL
+10	foo
+100	foobar
+11	abc
+11	f
+2	b
+20	NULL
+3	c
+4	d
+5	e
+NULL	NULL
+NULL	NULL
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 SELECT a,b,pk FROM t1;
+INSERT INTO t1 (a) SELECT a FROM t2 WHERE b = 'foo';
+SELECT a,b FROM t1;
+a	b
+0	test
+1	a
+10	NULL
+10	NULL
+10	foo
+100	foobar
+11	abc
+11	f
+2	b
+20	NULL
+3	c
+4	d
+5	e
+NULL	NULL
+NULL	NULL
+INSERT t1 (a,b) SELECT a,b FROM t1;
+SELECT a,b FROM t1;
+a	b
+0	test
+0	test
+1	a
+1	a
+10	NULL
+10	NULL
+10	NULL
+10	NULL
+10	foo
+10	foo
+100	foobar
+100	foobar
+11	abc
+11	abc
+11	f
+11	f
+2	b
+2	b
+20	NULL
+20	NULL
+3	c
+3	c
+4	d
+4	d
+5	e
+5	e
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+BEGIN;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(100,'foo');
+INSERT t1 (a,b) VALUE (10,'foo'),(11,'abc');
+COMMIT;
+SELECT a,b FROM t1;
+a	b
+1	a
+10	foo
+100	foo
+11	abc
+2	b
+3	c
+4	d
+5	e
+BEGIN;
+INSERT INTO t1 (b,a) VALUES ('test',0);
+SAVEPOINT spt1;
+ERROR 42000: The storage engine for the table doesn't support SAVEPOINT
+INSERT INTO t1 (a,b) VALUES (DEFAULT,DEFAULT);
+RELEASE SAVEPOINT spt1;
+Got one of the listed errors
+INSERT INTO t1 (a,b) VALUES (DEFAULT,DEFAULT);
+ROLLBACK;
+SELECT a,b FROM t1;
+a	b
+1	a
+10	foo
+100	foo
+11	abc
+2	b
+3	c
+4	d
+5	e
+BEGIN;
+INSERT t1 (a) VALUE (10),(20);
+SAVEPOINT spt1;
+ERROR 42000: The storage engine for the table doesn't support SAVEPOINT
+INSERT INTO t1 SET a = 11, b = 'f';
+INSERT t1 SET b = DEFAULT;
+ROLLBACK TO SAVEPOINT spt1;
+Got one of the listed errors
+INSERT INTO t1 (b,a) VALUES ('test1',10);
+COMMIT;
+SELECT a,b FROM t1;
+a	b
+1	a
+10	NULL
+10	foo
+10	test1
+100	foo
+11	abc
+11	f
+2	b
+20	NULL
+3	c
+4	d
+5	e
+NULL	NULL
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/insert.test b/mysql-test/suite/leveldb/insert.test
new file mode 100644
index 0000000..aab8659
--- /dev/null
+++ b/mysql-test/suite/leveldb/insert.test
@@ -0,0 +1,99 @@
+# 
+# Basic INSERT statements
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+# INSERT [INTO] .. VALUES|VALUE ..
+
+INSERT INTO t1 VALUES (100,'foobar',100),(1,'a',101),(2,'b',103),(3,'c',104),(4,'d',105),(5,'e',106);
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT t1 VALUE (10,'foo',107),(11,'abc',108);
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT INTO t1 (b,a) VALUES ('test',0);
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT INTO t1 VALUES (DEFAULT,DEFAULT,NULL);
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT t1 (a) VALUE (10),(20);
+--sorted_result
+SELECT a,b FROM t1;
+
+# INSERT [INTO] .. SET 
+
+INSERT INTO t1 SET a = 11, b = 'f';
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT t1 SET b = DEFAULT;
+--sorted_result
+SELECT a,b FROM t1;
+
+
+# INSERT .. SELECT
+
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+INSERT INTO t2 SELECT a,b,pk FROM t1;
+INSERT INTO t1 (a) SELECT a FROM t2 WHERE b = 'foo';
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT t1 (a,b) SELECT a,b FROM t1;
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1, t2;
+
+# 
+# Transactional INSERT
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+BEGIN;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(100,'foo');
+INSERT t1 (a,b) VALUE (10,'foo'),(11,'abc');
+COMMIT;
+--sorted_result
+SELECT a,b FROM t1;
+
+BEGIN;
+INSERT INTO t1 (b,a) VALUES ('test',0);
+--error ER_CHECK_NOT_IMPLEMENTED
+SAVEPOINT spt1;
+INSERT INTO t1 (a,b) VALUES (DEFAULT,DEFAULT);
+--error ER_CHECK_NOT_IMPLEMENTED,ER_SP_DOES_NOT_EXIST
+RELEASE SAVEPOINT spt1;
+INSERT INTO t1 (a,b) VALUES (DEFAULT,DEFAULT);
+ROLLBACK;
+--sorted_result
+SELECT a,b FROM t1;
+
+BEGIN;
+INSERT t1 (a) VALUE (10),(20);
+--error ER_CHECK_NOT_IMPLEMENTED
+SAVEPOINT spt1;
+INSERT INTO t1 SET a = 11, b = 'f';
+INSERT t1 SET b = DEFAULT;
+--error ER_CHECK_NOT_IMPLEMENTED,ER_SP_DOES_NOT_EXIST
+ROLLBACK TO SAVEPOINT spt1;
+INSERT INTO t1 (b,a) VALUES ('test1',10);
+COMMIT;
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/insert_with_keys.result b/mysql-test/suite/leveldb/insert_with_keys.result
new file mode 100644
index 0000000..ba0f2d0
--- /dev/null
+++ b/mysql-test/suite/leveldb/insert_with_keys.result
@@ -0,0 +1,63 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, KEY(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) VALUES (100,'a'), (6,'f');
+INSERT INTO t1 (a,b) VALUES (30,'m'),(29,'n');
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+INSERT INTO t1 (a,b) VALUES (3,'a'),(0,'');
+SELECT a,b FROM t1;
+a	b
+0	
+1	a
+1	a
+100	a
+12345	z
+2	b
+29	n
+3	a
+3	c
+30	m
+4	d
+5	e
+6	f
+DROP TABLE t1;
+#----------------------------------------
+# UNIQUE KEYS are not supported currently
+#-----------------------------------------
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) VALUES (100,'a'), (6,'f');
+INSERT INTO t1 (a,b) VALUES (30,'m'),(29,'n');
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+INSERT INTO t1 (a,b) VALUES (3,'a'),(0,'');
+ERROR 23000: Duplicate entry '3' for key 'PRIMARY'
+INSERT INTO t1 (a,b) VALUES (0,'');
+SELECT a,b FROM t1;
+a	b
+0	
+1	a
+100	a
+2	b
+29	n
+3	c
+30	m
+4	d
+5	e
+6	f
+INSERT IGNORE INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z') ON DUPLICATE KEY UPDATE b = CONCAT(b,b);
+SELECT a,b FROM t1;
+a	b
+0	
+1	aa
+100	a
+12345	zz
+2	b
+29	n
+3	c
+30	m
+4	d
+5	e
+6	f
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/insert_with_keys.test b/mysql-test/suite/leveldb/insert_with_keys.test
new file mode 100644
index 0000000..171ec49
--- /dev/null
+++ b/mysql-test/suite/leveldb/insert_with_keys.test
@@ -0,0 +1,91 @@
+# 
+# INSERT statements for tables with keys
+#
+
+##################################################
+# TODO:
+# A part of the test is disabled because currently
+# unique indexes are not supported
+##################################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, KEY(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) VALUES (100,'a'), (6,'f');
+INSERT INTO t1 (a,b) VALUES (30,'m'),(29,'n');
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+INSERT INTO t1 (a,b) VALUES (3,'a'),(0,'');
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+--echo #----------------------------------------
+--echo # UNIQUE KEYS are not supported currently
+--echo #-----------------------------------------
+
+--disable_parsing
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, UNIQUE INDEX(a)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) VALUES (100,'a'), (6,'f');
+INSERT INTO t1 (a,b) VALUES (30,'m'),(29,'n');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (3,'a'),(0,'');
+INSERT INTO t1 (a,b) VALUES (0,'');
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT IGNORE INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+INSERT INTO t1 (a,b) VALUES (3,'a'),(4,'d') ON DUPLICATE KEY UPDATE a = a+10;
+
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, UNIQUE INDEX(a,b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) VALUES (100,'a'), (6,'f');
+INSERT INTO t1 (a,b) VALUES (30,'m'),(29,'n');
+INSERT INTO t1 (a,b) VALUES (100,'b'), (2,'c');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT IGNORE INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z') ON DUPLICATE KEY UPDATE a = a+VALUES(a);
+--sorted_result
+SELECT a,b FROM t1;
+
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (101,'x'),(101,'x');
+DROP TABLE t1;
+
+--enable_parsing
+
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+INSERT INTO t1 (a,b) VALUES (100,'a'), (6,'f');
+INSERT INTO t1 (a,b) VALUES (30,'m'),(29,'n');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (3,'a'),(0,'');
+INSERT INTO t1 (a,b) VALUES (0,'');
+--sorted_result
+SELECT a,b FROM t1;
+
+INSERT IGNORE INTO t1 (a,b) VALUES (1,'a'),(12345,'z');
+INSERT INTO t1 (a,b) VALUES (1,'a'),(12345,'z') ON DUPLICATE KEY UPDATE b = CONCAT(b,b);
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/level_read_committed.result b/mysql-test/suite/leveldb/level_read_committed.result
new file mode 100644
index 0000000..ce1b126
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_read_committed.result
@@ -0,0 +1,91 @@
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+connect  con2,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+connection con1;
+CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+START TRANSACTION;
+SELECT a FROM t1;
+a
+connection con2;
+BEGIN;
+INSERT INTO t1 (a) VALUES(1);
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+connection con2;
+INSERT INTO t1 (a) VALUES (2);
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+INSERT INTO t1 (a) SELECT a+100 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+connection con2;
+SELECT a FROM t1;
+a
+1
+2
+COMMIT;
+SELECT a FROM t1;
+a
+1
+2
+connection con1;
+SELECT a FROM t1;
+a
+1
+2
+INSERT INTO t1 (a) SELECT a+200 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+1
+2
+201
+202
+COMMIT;
+SELECT a FROM t1;
+a
+1
+2
+201
+202
+connection con2;
+SELECT a FROM t1;
+a
+1
+2
+201
+202
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+connect  con2,localhost,root,,;
+connection con1;
+CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection con2;
+INSERT INTO t1 (a) VALUES (1);
+connection con1;
+# If consistent read works on this isolation level (READ COMMITTED), the following SELECT should not return the value we inserted (1)
+SELECT a FROM t1;
+a
+1
+COMMIT;
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/level_read_committed.test b/mysql-test/suite/leveldb/level_read_committed.test
new file mode 100644
index 0000000..cc27fc4
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_read_committed.test
@@ -0,0 +1,5 @@
+let $trx_isolation = READ COMMITTED;
+
+--source transaction_isolation.inc
+--source consistent_snapshot.inc
+
diff --git a/mysql-test/suite/leveldb/level_read_uncommitted.result b/mysql-test/suite/leveldb/level_read_uncommitted.result
new file mode 100644
index 0000000..68fbe56
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_read_uncommitted.result
@@ -0,0 +1,116 @@
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+connect  con2,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+connection con1;
+CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+START TRANSACTION;
+SELECT a FROM t1;
+a
+connection con2;
+BEGIN;
+INSERT INTO t1 (a) VALUES(1);
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+1
+connection con2;
+INSERT INTO t1 (a) VALUES (2);
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+1
+2
+INSERT INTO t1 (a) SELECT a+100 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+connection con2;
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+COMMIT;
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+connection con1;
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+INSERT INTO t1 (a) SELECT a+200 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+201
+202
+301
+302
+COMMIT;
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+201
+202
+301
+302
+connection con2;
+SELECT a FROM t1;
+a
+1
+101
+102
+2
+201
+202
+301
+302
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+connect  con2,localhost,root,,;
+connection con1;
+CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection con2;
+INSERT INTO t1 (a) VALUES (1);
+connection con1;
+# If consistent read works on this isolation level (READ UNCOMMITTED), the following SELECT should not return the value we inserted (1)
+SELECT a FROM t1;
+a
+1
+COMMIT;
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/level_read_uncommitted.test b/mysql-test/suite/leveldb/level_read_uncommitted.test
new file mode 100644
index 0000000..c26d3c9
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_read_uncommitted.test
@@ -0,0 +1,4 @@
+let $trx_isolation = READ UNCOMMITTED;
+--source transaction_isolation.inc
+--source consistent_snapshot.inc
+
diff --git a/mysql-test/suite/leveldb/level_repeatable_read.result b/mysql-test/suite/leveldb/level_repeatable_read.result
new file mode 100644
index 0000000..c828b18
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_repeatable_read.result
@@ -0,0 +1,69 @@
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+connect  con2,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+connection con1;
+CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+START TRANSACTION;
+SELECT a FROM t1;
+a
+connection con2;
+BEGIN;
+INSERT INTO t1 (a) VALUES(1);
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+connection con2;
+INSERT INTO t1 (a) VALUES (2);
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+INSERT INTO t1 (a) SELECT a+100 FROM t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+connection con2;
+SELECT a FROM t1;
+a
+1
+2
+COMMIT;
+SELECT a FROM t1;
+a
+1
+2
+connection con1;
+SELECT a FROM t1;
+a
+INSERT INTO t1 (a) SELECT a+200 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+201
+202
+COMMIT;
+SELECT a FROM t1;
+a
+1
+2
+201
+202
+connection con2;
+SELECT a FROM t1;
+a
+1
+2
+201
+202
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/level_repeatable_read.test b/mysql-test/suite/leveldb/level_repeatable_read.test
new file mode 100644
index 0000000..9a3fe5b
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_repeatable_read.test
@@ -0,0 +1,3 @@
+let $trx_isolation = REPEATABLE READ;
+--source transaction_isolation.inc
+
diff --git a/mysql-test/suite/leveldb/level_serializable.result b/mysql-test/suite/leveldb/level_serializable.result
new file mode 100644
index 0000000..3f57395
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_serializable.result
@@ -0,0 +1,56 @@
+DROP TABLE IF EXISTS t1;
+connect  con1,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+connect  con2,localhost,root,,;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+connection con1;
+CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+START TRANSACTION;
+SELECT a FROM t1;
+a
+connection con2;
+BEGIN;
+INSERT INTO t1 (a) VALUES(1);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+connection con2;
+INSERT INTO t1 (a) VALUES (2);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+# WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'. 
+#          If it differs from the result file, it might indicate a problem.
+connection con1;
+SELECT a FROM t1;
+a
+INSERT INTO t1 (a) SELECT a+100 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+connection con2;
+SELECT a FROM t1;
+a
+COMMIT;
+SELECT a FROM t1;
+a
+connection con1;
+SELECT a FROM t1;
+a
+INSERT INTO t1 (a) SELECT a+200 FROM t1;
+# WARNING: Statement ended with errno 0, errname ''. 
+#          If it differs from the result file, it might indicate a problem.
+SELECT a FROM t1;
+a
+COMMIT;
+SELECT a FROM t1;
+a
+connection con2;
+SELECT a FROM t1;
+a
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/level_serializable.test b/mysql-test/suite/leveldb/level_serializable.test
new file mode 100644
index 0000000..207aa43
--- /dev/null
+++ b/mysql-test/suite/leveldb/level_serializable.test
@@ -0,0 +1,3 @@
+let $trx_isolation = SERIALIZABLE;
+--source transaction_isolation.inc
+
diff --git a/mysql-test/suite/leveldb/loaddata.result b/mysql-test/suite/leveldb/loaddata.result
new file mode 100644
index 0000000..9f2df8a
--- /dev/null
+++ b/mysql-test/suite/leveldb/loaddata.result
@@ -0,0 +1,93 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+LOAD DATA INFILE '<DATADIR>/se_loaddata.dat' INTO TABLE t1 
+FIELDS TERMINATED BY ',' (a,b);
+SELECT a,b FROM t1;
+a	b
+1	foo
+2	bar
+3	
+4	abc
+LOAD DATA LOCAL INFILE '<DATADIR>/se_loaddata.dat' INTO TABLE t1
+CHARACTER SET utf8 COLUMNS TERMINATED BY ','
+  ESCAPED BY '/' (a,b);
+SELECT a,b FROM t1;
+a	b
+1	foo
+1	foo
+2	bar
+2	bar
+3	
+3	
+4	abc
+4	abc
+LOAD DATA LOCAL INFILE '<DATADIR>/se_loaddata.dat' INTO TABLE t1
+FIELDS TERMINATED BY ';'
+  (a) SET b='loaded';
+Warnings:
+Warning	1262	Row 1 was truncated; it contained more data than there were input columns
+Warning	1262	Row 2 was truncated; it contained more data than there were input columns
+Warning	1262	Row 3 was truncated; it contained more data than there were input columns
+SELECT a,b FROM t1;
+a	b
+0	loaded
+1	foo
+1	foo
+102	loaded
+2	bar
+2	bar
+3	
+3	
+4	abc
+4	abc
+5	loaded
+LOAD DATA INFILE '<DATADIR>/se_loaddata.dat' INTO TABLE t1
+FIELDS TERMINATED BY ';'
+  OPTIONALLY ENCLOSED BY ''''
+  LINES STARTING BY 'prefix:' 
+IGNORE 2 LINES (a,b);
+Warnings:
+Warning	1262	Row 2 was truncated; it contained more data than there were input columns
+SELECT a,b FROM t1;
+a	b
+0	
+0	loaded
+1	foo
+1	foo
+100	foo
+102	loaded
+2	bar
+2	bar
+3	
+3	
+4	abc
+4	abc
+5	loaded
+7	test
+LOAD DATA INFILE '<DATADIR>/se_loaddata.dat' INTO TABLE t1;
+Warnings:
+Warning	1261	Row 1 doesn't contain data for all columns
+Warning	1261	Row 2 doesn't contain data for all columns
+Warning	1261	Row 3 doesn't contain data for all columns
+Warning	1261	Row 4 doesn't contain data for all columns
+SELECT a,b FROM t1;
+a	b
+0	
+0	loaded
+1	foo
+1	foo
+1	foo
+100	foo
+102	loaded
+2	bar
+2	bar
+2	bar
+3	
+3	
+3	
+4	abc
+4	abc
+4	abc
+5	loaded
+7	test
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/loaddata.test b/mysql-test/suite/leveldb/loaddata.test
new file mode 100644
index 0000000..437e847
--- /dev/null
+++ b/mysql-test/suite/leveldb/loaddata.test
@@ -0,0 +1,91 @@
+# 
+# Basic LOAD DATA statements
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+let $datadir = `SELECT @@datadir`;
+
+--write_file $datadir/se_loaddata.dat
+1,foo,
+2,bar,
+3,,
+4,abc,
+EOF
+
+--replace_result $datadir <DATADIR>
+eval
+LOAD DATA INFILE '$datadir/se_loaddata.dat' INTO TABLE t1 
+  FIELDS TERMINATED BY ',' (a,b);
+--sorted_result
+SELECT a,b FROM t1;
+
+--replace_result $datadir <DATADIR>
+eval
+LOAD DATA LOCAL INFILE '$datadir/se_loaddata.dat' INTO TABLE t1
+  CHARACTER SET utf8 COLUMNS TERMINATED BY ','
+  ESCAPED BY '/' (a,b);
+--sorted_result
+SELECT a,b FROM t1;
+
+--remove_file $datadir/se_loaddata.dat
+--write_file $datadir/se_loaddata.dat
+5;YYY;
+102;'zzz';
+0;'test';
+EOF
+
+--replace_result $datadir <DATADIR>
+eval
+LOAD DATA LOCAL INFILE '$datadir/se_loaddata.dat' INTO TABLE t1
+  FIELDS TERMINATED BY ';'
+  (a) SET b='loaded';
+
+--sorted_result
+SELECT a,b FROM t1;
+
+--remove_file $datadir/se_loaddata.dat
+--write_file $datadir/se_loaddata.dat
+prefix:5;'foo';
+prefix:6;'';
+prefix:100;foo;
+prefix:7;'test';suffix
+101;abc;
+102;'z';
+prefix:0;;
+EOF
+
+--replace_result $datadir <DATADIR>
+eval
+LOAD DATA INFILE '$datadir/se_loaddata.dat' INTO TABLE t1
+  FIELDS TERMINATED BY ';'
+  OPTIONALLY ENCLOSED BY ''''
+  LINES STARTING BY 'prefix:' 
+  IGNORE 2 LINES (a,b);
+
+--sorted_result
+SELECT a,b FROM t1;
+
+--remove_file $datadir/se_loaddata.dat
+--write_file $datadir/se_loaddata.dat
+1	foo
+2	bar
+3	
+4	abc
+EOF
+
+--replace_result $datadir <DATADIR>
+eval
+LOAD DATA INFILE '$datadir/se_loaddata.dat' INTO TABLE t1;
+--sorted_result
+SELECT a,b FROM t1;
+
+--remove_file $datadir/se_loaddata.dat
+
+# Cleanup
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/lock.result b/mysql-test/suite/leveldb/lock.result
new file mode 100644
index 0000000..12e9969
--- /dev/null
+++ b/mysql-test/suite/leveldb/lock.result
@@ -0,0 +1,108 @@
+connect  con1,localhost,root,,;
+SET lock_wait_timeout=1;
+connection default;
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1 (id INT, id2 INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (id,id2) VALUES (1,1),(1,2),(1,3);
+LOCK TABLE t1 LOW_PRIORITY WRITE;
+Warnings:
+Warning	1287	'LOW_PRIORITY WRITE' is deprecated and will be removed in a future release. Please use WRITE instead
+SELECT id2,COUNT(DISTINCT id) FROM t1 GROUP BY id2;
+id2	COUNT(DISTINCT id)
+1	1
+2	1
+3	1
+UPDATE t1 SET id=-1 WHERE id=1;
+connection con1;
+SELECT id,id2 FROM t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+LOCK TABLE t1 READ;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
+LOCK TABLE t1 READ;
+UPDATE t1 SET id=1 WHERE id=1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+connection con1;
+SELECT COUNT(DISTINCT id) FROM t1;
+COUNT(DISTINCT id)
+1
+UPDATE t1 SET id=2 WHERE id=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+LOCK TABLE t1 WRITE;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+LOCK TABLE t1 READ;
+UNLOCK TABLES;
+connection default;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+UNLOCK TABLES;
+CREATE TABLE t2 (id INT, id2 INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+LOCK TABLE t1 WRITE, t2 WRITE;
+INSERT INTO t2 (id,id2) SELECT id,id2 FROM t1;
+UPDATE t1 SET id=1 WHERE id=-1;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (i1 INT, nr INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+CREATE TABLE t2 (nr INT, nm INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (nr,nm) VALUES (1,3);
+INSERT INTO t2 (nr,nm) VALUES (2,4);
+LOCK TABLES t1 WRITE, t2 READ;
+INSERT INTO t1 (i1,nr) SELECT 1, nr FROM t2 WHERE nm=3;
+INSERT INTO t1 (i1,nr) SELECT 2, nr FROM t2 WHERE nm=4;
+UNLOCK TABLES;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 (i1,nr) SELECT i1, nr FROM t1;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLES t1 WRITE, t1 AS t1_alias READ;
+INSERT INTO t1 (i1,nr) SELECT i1, nr FROM t1 AS t1_alias;
+DROP TABLE t1,t2;
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+UNLOCK TABLES;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=LevelDB;
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
+DROP TABLE t2, t3, t1;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=LevelDB;
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t1 AS t4 READ;
+ALTER TABLE t2 ADD COLUMN c2 INT;
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+LOCK TABLE t1 READ, t2 READ;
+FLUSH TABLE t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+FLUSH TABLES;
+ERROR HY000: Table 't2' was locked with a READ lock and can't be updated
+FLUSH TABLES t1, t2 WITH READ LOCK;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
+UNLOCK TABLES;
+FLUSH TABLES t1, t2 WITH READ LOCK;
+connection con1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
+UNLOCK TABLES;
+FLUSH TABLES WITH READ LOCK;
+connection con1;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection default;
+UNLOCK TABLES;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+FLUSH TABLES WITH READ LOCK;
+DROP TABLE t1, t2;
+ERROR HY000: Can't execute the query because you have a conflicting read lock
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+disconnect con1;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+LOCK TABLE t1 WRITE, t2 WRITE;
+SELECT a,b FROM t1;
+a	b
+UNLOCK TABLES;
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/lock.test b/mysql-test/suite/leveldb/lock.test
new file mode 100644
index 0000000..7932d42
--- /dev/null
+++ b/mysql-test/suite/leveldb/lock.test
@@ -0,0 +1,200 @@
+# Standard table locking:
+#   LOCK TABLE .. READ 
+#   LOCK TABLE .. [LOW_PRIORITY] WRITE 
+#   UNLOCK TABLES
+#
+# and global locking:
+# FLUSH TABLES [..] WITH READ LOCK
+# 
+############################################
+# TODO:   
+# A part of the test is currently disabled
+# because temporary tables are not supported
+############################################
+
+--enable_connect_log
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+connect (con1,localhost,root,,);
+SET lock_wait_timeout=1;
+
+connection default;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1 (id INT, id2 INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (id,id2) VALUES (1,1),(1,2),(1,3);
+
+# LOW_PRIORITY has no effect, but is still syntactically correct
+LOCK TABLE t1 LOW_PRIORITY WRITE;
+SELECT id2,COUNT(DISTINCT id) FROM t1 GROUP BY id2;
+
+UPDATE t1 SET id=-1 WHERE id=1;
+
+connection con1;
+# With WRITE lock held by connection 'default',
+# nobody else can access the table
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT id,id2 FROM t1;
+--error ER_LOCK_WAIT_TIMEOUT
+LOCK TABLE t1 READ;
+
+connection default;
+LOCK TABLE t1 READ;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+UPDATE t1 SET id=1 WHERE id=1;
+
+connection con1;
+# With READ lock held by connection 'default',
+# it should be possible to read from the table
+# or acquire another READ lock, 
+# but not update it or acquire WRITE lock
+SELECT COUNT(DISTINCT id) FROM t1;
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t1 SET id=2 WHERE id=2;
+--error ER_LOCK_WAIT_TIMEOUT
+LOCK TABLE t1 WRITE;
+LOCK TABLE t1 READ;
+UNLOCK TABLES;
+
+
+--connection default
+
+--error ER_TABLE_NOT_LOCKED
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+
+--disable_parsing
+
+CREATE TEMPORARY TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+DROP TABLE IF EXISTS t2;
+
+--enable_parsing
+
+UNLOCK TABLES;
+
+CREATE TABLE t2 (id INT, id2 INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+LOCK TABLE t1 WRITE, t2 WRITE;
+INSERT INTO t2 (id,id2) SELECT id,id2 FROM t1;
+UPDATE t1 SET id=1 WHERE id=-1;
+DROP TABLE t1,t2;
+
+#
+# INSERT ... SELECT with lock tables
+#
+
+CREATE TABLE t1 (i1 INT, nr INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+CREATE TABLE t2 (nr INT, nm INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (nr,nm) VALUES (1,3);
+INSERT INTO t2 (nr,nm) VALUES (2,4);
+
+LOCK TABLES t1 WRITE, t2 READ;
+INSERT INTO t1 (i1,nr) SELECT 1, nr FROM t2 WHERE nm=3;
+INSERT INTO t1 (i1,nr) SELECT 2, nr FROM t2 WHERE nm=4;
+UNLOCK TABLES;
+
+LOCK TABLES t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
+INSERT INTO t1 (i1,nr) SELECT i1, nr FROM t1;
+UNLOCK TABLES;
+LOCK TABLES t1 WRITE, t1 AS t1_alias READ;
+INSERT INTO t1 (i1,nr) SELECT i1, nr FROM t1 AS t1_alias;
+--error ER_TABLE_NOT_LOCKED
+DROP TABLE t1,t2;
+UNLOCK TABLES;
+DROP TABLE t1,t2;
+
+#
+# Check that a dropped table is removed from a lock
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=LevelDB;
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
+# This removes one table after the other from the lock.
+DROP TABLE t2, t3, t1;
+#
+# Check that a lock merge works
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=LevelDB;
+LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE, t1 AS t4 READ;
+
+ALTER TABLE t2 ADD COLUMN c2 INT;
+
+DROP TABLE t1, t2, t3;
+
+# FLUSH TABLES is not permitted when there is an active LOCK TABLES .. READ,
+# FLUSH TABLES .. WITH READ LOCK should be used instead
+# (and for other connections the table is locked)
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+
+LOCK TABLE t1 READ, t2 READ;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+FLUSH TABLE t1;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+FLUSH TABLES;
+--error ER_LOCK_OR_ACTIVE_TRANSACTION
+FLUSH TABLES t1, t2 WITH READ LOCK;
+UNLOCK TABLES;
+
+FLUSH TABLES t1, t2 WITH READ LOCK;
+
+--connection con1
+--error ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+
+--connection default
+UNLOCK TABLES;
+
+# Global lock
+
+FLUSH TABLES WITH READ LOCK;
+
+--connection con1
+--error ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+
+--connection default
+UNLOCK TABLES;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+FLUSH TABLES WITH READ LOCK;
+--error ER_CANT_UPDATE_WITH_READLOCK
+DROP TABLE t1, t2;
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+
+--disconnect con1
+
+#
+# Ensure that FLUSH TABLES doesn't substitute a base locked table
+# with a temporary one.
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+CREATE TABLE t2 (a INT, b CHAR(8), PRIMARY KEY(b)) ENGINE=LevelDB;
+
+LOCK TABLE t1 WRITE, t2 WRITE;
+
+--disable_parsing
+
+CREATE TEMPORARY TABLE t1 (a INT, b CHAR(8), PRIMARY KEY(a)) ENGINE=LevelDB;
+FLUSH TABLE t1;
+DROP TEMPORARY TABLE t1;
+
+--enable_parsing
+
+SELECT a,b FROM t1;
+UNLOCK TABLES;
+DROP TABLE t1, t2;
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/suite/leveldb/misc.result b/mysql-test/suite/leveldb/misc.result
new file mode 100644
index 0000000..812a7f2
--- /dev/null
+++ b/mysql-test/suite/leveldb/misc.result
@@ -0,0 +1,89 @@
+INSERT INTO mysql.event (
+db,
+name,
+body,
+definer,
+interval_value,
+interval_field,
+originator,
+character_set_client,
+collation_connection,
+db_collation,
+body_utf8)
+values (
+database(),
+"ev1",
+"select 1",
+user(),
+100,
+"SECOND_MICROSECOND",
+1,
+'utf8',
+'utf8_general_ci',
+'utf8_general_ci',
+'select 1');
+SHOW EVENTS;
+ERROR 42000: This version of MySQL doesn't yet support 'MICROSECOND'
+DROP EVENT ev1;
+SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
+FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
+TABLE_NAME	COLUMN_NAME	REFERENCED_TABLE_NAME	REFERENCED_COLUMN_NAME
+columns_priv	Column_name	NULL	NULL
+columns_priv	Db	NULL	NULL
+columns_priv	Host	NULL	NULL
+columns_priv	Table_name	NULL	NULL
+columns_priv	User	NULL	NULL
+db	Db	NULL	NULL
+db	Host	NULL	NULL
+db	User	NULL	NULL
+event	db	NULL	NULL
+event	name	NULL	NULL
+func	name	NULL	NULL
+help_category	help_category_id	NULL	NULL
+help_category	name	NULL	NULL
+help_keyword	help_keyword_id	NULL	NULL
+help_keyword	name	NULL	NULL
+help_relation	help_keyword_id	NULL	NULL
+help_relation	help_topic_id	NULL	NULL
+help_topic	help_topic_id	NULL	NULL
+help_topic	name	NULL	NULL
+innodb_index_stats	database_name	NULL	NULL
+innodb_index_stats	index_name	NULL	NULL
+innodb_index_stats	stat_name	NULL	NULL
+innodb_index_stats	table_name	NULL	NULL
+innodb_table_stats	database_name	NULL	NULL
+innodb_table_stats	table_name	NULL	NULL
+ndb_binlog_index	epoch	NULL	NULL
+ndb_binlog_index	orig_epoch	NULL	NULL
+ndb_binlog_index	orig_server_id	NULL	NULL
+plugin	name	NULL	NULL
+proc	db	NULL	NULL
+proc	name	NULL	NULL
+proc	type	NULL	NULL
+procs_priv	Db	NULL	NULL
+procs_priv	Host	NULL	NULL
+procs_priv	Routine_name	NULL	NULL
+procs_priv	Routine_type	NULL	NULL
+procs_priv	User	NULL	NULL
+proxies_priv	Host	NULL	NULL
+proxies_priv	Proxied_host	NULL	NULL
+proxies_priv	Proxied_user	NULL	NULL
+proxies_priv	User	NULL	NULL
+servers	Server_name	NULL	NULL
+slave_master_info	Host	NULL	NULL
+slave_master_info	Port	NULL	NULL
+slave_relay_log_info	Id	NULL	NULL
+slave_worker_info	Id	NULL	NULL
+tables_priv	Db	NULL	NULL
+tables_priv	Host	NULL	NULL
+tables_priv	Table_name	NULL	NULL
+tables_priv	User	NULL	NULL
+time_zone	Time_zone_id	NULL	NULL
+time_zone_leap_second	Transition_time	NULL	NULL
+time_zone_name	Name	NULL	NULL
+time_zone_transition	Time_zone_id	NULL	NULL
+time_zone_transition	Transition_time	NULL	NULL
+time_zone_transition_type	Time_zone_id	NULL	NULL
+time_zone_transition_type	Transition_type_id	NULL	NULL
+user	Host	NULL	NULL
+user	User	NULL	NULL
diff --git a/mysql-test/suite/leveldb/misc.test b/mysql-test/suite/leveldb/misc.test
new file mode 100644
index 0000000..177c29b
--- /dev/null
+++ b/mysql-test/suite/leveldb/misc.test
@@ -0,0 +1,43 @@
+#
+# Different statements not related to an engine,
+# but added to provide function coverage for handler.cc and handler.h.
+# The test can be disabled or removed later.
+#
+
+# hits get_error_message(int, String*) 
+
+INSERT INTO mysql.event (
+  db,
+  name,
+  body,
+  definer,
+  interval_value,
+  interval_field,
+  originator,
+  character_set_client,
+  collation_connection,
+  db_collation,
+  body_utf8)
+values (
+  database(),
+  "ev1",
+  "select 1",
+  user(),
+  100,
+  "SECOND_MICROSECOND",
+  1,
+  'utf8',
+  'utf8_general_ci',
+  'utf8_general_ci',
+  'select 1');
+
+--error ER_NOT_SUPPORTED_YET
+SHOW EVENTS;
+DROP EVENT ev1;
+
+# hits get_foreign_key_list(THD*, List<st_foreign_key_info>*)
+--sorted_result
+SELECT TABLE_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
+FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ORDER BY TABLE_NAME;
+
+
diff --git a/mysql-test/suite/leveldb/my.cnf b/mysql-test/suite/leveldb/my.cnf
new file mode 100644
index 0000000..086227e
--- /dev/null
+++ b/mysql-test/suite/leveldb/my.cnf
@@ -0,0 +1,7 @@
+!include include/default_my.cnf
+
+[server]
+sql-mode=NO_ENGINE_SUBSTITUTION
+explicit-defaults-for-timestamp=1
+leveldb_lock_wait_timeout=1
+
diff --git a/mysql-test/suite/leveldb/optimize_table.inc b/mysql-test/suite/leveldb/optimize_table.inc
new file mode 100644
index 0000000..991341e
--- /dev/null
+++ b/mysql-test/suite/leveldb/optimize_table.inc
@@ -0,0 +1,30 @@
+# 
+# OPTIMIZE TABLE statements
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+OPTIMIZE TABLE t1;
+INSERT INTO t2 (a,b) VALUES (4,'d');
+OPTIMIZE NO_WRITE_TO_BINLOG TABLE t2;
+INSERT INTO t2 (a,b) VALUES (5,'e');
+INSERT INTO t1 (a,b) VALUES (6,'f');
+OPTIMIZE LOCAL TABLE t1, t2;
+OPTIMIZE TABLE t1, t2;
+
+DROP TABLE t1, t2;
+
+# OPTIMIZE on a table with index
+
+CREATE TABLE t1 (a INT, b CHAR(8), KEY(a), PRIMARY KEY(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(100,'b'),(2,'c'),(3,'d');
+OPTIMIZE TABLE t1;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/optimize_table.result b/mysql-test/suite/leveldb/optimize_table.result
new file mode 100644
index 0000000..c274d7f
--- /dev/null
+++ b/mysql-test/suite/leveldb/optimize_table.result
@@ -0,0 +1,29 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	note	The storage engine for the table doesn't support optimize
+INSERT INTO t2 (a,b) VALUES (4,'d');
+OPTIMIZE NO_WRITE_TO_BINLOG TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	optimize	note	The storage engine for the table doesn't support optimize
+INSERT INTO t2 (a,b) VALUES (5,'e');
+INSERT INTO t1 (a,b) VALUES (6,'f');
+OPTIMIZE LOCAL TABLE t1, t2;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	note	The storage engine for the table doesn't support optimize
+test.t2	optimize	note	The storage engine for the table doesn't support optimize
+OPTIMIZE TABLE t1, t2;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	note	The storage engine for the table doesn't support optimize
+test.t2	optimize	note	The storage engine for the table doesn't support optimize
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT, b CHAR(8), KEY(a), PRIMARY KEY(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(100,'b'),(2,'c'),(3,'d');
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	note	The storage engine for the table doesn't support optimize
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/optimize_table.test b/mysql-test/suite/leveldb/optimize_table.test
new file mode 100644
index 0000000..aaef6d2
--- /dev/null
+++ b/mysql-test/suite/leveldb/optimize_table.test
@@ -0,0 +1,6 @@
+# 
+# OPTIMIZE TABLE statements
+#
+
+--source optimize_table.inc
+
diff --git a/mysql-test/suite/leveldb/repair_table.inc b/mysql-test/suite/leveldb/repair_table.inc
new file mode 100644
index 0000000..0cbc9ee
--- /dev/null
+++ b/mysql-test/suite/leveldb/repair_table.inc
@@ -0,0 +1,38 @@
+# 
+# REPAIR TABLE statements
+#
+# Note: the output is likely to be different for the engine under test,
+# in which case rdiff will be needed. Or, the output might say that
+# the storage engine does not support REPAIR.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT, b CHAR(8) PRIMARY KEY) ENGINE=LevelDB;
+
+REPAIR TABLE t1;
+
+INSERT INTO t1 (a,b) VALUES (3,'c');
+INSERT INTO t2 (a,b) VALUES (4,'d');
+REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2;
+INSERT INTO t2 (a,b) VALUES (5,'e'),(6,'f');
+REPAIR LOCAL TABLE t2;
+INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+INSERT INTO t2 (a,b) VALUES (9,'i');
+REPAIR LOCAL TABLE t2, t1 EXTENDED;
+INSERT INTO t1 (a,b) VALUES (10,'j');
+INSERT INTO t2 (a,b) VALUES (11,'k');
+REPAIR TABLE t1, t2 QUICK USE_FRM;
+INSERT INTO t1 (a,b) VALUES (12,'l');
+INSERT INTO t2 (a,b) VALUES (13,'m');
+REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2 QUICK EXTENDED USE_FRM;
+FLUSH TABLE t1;
+
+DROP TABLE t1, t2;
+
+
+
diff --git a/mysql-test/suite/leveldb/repair_table.result b/mysql-test/suite/leveldb/repair_table.result
new file mode 100644
index 0000000..4eac720
--- /dev/null
+++ b/mysql-test/suite/leveldb/repair_table.result
@@ -0,0 +1,37 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+CREATE TABLE t2 (a INT, b CHAR(8) PRIMARY KEY) ENGINE=LevelDB;
+REPAIR TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	note	The storage engine for the table doesn't support repair
+INSERT INTO t1 (a,b) VALUES (3,'c');
+INSERT INTO t2 (a,b) VALUES (4,'d');
+REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	note	The storage engine for the table doesn't support repair
+test.t2	repair	note	The storage engine for the table doesn't support repair
+INSERT INTO t2 (a,b) VALUES (5,'e'),(6,'f');
+REPAIR LOCAL TABLE t2;
+Table	Op	Msg_type	Msg_text
+test.t2	repair	note	The storage engine for the table doesn't support repair
+INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+INSERT INTO t2 (a,b) VALUES (9,'i');
+REPAIR LOCAL TABLE t2, t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t2	repair	note	The storage engine for the table doesn't support repair
+test.t1	repair	note	The storage engine for the table doesn't support repair
+INSERT INTO t1 (a,b) VALUES (10,'j');
+INSERT INTO t2 (a,b) VALUES (11,'k');
+REPAIR TABLE t1, t2 QUICK USE_FRM;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	note	The storage engine for the table doesn't support repair
+test.t2	repair	note	The storage engine for the table doesn't support repair
+INSERT INTO t1 (a,b) VALUES (12,'l');
+INSERT INTO t2 (a,b) VALUES (13,'m');
+REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2 QUICK EXTENDED USE_FRM;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	note	The storage engine for the table doesn't support repair
+test.t2	repair	note	The storage engine for the table doesn't support repair
+FLUSH TABLE t1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/repair_table.test b/mysql-test/suite/leveldb/repair_table.test
new file mode 100644
index 0000000..993331d
--- /dev/null
+++ b/mysql-test/suite/leveldb/repair_table.test
@@ -0,0 +1,6 @@
+# 
+# REPAIR TABLE statements
+#
+
+--source repair_table.inc
+
diff --git a/mysql-test/suite/leveldb/replace.result b/mysql-test/suite/leveldb/replace.result
new file mode 100644
index 0000000..38fa629
--- /dev/null
+++ b/mysql-test/suite/leveldb/replace.result
@@ -0,0 +1,32 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+REPLACE INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+SELECT a,b FROM t1;
+a	b
+1	a
+2	b
+3	c
+4	d
+5	e
+REPLACE t1 (a,b) VALUE (10,'foo'),(10,'foo');
+SELECT a,b FROM t1;
+a	b
+1	a
+10	foo
+10	foo
+2	b
+3	c
+4	d
+5	e
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY (b)) ENGINE=LevelDB;
+REPLACE INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c');
+INSERT INTO t1 (a,b) VALUES (4,'b');
+ERROR 23000: Duplicate entry 'b' for key 'PRIMARY'
+REPLACE INTO t1 (a,b) VALUES (4,'b');
+SELECT a,b FROM t1;
+a	b
+1	a
+3	c
+4	b
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/replace.test b/mysql-test/suite/leveldb/replace.test
new file mode 100644
index 0000000..5b98a53
--- /dev/null
+++ b/mysql-test/suite/leveldb/replace.test
@@ -0,0 +1,52 @@
+# 
+# Basic REPLACE statements
+#
+
+###########################################
+# TODO:
+# A part of the test is currently disabled
+# because unique indexes are not supported
+###########################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+# When there is no duplicate key, REPLACE should work as INSERT
+
+REPLACE INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
+--sorted_result
+SELECT a,b FROM t1;
+
+REPLACE t1 (a,b) VALUE (10,'foo'),(10,'foo');
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+--disable_parsing
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, UNIQUE INDEX (a)) ENGINE=LevelDB;
+REPLACE INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (2,'d');
+REPLACE INTO t1 (a,b) VALUES (2,'d');
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (a INT, b CHAR(8), PRIMARY KEY (b)) ENGINE=LevelDB;
+REPLACE INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c');
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b) VALUES (4,'b');
+REPLACE INTO t1 (a,b) VALUES (4,'b');
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/se-innodb.out b/mysql-test/suite/leveldb/se-innodb.out
new file mode 100644
index 0000000..406e506
--- /dev/null
+++ b/mysql-test/suite/leveldb/se-innodb.out
@@ -0,0 +1 @@
+Can't open perl script "./mtr": No such file or directory
diff --git a/mysql-test/suite/leveldb/select.result b/mysql-test/suite/leveldb/select.result
new file mode 100644
index 0000000..f7e1c42
--- /dev/null
+++ b/mysql-test/suite/leveldb/select.result
@@ -0,0 +1,373 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'foobar'),(1,'z'),(200,'bar');
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (a,b) SELECT a, b FROM t1;
+INSERT INTO t1 (a,b) SELECT a, b FROM t2;
+SELECT * FROM t1;
+a	b	pk
+1	z	2
+1	z	5
+100	foobar	1
+100	foobar	4
+200	bar	3
+200	bar	6
+SELECT DISTINCT a FROM t1;
+a
+1
+100
+200
+SELECT ALL b, a FROM t1;
+b	a
+bar	200
+bar	200
+foobar	100
+foobar	100
+z	1
+z	1
+SELECT STRAIGHT_JOIN SQL_CACHE t1.* FROM t2, t1 WHERE t1.a <> t2.a;
+a	b	pk
+1	z	2
+1	z	2
+1	z	5
+1	z	5
+100	foobar	1
+100	foobar	1
+100	foobar	4
+100	foobar	4
+200	bar	3
+200	bar	3
+200	bar	6
+200	bar	6
+SELECT SQL_SMALL_RESULT SQL_NO_CACHE t1.a FROM t1, t2;
+a
+1
+1
+1
+1
+1
+1
+100
+100
+100
+100
+100
+100
+200
+200
+200
+200
+200
+200
+SELECT SQL_BIG_RESULT SQL_CALC_FOUND_ROWS DISTINCT(t2.a) 
+FROM t1 t1_1, t2, t1 t1_2;
+a
+1
+100
+200
+SELECT FOUND_ROWS();
+FOUND_ROWS()
+3
+SET GLOBAL query_cache_size = 1024*1024;
+SELECT SQL_CACHE * FROM t1, t2;
+a	b	pk	a	b	pk
+1	z	2	1	z	2
+1	z	2	100	foobar	1
+1	z	2	200	bar	3
+1	z	5	1	z	2
+1	z	5	100	foobar	1
+1	z	5	200	bar	3
+100	foobar	1	1	z	2
+100	foobar	1	100	foobar	1
+100	foobar	1	200	bar	3
+100	foobar	4	1	z	2
+100	foobar	4	100	foobar	1
+100	foobar	4	200	bar	3
+200	bar	3	1	z	2
+200	bar	3	100	foobar	1
+200	bar	3	200	bar	3
+200	bar	6	1	z	2
+200	bar	6	100	foobar	1
+200	bar	6	200	bar	3
+SET GLOBAL query_cache_size = 1048576;
+SELECT a+10 AS field1, CONCAT(b,':',b) AS field2 FROM t1 
+WHERE b > 'b' AND a IS NOT NULL 
+GROUP BY 2 DESC, field1 ASC
+HAVING field1 < 1000
+ORDER BY field2, 1 DESC, field1*2
+LIMIT 5 OFFSET 1;
+field1	field2
+11	z:z
+110	foobar:foobar
+SELECT SUM(a), MAX(a), b FROM t1 GROUP BY b WITH ROLLUP;
+SUM(a)	MAX(a)	b
+2	1	z
+200	100	foobar
+400	200	bar
+602	200	NULL
+SELECT * FROM t2 WHERE a>0 PROCEDURE ANALYSE();
+Field_name	Min_value	Max_value	Min_length	Max_length	Empties_or_zeros	Nulls	Avg_value_or_avg_length	Std	Optimal_fieldtype
+test.t2.a	1	200	1	3	0	0	100.3333	81.2418	ENUM('1','100','200') NOT NULL
+test.t2.b	bar	z	1	6	0	0	3.3333	NULL	ENUM('bar','foobar','z') NOT NULL
+test.t2.pk	1	3	1	1	0	0	2.0000	0.8165	ENUM('1','2','3') NOT NULL
+SELECT t1.a, t2.b FROM t2, t1 WHERE t1.a = t2.a ORDER BY t2.b, t1.a 
+INTO OUTFILE '<DATADIR>/select.out' 
+CHARACTER SET utf8
+FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '''';
+200,'bar'
+200,'bar'
+100,'foobar'
+100,'foobar'
+1,'z'
+1,'z'
+SELECT t1.a, t2.b FROM t2, t1 WHERE t1.a = t2.a ORDER BY t2.b, t1.a
+INTO DUMPFILE '<DATADIR>/select.dump';
+ERROR 42000: Result consisted of more than one row
+SELECT t1.*, t2.* FROM t1, t2 ORDER BY t2.b, t1.a, t2.a, t1.b, t1.pk, t2.pk LIMIT 1
+INTO DUMPFILE '<DATADIR>/select.dump';
+1z2200bar3
+SELECT MIN(a), MAX(a) FROM t1 INTO @min, @max;
+SELECT @min, @max;
+ at min	@max
+1	200
+SELECT t1_1.*, t2.* FROM t2, t1 AS t1_1, t1 AS t1_2 
+WHERE t1_1.a = t1_2.a AND t2.a = t1_1.a;
+a	b	pk	a	b	pk
+1	z	2	1	z	2
+1	z	2	1	z	2
+1	z	5	1	z	2
+1	z	5	1	z	2
+100	foobar	1	100	foobar	1
+100	foobar	1	100	foobar	1
+100	foobar	4	100	foobar	1
+100	foobar	4	100	foobar	1
+200	bar	3	200	bar	3
+200	bar	3	200	bar	3
+200	bar	6	200	bar	3
+200	bar	6	200	bar	3
+SELECT alias1.* FROM ( SELECT a,b FROM t1 ) alias1, t2 WHERE t2.a IN (100,200);
+a	b
+1	z
+1	z
+1	z
+1	z
+100	foobar
+100	foobar
+100	foobar
+100	foobar
+200	bar
+200	bar
+200	bar
+200	bar
+SELECT t1.a FROM { OJ t1 LEFT OUTER JOIN t2 ON t1.a = t2.a+10 };
+a
+1
+1
+100
+100
+200
+200
+SELECT t1.* FROM t2 INNER JOIN t1;
+a	b	pk
+1	z	2
+1	z	2
+1	z	2
+1	z	5
+1	z	5
+1	z	5
+100	foobar	1
+100	foobar	1
+100	foobar	1
+100	foobar	4
+100	foobar	4
+100	foobar	4
+200	bar	3
+200	bar	3
+200	bar	3
+200	bar	6
+200	bar	6
+200	bar	6
+SELECT t1_2.* FROM t1 t1_1 CROSS JOIN t1 t1_2 ON t1_1.b = t1_2.b;
+a	b	pk
+1	z	2
+1	z	2
+1	z	5
+1	z	5
+100	foobar	1
+100	foobar	1
+100	foobar	4
+100	foobar	4
+200	bar	3
+200	bar	3
+200	bar	6
+200	bar	6
+SELECT t1.a, t2.b FROM t2 STRAIGHT_JOIN t1 WHERE t1.b > t2.b;
+a	b
+1	bar
+1	bar
+1	foobar
+1	foobar
+100	bar
+100	bar
+SELECT t1.a, t2.b FROM t2 STRAIGHT_JOIN t1 ON t1.b > t2.b ORDER BY t1.a, t2.b;
+a	b
+1	bar
+1	bar
+1	foobar
+1	foobar
+100	bar
+100	bar
+SELECT t2.* FROM t1 LEFT JOIN t2 USING (a) ORDER BY t2.a, t2.b LIMIT 1;
+a	b	pk
+1	z	2
+SELECT t2.* FROM t2 LEFT OUTER JOIN t1 ON t1.a = t2.a WHERE t1.a IS NOT NULL;
+a	b	pk
+1	z	2
+1	z	2
+100	foobar	1
+100	foobar	1
+200	bar	3
+200	bar	3
+SELECT SUM(t2.a) FROM t1 RIGHT JOIN t2 ON t2.b = t1.b;
+SUM(t2.a)
+602
+SELECT MIN(t2.a) FROM t1 RIGHT OUTER JOIN t2 USING (b,a);
+MIN(t2.a)
+1
+SELECT alias.b FROM t1 NATURAL JOIN ( SELECT a,b FROM t1 ) alias WHERE b > '';
+b
+bar
+bar
+bar
+bar
+foobar
+foobar
+foobar
+foobar
+z
+z
+z
+z
+SELECT t2.b FROM ( SELECT a,b FROM t1 ) alias NATURAL LEFT JOIN t2 WHERE b IS NOT NULL;
+b
+bar
+bar
+foobar
+foobar
+z
+z
+SELECT t1.*, t2.* FROM t1 NATURAL LEFT OUTER JOIN t2;
+a	b	pk	a	b	pk
+1	z	2	1	z	2
+1	z	5	NULL	NULL	NULL
+100	foobar	1	100	foobar	1
+100	foobar	4	NULL	NULL	NULL
+200	bar	3	200	bar	3
+200	bar	6	NULL	NULL	NULL
+SELECT t2_2.* FROM t2 t2_1 NATURAL RIGHT JOIN t2 t2_2 WHERE t2_1.a IN ( SELECT a FROM t1 );
+a	b	pk
+1	z	2
+100	foobar	1
+200	bar	3
+SELECT t1_2.b FROM t1 t1_1 NATURAL RIGHT OUTER JOIN t1 t1_2 INNER JOIN t2;
+b
+bar
+bar
+bar
+bar
+bar
+bar
+foobar
+foobar
+foobar
+foobar
+foobar
+foobar
+z
+z
+z
+z
+z
+z
+SELECT ( SELECT MIN(a) FROM ( SELECT a,b FROM t1 ) alias1 ) AS min_a FROM t2;
+min_a
+1
+1
+1
+SELECT a,b FROM t2 WHERE a = ( SELECT MIN(a) FROM t1 );
+a	b
+1	z
+SELECT a,b FROM t2 WHERE b LIKE ( SELECT b FROM t1 ORDER BY b LIMIT 1 );
+a	b
+200	bar
+SELECT t2.* FROM t1 t1_outer, t2 WHERE ( t1_outer.a, t2.b ) IN ( SELECT a, b FROM t2 WHERE a = t1_outer.a );
+a	b	pk
+1	z	2
+1	z	2
+100	foobar	1
+100	foobar	1
+200	bar	3
+200	bar	3
+SELECT a,b FROM t2 WHERE b = ANY ( SELECT b FROM t1 WHERE a > 1 );
+a	b
+100	foobar
+200	bar
+SELECT a,b FROM t2 WHERE b > ALL ( SELECT b FROM t1 WHERE b < 'foo' );
+a	b
+1	z
+100	foobar
+SELECT a,b FROM t1 WHERE ROW(a, b) = ( SELECT a, b FROM t2 ORDER BY a, b LIMIT 1 );
+a	b
+1	z
+1	z
+SELECT a,b FROM t1 WHERE EXISTS ( SELECT a,b FROM t2 WHERE t2.b > t1.b );
+a	b
+100	foobar
+100	foobar
+200	bar
+200	bar
+SELECT t1.* FROM t1, t2 ORDER BY ( SELECT b FROM t1 WHERE a IS NULL ORDER BY b LIMIT 1 ) DESC;
+a	b	pk
+1	z	2
+1	z	2
+1	z	2
+1	z	5
+1	z	5
+1	z	5
+100	foobar	1
+100	foobar	1
+100	foobar	1
+100	foobar	4
+100	foobar	4
+100	foobar	4
+200	bar	3
+200	bar	3
+200	bar	3
+200	bar	6
+200	bar	6
+200	bar	6
+SELECT a, b FROM t1 HAVING a IN ( SELECT a FROM t2 WHERE b = t1.b );
+a	b
+1	z
+1	z
+100	foobar
+100	foobar
+200	bar
+200	bar
+SELECT a,b FROM t1 UNION SELECT a,b FROM t2 UNION DISTINCT SELECT a,b FROM t1;
+a	b
+1	z
+100	foobar
+200	bar
+SELECT a,b FROM t1 UNION SELECT a,b FROM t2 UNION ALL SELECT a,b FROM t1;
+a	b
+1	z
+1	z
+1	z
+100	foobar
+100	foobar
+100	foobar
+200	bar
+200	bar
+200	bar
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/select.test b/mysql-test/suite/leveldb/select.test
new file mode 100644
index 0000000..254edfb
--- /dev/null
+++ b/mysql-test/suite/leveldb/select.test
@@ -0,0 +1,200 @@
+# 
+# Basic SELECT statements
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'foobar'),(1,'z'),(200,'bar');
+
+CREATE TABLE t2 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (a,b) SELECT a, b FROM t1;
+INSERT INTO t1 (a,b) SELECT a, b FROM t2;
+
+--sorted_result
+SELECT * FROM t1;
+
+# Modifiers
+
+--sorted_result
+SELECT DISTINCT a FROM t1;
+
+--sorted_result
+SELECT ALL b, a FROM t1;
+
+# Optimizer and cache directives should not have any visible effect here,
+# but we will add them for completness
+
+--sorted_result
+SELECT STRAIGHT_JOIN SQL_CACHE t1.* FROM t2, t1 WHERE t1.a <> t2.a;
+
+--sorted_result
+SELECT SQL_SMALL_RESULT SQL_NO_CACHE t1.a FROM t1, t2;
+
+--sorted_result
+SELECT SQL_BIG_RESULT SQL_CALC_FOUND_ROWS DISTINCT(t2.a) 
+  FROM t1 t1_1, t2, t1 t1_2;
+SELECT FOUND_ROWS();
+
+let $query_cache = `SELECT @@query_cache_size`;
+SET GLOBAL query_cache_size = 1024*1024;
+--sorted_result
+SELECT SQL_CACHE * FROM t1, t2;
+eval SET GLOBAL query_cache_size = $query_cache;
+
+# Combination of main clauses
+
+--sorted_result
+SELECT a+10 AS field1, CONCAT(b,':',b) AS field2 FROM t1 
+WHERE b > 'b' AND a IS NOT NULL 
+GROUP BY 2 DESC, field1 ASC
+HAVING field1 < 1000
+ORDER BY field2, 1 DESC, field1*2
+LIMIT 5 OFFSET 1;
+
+# ROLLUP
+--sorted_result
+SELECT SUM(a), MAX(a), b FROM t1 GROUP BY b WITH ROLLUP;
+
+# Procedure
+
+--sorted_result
+SELECT * FROM t2 WHERE a>0 PROCEDURE ANALYSE();
+
+# SELECT INTO
+let $datadir = `SELECT @@datadir`;
+
+--replace_result $datadir <DATADIR>
+eval
+SELECT t1.a, t2.b FROM t2, t1 WHERE t1.a = t2.a ORDER BY t2.b, t1.a 
+  INTO OUTFILE '$datadir/select.out' 
+  CHARACTER SET utf8
+  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '''';
+--cat_file $datadir/select.out
+--remove_file $datadir/select.out
+
+--replace_result $datadir <DATADIR>
+--error ER_TOO_MANY_ROWS
+eval
+SELECT t1.a, t2.b FROM t2, t1 WHERE t1.a = t2.a ORDER BY t2.b, t1.a
+  INTO DUMPFILE '$datadir/select.dump';
+--remove_file $datadir/select.dump
+--replace_result $datadir <DATADIR>
+eval
+SELECT t1.*, t2.* FROM t1, t2 ORDER BY t2.b, t1.a, t2.a, t1.b, t1.pk, t2.pk LIMIT 1
+  INTO DUMPFILE '$datadir/select.dump';
+
+--cat_file $datadir/select.dump
+--echo
+--remove_file $datadir/select.dump
+
+SELECT MIN(a), MAX(a) FROM t1 INTO @min, @max;
+SELECT @min, @max;
+
+# Joins
+
+--sorted_result
+SELECT t1_1.*, t2.* FROM t2, t1 AS t1_1, t1 AS t1_2 
+  WHERE t1_1.a = t1_2.a AND t2.a = t1_1.a;
+
+--sorted_result
+SELECT alias1.* FROM ( SELECT a,b FROM t1 ) alias1, t2 WHERE t2.a IN (100,200);
+
+--sorted_result
+SELECT t1.a FROM { OJ t1 LEFT OUTER JOIN t2 ON t1.a = t2.a+10 };
+
+--sorted_result
+SELECT t1.* FROM t2 INNER JOIN t1;
+
+--sorted_result 
+SELECT t1_2.* FROM t1 t1_1 CROSS JOIN t1 t1_2 ON t1_1.b = t1_2.b;
+
+--sorted_result
+SELECT t1.a, t2.b FROM t2 STRAIGHT_JOIN t1 WHERE t1.b > t2.b;
+
+SELECT t1.a, t2.b FROM t2 STRAIGHT_JOIN t1 ON t1.b > t2.b ORDER BY t1.a, t2.b;
+
+SELECT t2.* FROM t1 LEFT JOIN t2 USING (a) ORDER BY t2.a, t2.b LIMIT 1;
+
+--sorted_result
+SELECT t2.* FROM t2 LEFT OUTER JOIN t1 ON t1.a = t2.a WHERE t1.a IS NOT NULL;
+
+SELECT SUM(t2.a) FROM t1 RIGHT JOIN t2 ON t2.b = t1.b;
+
+SELECT MIN(t2.a) FROM t1 RIGHT OUTER JOIN t2 USING (b,a);
+
+--sorted_result
+SELECT alias.b FROM t1 NATURAL JOIN ( SELECT a,b FROM t1 ) alias WHERE b > '';
+
+--sorted_result
+SELECT t2.b FROM ( SELECT a,b FROM t1 ) alias NATURAL LEFT JOIN t2 WHERE b IS NOT NULL;
+
+--sorted_result
+SELECT t1.*, t2.* FROM t1 NATURAL LEFT OUTER JOIN t2;
+
+--sorted_result
+SELECT t2_2.* FROM t2 t2_1 NATURAL RIGHT JOIN t2 t2_2 WHERE t2_1.a IN ( SELECT a FROM t1 );
+
+--sorted_result
+SELECT t1_2.b FROM t1 t1_1 NATURAL RIGHT OUTER JOIN t1 t1_2 INNER JOIN t2;
+
+# Subquery as scalar operand, subquery in the FROM clause
+
+--sorted_result
+SELECT ( SELECT MIN(a) FROM ( SELECT a,b FROM t1 ) alias1 ) AS min_a FROM t2;
+
+# Comparison using subqueries
+
+--sorted_result
+SELECT a,b FROM t2 WHERE a = ( SELECT MIN(a) FROM t1 );
+
+--sorted_result
+SELECT a,b FROM t2 WHERE b LIKE ( SELECT b FROM t1 ORDER BY b LIMIT 1 );
+
+# Subquery with IN, correlated subquery
+
+--sorted_result
+SELECT t2.* FROM t1 t1_outer, t2 WHERE ( t1_outer.a, t2.b ) IN ( SELECT a, b FROM t2 WHERE a = t1_outer.a );
+
+# Subquery with ANY, ALL
+
+--sorted_result
+SELECT a,b FROM t2 WHERE b = ANY ( SELECT b FROM t1 WHERE a > 1 );
+
+--sorted_result
+SELECT a,b FROM t2 WHERE b > ALL ( SELECT b FROM t1 WHERE b < 'foo' );
+
+# Row subqueries
+
+--sorted_result
+SELECT a,b FROM t1 WHERE ROW(a, b) = ( SELECT a, b FROM t2 ORDER BY a, b LIMIT 1 );
+
+# Subquery with EXISTS
+
+--sorted_result
+SELECT a,b FROM t1 WHERE EXISTS ( SELECT a,b FROM t2 WHERE t2.b > t1.b );
+
+# Subquery in ORDER BY
+
+--sorted_result
+SELECT t1.* FROM t1, t2 ORDER BY ( SELECT b FROM t1 WHERE a IS NULL ORDER BY b LIMIT 1 ) DESC;
+
+# Subquery in HAVING
+
+--sorted_result
+SELECT a, b FROM t1 HAVING a IN ( SELECT a FROM t2 WHERE b = t1.b );
+
+# Union
+
+--sorted_result
+SELECT a,b FROM t1 UNION SELECT a,b FROM t2 UNION DISTINCT SELECT a,b FROM t1;
+
+--sorted_result
+SELECT a,b FROM t1 UNION SELECT a,b FROM t2 UNION ALL SELECT a,b FROM t1;
+
+
+# Cleanup
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/select_for_update.result b/mysql-test/suite/leveldb/select_for_update.result
new file mode 100644
index 0000000..f595448
--- /dev/null
+++ b/mysql-test/suite/leveldb/select_for_update.result
@@ -0,0 +1,35 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'a');
+connect  con1,localhost,root,,;
+BEGIN;
+SELECT a,b FROM t1 WHERE b='a' FOR UPDATE;
+a	b
+1	a
+3	a
+connection default;
+SET lock_wait_timeout = 1;
+SELECT a,b FROM t1 WHERE b='a';
+a	b
+1	a
+3	a
+SELECT a,b FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+UPDATE t1 SET b='c' WHERE b='a';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection con1;
+COMMIT;
+SELECT a,b FROM t1;
+a	b
+1	a
+2	b
+3	a
+disconnect con1;
+connection default;
+UPDATE t1 SET b='c' WHERE b='a';
+SELECT a,b FROM t1;
+a	b
+1	c
+2	b
+3	c
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/select_for_update.test b/mysql-test/suite/leveldb/select_for_update.test
new file mode 100644
index 0000000..69804f8
--- /dev/null
+++ b/mysql-test/suite/leveldb/select_for_update.test
@@ -0,0 +1,53 @@
+#
+# SELECT .. FOR UPDATE
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--enable_connect_log
+
+--source include/count_sessions.inc
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'a');
+
+--connect (con1,localhost,root,,)
+BEGIN;
+--sorted_result
+SELECT a,b FROM t1 WHERE b='a' FOR UPDATE;
+
+--connection default
+SET lock_wait_timeout = 1;
+
+# Should still be able to select 
+
+--sorted_result
+SELECT a,b FROM t1 WHERE b='a';
+
+# ... but not with LOCK IN SHARE MODE
+
+--sorted_result
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT a,b FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t1 SET b='c' WHERE b='a';
+
+--connection con1
+COMMIT;
+--sorted_result
+SELECT a,b FROM t1;
+
+--disconnect con1
+--connection default
+# Now it can be updated all right
+UPDATE t1 SET b='c' WHERE b='a';  
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/suite/leveldb/select_lock_in_share_mode.result b/mysql-test/suite/leveldb/select_lock_in_share_mode.result
new file mode 100644
index 0000000..3d668d7
--- /dev/null
+++ b/mysql-test/suite/leveldb/select_lock_in_share_mode.result
@@ -0,0 +1,37 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'a');
+connect  con1,localhost,root,,;
+BEGIN;
+SELECT a,b FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+a	b
+1	a
+3	a
+connection default;
+SET lock_wait_timeout = 1;
+SELECT a,b FROM t1 WHERE b='a';
+a	b
+1	a
+3	a
+SELECT a,b FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+a	b
+1	a
+3	a
+UPDATE t1 SET b='c' WHERE b='a';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection con1;
+COMMIT;
+SELECT a,b FROM t1;
+a	b
+1	a
+2	b
+3	a
+disconnect con1;
+connection default;
+UPDATE t1 SET b='c' WHERE b='a';
+SELECT a,b FROM t1;
+a	b
+1	c
+2	b
+3	c
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/select_lock_in_share_mode.test b/mysql-test/suite/leveldb/select_lock_in_share_mode.test
new file mode 100644
index 0000000..9ce31d1
--- /dev/null
+++ b/mysql-test/suite/leveldb/select_lock_in_share_mode.test
@@ -0,0 +1,52 @@
+#
+# SELECT .. LOCK IN SHARE MODE 
+#
+# If the engine has its own lock timeouts, 
+# it makes sense to set them to minimum to decrease
+# the duration of the test.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--enable_connect_log
+
+--source include/count_sessions.inc
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'a');
+
+--connect (con1,localhost,root,,)
+BEGIN;
+--sorted_result
+SELECT a,b FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+
+--connection default
+SET lock_wait_timeout = 1;
+
+# Should still be able to select 
+
+--sorted_result
+SELECT a,b FROM t1 WHERE b='a';
+--sorted_result
+SELECT a,b FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t1 SET b='c' WHERE b='a';
+
+--connection con1
+COMMIT;
+--sorted_result
+SELECT a,b FROM t1;
+
+--disconnect con1
+--connection default
+# Now it can be updated all right
+UPDATE t1 SET b='c' WHERE b='a';  
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/suite/leveldb/show_engine.result b/mysql-test/suite/leveldb/show_engine.result
new file mode 100644
index 0000000..cae6fe3
--- /dev/null
+++ b/mysql-test/suite/leveldb/show_engine.result
@@ -0,0 +1,5 @@
+SHOW ENGINE LevelDB STATUS;
+Type	Name	Status
+SHOW ENGINE LevelDB MUTEX;
+Type	Name	Status
+SHOW ENGINE ALL MUTEX;
diff --git a/mysql-test/suite/leveldb/show_engine.test b/mysql-test/suite/leveldb/show_engine.test
new file mode 100644
index 0000000..8260c3d
--- /dev/null
+++ b/mysql-test/suite/leveldb/show_engine.test
@@ -0,0 +1,13 @@
+#
+# SHOW ENGINE STATUS command
+# Checking that the command doesn't produce an error.
+# If it starts producing an actual result, the result file
+# will need to be updated, and possibly masked.
+
+SHOW ENGINE LevelDB STATUS;
+SHOW ENGINE LevelDB MUTEX;
+# For SHOW ALL MUTEX even the number of lines is volatile, so the result logging is disabled
+--disable_result_log
+SHOW ENGINE ALL MUTEX;
+--enable_result_log
+
diff --git a/mysql-test/suite/leveldb/show_table_status.result b/mysql-test/suite/leveldb/show_table_status.result
new file mode 100644
index 0000000..47730d3
--- /dev/null
+++ b/mysql-test/suite/leveldb/show_table_status.result
@@ -0,0 +1,62 @@
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1 (a INT, b CHAR(8) PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'a'),(2,'foo');
+CREATE TABLE t2 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t2 (a,b) VALUES (1,'bar');
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=LevelDB CHARACTER SET utf8;
+SHOW TABLE STATUS WHERE name IN ( 't1', 't2', 't3' );
+Name	t1
+Engine	LEVELDB
+Version	10
+Row_format	Fixed
+Rows	1000
+Avg_row_length	0
+Data_length	0
+Max_data_length	0
+Index_length	0
+Data_free	0
+Auto_increment	NULL
+Create_time	NULL
+Update_time	NULL
+Check_time	NULL
+Collation	latin1_swedish_ci
+Checksum	NULL
+Create_options	
+Comment	
+Name	t2
+Engine	LEVELDB
+Version	10
+Row_format	Fixed
+Rows	1000
+Avg_row_length	0
+Data_length	0
+Max_data_length	0
+Index_length	0
+Data_free	0
+Auto_increment	NULL
+Create_time	NULL
+Update_time	NULL
+Check_time	NULL
+Collation	latin1_swedish_ci
+Checksum	NULL
+Create_options	
+Comment	
+Name	t3
+Engine	LEVELDB
+Version	10
+Row_format	Fixed
+Rows	1000
+Avg_row_length	0
+Data_length	0
+Max_data_length	0
+Index_length	0
+Data_free	0
+Auto_increment	NULL
+Create_time	NULL
+Update_time	NULL
+Check_time	NULL
+Collation	utf8_general_ci
+Checksum	NULL
+Create_options	
+Comment	
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/leveldb/show_table_status.test b/mysql-test/suite/leveldb/show_table_status.test
new file mode 100644
index 0000000..1554725
--- /dev/null
+++ b/mysql-test/suite/leveldb/show_table_status.test
@@ -0,0 +1,26 @@
+# 
+# SHOW TABLE STATUS statement
+#
+
+###################################
+# TODO:
+# The result file is likely to change 
+# if MDEV-4197 is fixed
+###################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8) PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (100,'a'),(2,'foo');
+
+CREATE TABLE t2 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t2 (a,b) VALUES (1,'bar');
+
+CREATE TABLE t3 (a INT, b CHAR(8), pk INT PRIMARY KEY) ENGINE=LevelDB CHARACTER SET utf8;
+
+#--replace_column 2 <STORAGE_ENGINE> 4 ### 6 ### 7 ### 8 ### 9 ### 10 ### 12 ### 13 ### 
+--query_vertical SHOW TABLE STATUS WHERE name IN ( 't1', 't2', 't3' )
+DROP TABLE t1, t2, t3;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_ai.result b/mysql-test/suite/leveldb/tbl_opt_ai.result
new file mode 100644
index 0000000..00ffb1e
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_ai.result
@@ -0,0 +1,38 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB AUTO_INCREMENT=10;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1;
+a
+10
+ALTER TABLE t1 AUTO_INCREMENT=100;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB AUTO_INCREMENT=100 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1 ORDER BY a;
+a
+10
+100
+ALTER TABLE t1 AUTO_INCREMENT=50;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL AUTO_INCREMENT,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB AUTO_INCREMENT=50 DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1 ORDER BY a;
+a
+10
+50
+100
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_ai.test b/mysql-test/suite/leveldb/tbl_opt_ai.test
new file mode 100644
index 0000000..e7189ad
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_ai.test
@@ -0,0 +1,27 @@
+# 
+# Check whether AUTO_INCREMENT option 
+# is supported in CREATE and ALTER TABLE
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB AUTO_INCREMENT=10;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1;
+
+ALTER TABLE t1 AUTO_INCREMENT=100;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1 ORDER BY a;
+
+ALTER TABLE t1 AUTO_INCREMENT=50;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (NULL);
+SELECT * FROM t1 ORDER BY a;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_avg_row_length.result b/mysql-test/suite/leveldb/tbl_opt_avg_row_length.result
new file mode 100644
index 0000000..b6f7424
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_avg_row_length.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB AVG_ROW_LENGTH=300;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=300
+ALTER TABLE t1 AVG_ROW_LENGTH=30000000;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=30000000
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_avg_row_length.test b/mysql-test/suite/leveldb/tbl_opt_avg_row_length.test
new file mode 100644
index 0000000..52ba365
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_avg_row_length.test
@@ -0,0 +1,21 @@
+# 
+# Check whether AVG_ROW_LENGTH option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB AVG_ROW_LENGTH=300;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 AVG_ROW_LENGTH=30000000;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_checksum.result b/mysql-test/suite/leveldb/tbl_opt_checksum.result
new file mode 100644
index 0000000..980f43a
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_checksum.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 CHECKSUM=1
+ALTER TABLE t1 CHECKSUM=0;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_checksum.test b/mysql-test/suite/leveldb/tbl_opt_checksum.test
new file mode 100644
index 0000000..64ba8da
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_checksum.test
@@ -0,0 +1,17 @@
+# 
+# Check whether CHECKSUM option is supported
+# in CREATE and ALTER TABLE.
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CHECKSUM=1;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 CHECKSUM=0;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_connection.result b/mysql-test/suite/leveldb/tbl_opt_connection.result
new file mode 100644
index 0000000..c1883c5
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_connection.result
@@ -0,0 +1,26 @@
+DROP TABLE IF EXISTS t1;
+CREATE DATABASE test_remote;
+CREATE SERVER test_connection FOREIGN DATA WRAPPER mysql
+OPTIONS (USER 'root', HOST 'localhost', DATABASE 'test_remote');
+CREATE SERVER test_connection2 FOREIGN DATA WRAPPER mysql
+OPTIONS (USER 'root', HOST 'localhost', DATABASE 'test_remote');
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CONNECTION='test_connection';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 CONNECTION='test_connection'
+ALTER TABLE t1 CONNECTION='test_connection2';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 CONNECTION='test_connection2'
+DROP TABLE t1;
+DROP SERVER test_connection;
+DROP SERVER test_connection2;
+DROP DATABASE test_remote;
diff --git a/mysql-test/suite/leveldb/tbl_opt_connection.test b/mysql-test/suite/leveldb/tbl_opt_connection.test
new file mode 100644
index 0000000..56c6120
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_connection.test
@@ -0,0 +1,30 @@
+# 
+# Check whether CONNECTION option is supported
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE DATABASE test_remote;
+CREATE SERVER test_connection FOREIGN DATA WRAPPER mysql
+OPTIONS (USER 'root', HOST 'localhost', DATABASE 'test_remote');
+CREATE SERVER test_connection2 FOREIGN DATA WRAPPER mysql
+OPTIONS (USER 'root', HOST 'localhost', DATABASE 'test_remote');
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB CONNECTION='test_connection';
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 CONNECTION='test_connection2';
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+DROP SERVER test_connection;
+DROP SERVER test_connection2;
+DROP DATABASE test_remote;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_data_index_dir.result b/mysql-test/suite/leveldb/tbl_opt_data_index_dir.result
new file mode 100644
index 0000000..1181f30
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_data_index_dir.result
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB DATA DIRECTORY = '<DATA_DIR>' INDEX DIRECTORY = '<INDEX_DIR>';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 INDEX DIRECTORY = '<DATA_DIR>';
+Warnings:
+Warning	1618	<INDEX DIRECTORY> option ignored
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_data_index_dir.test b/mysql-test/suite/leveldb/tbl_opt_data_index_dir.test
new file mode 100644
index 0000000..4a7b8dc
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_data_index_dir.test
@@ -0,0 +1,35 @@
+# 
+# Check whether DATA DIRECTORY and INDEX DIRECTORY
+# are supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the options
+#       have any real effect on the table, only 
+#       that they are accepted
+#       (and apparently ignored)
+# 
+
+--let $data_dir = $MYSQLTEST_VARDIR/storage_engine_data_dir/
+--let $index_dir = $MYSQLTEST_VARDIR/storage_engine_index_dir/
+--mkdir $data_dir
+--mkdir $index_dir
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--replace_result $data_dir <DATA_DIR> $index_dir <INDEX_DIR>
+eval CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB DATA DIRECTORY = '$data_dir' INDEX DIRECTORY = '$index_dir';
+--replace_result $data_dir <DATA_DIR> $index_dir <INDEX_DIR>
+SHOW CREATE TABLE t1;
+
+--replace_result $data_dir <DATA_DIR> $index_dir <INDEX_DIR>
+eval ALTER TABLE t1 INDEX DIRECTORY = '$data_dir';
+--replace_result $data_dir <DATA_DIR> $index_dir <INDEX_DIR> 
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
+--rmdir $data_dir
+--rmdir $index_dir
+
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_delay_key_write.result b/mysql-test/suite/leveldb/tbl_opt_delay_key_write.result
new file mode 100644
index 0000000..24bbb33
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_delay_key_write.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB DELAY_KEY_WRITE=1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
+ALTER TABLE t1 DELAY_KEY_WRITE=0;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_delay_key_write.test b/mysql-test/suite/leveldb/tbl_opt_delay_key_write.test
new file mode 100644
index 0000000..cfff52b
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_delay_key_write.test
@@ -0,0 +1,21 @@
+# 
+# Check whether DELAY_KEY_WRITE option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB DELAY_KEY_WRITE=1;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 DELAY_KEY_WRITE=0;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_insert_method.result b/mysql-test/suite/leveldb/tbl_opt_insert_method.result
new file mode 100644
index 0000000..265bd92
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_insert_method.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB INSERT_METHOD=FIRST;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 INSERT_METHOD=NO;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_insert_method.test b/mysql-test/suite/leveldb/tbl_opt_insert_method.test
new file mode 100644
index 0000000..f04535c
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_insert_method.test
@@ -0,0 +1,21 @@
+# 
+# Check whether INSERT_METHOD option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted (and apparently ignored)
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB INSERT_METHOD=FIRST;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 INSERT_METHOD=NO;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_key_block_size.result b/mysql-test/suite/leveldb/tbl_opt_key_block_size.result
new file mode 100644
index 0000000..1b6598b
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_key_block_size.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB KEY_BLOCK_SIZE=8;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8
+ALTER TABLE t1 KEY_BLOCK_SIZE=1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`) KEY_BLOCK_SIZE=8
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_key_block_size.test b/mysql-test/suite/leveldb/tbl_opt_key_block_size.test
new file mode 100644
index 0000000..ff63964
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_key_block_size.test
@@ -0,0 +1,21 @@
+# 
+# Check whether KEY_BLOCK_SIZE option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB KEY_BLOCK_SIZE=8;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 KEY_BLOCK_SIZE=1;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_max_rows.result b/mysql-test/suite/leveldb/tbl_opt_max_rows.result
new file mode 100644
index 0000000..5739013
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_max_rows.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB MAX_ROWS=10000000;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 MAX_ROWS=10000000
+ALTER TABLE t1 MAX_ROWS=30000000;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 MAX_ROWS=30000000
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_max_rows.test b/mysql-test/suite/leveldb/tbl_opt_max_rows.test
new file mode 100644
index 0000000..790c66c
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_max_rows.test
@@ -0,0 +1,21 @@
+# 
+# Check whether MAX_ROWS option
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB MAX_ROWS=10000000;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 MAX_ROWS=30000000;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_min_rows.result b/mysql-test/suite/leveldb/tbl_opt_min_rows.result
new file mode 100644
index 0000000..8bd62f7
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_min_rows.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB MIN_ROWS=1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 MIN_ROWS=1
+ALTER TABLE t1 MIN_ROWS=10000;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 MIN_ROWS=10000
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_min_rows.test b/mysql-test/suite/leveldb/tbl_opt_min_rows.test
new file mode 100644
index 0000000..52fe8fd
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_min_rows.test
@@ -0,0 +1,21 @@
+# 
+# Check whether MIN_ROWS option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB MIN_ROWS=1;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 MIN_ROWS=10000;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_pack_keys.result b/mysql-test/suite/leveldb/tbl_opt_pack_keys.result
new file mode 100644
index 0000000..0a4fb70
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_pack_keys.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB PACK_KEYS=1;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 PACK_KEYS=1
+ALTER TABLE t1 PACK_KEYS=0;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 PACK_KEYS=0
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_pack_keys.test b/mysql-test/suite/leveldb/tbl_opt_pack_keys.test
new file mode 100644
index 0000000..384a794
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_pack_keys.test
@@ -0,0 +1,21 @@
+# 
+# Check whether PACK KEYS option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB PACK_KEYS=1;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 PACK_KEYS=0;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_password.result b/mysql-test/suite/leveldb/tbl_opt_password.result
new file mode 100644
index 0000000..dcf3ff0
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_password.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB PASSWORD='password';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 PASSWORD='new_password';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_password.test b/mysql-test/suite/leveldb/tbl_opt_password.test
new file mode 100644
index 0000000..ff94cd8
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_password.test
@@ -0,0 +1,25 @@
+# 
+# Check whether PASSWORD option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+# This option is not supported by any known engines,
+# that's why the result file does not contain it;
+# but it's syntactically acceptable.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB PASSWORD='password';
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 PASSWORD='new_password';
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_row_format.result b/mysql-test/suite/leveldb/tbl_opt_row_format.result
new file mode 100644
index 0000000..9c67172
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_row_format.result
@@ -0,0 +1,18 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8) PRIMARY KEY) ENGINE=LevelDB ROW_FORMAT=FIXED;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) NOT NULL,
+  PRIMARY KEY (`b`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED
+ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` char(8) NOT NULL,
+  PRIMARY KEY (`b`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_opt_row_format.test b/mysql-test/suite/leveldb/tbl_opt_row_format.test
new file mode 100644
index 0000000..9c18559
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_row_format.test
@@ -0,0 +1,21 @@
+# 
+# Check whether ROW_FORMAT option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8) PRIMARY KEY) ENGINE=LevelDB ROW_FORMAT=FIXED;
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/tbl_opt_union.result b/mysql-test/suite/leveldb/tbl_opt_union.result
new file mode 100644
index 0000000..2680f05
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_union.result
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS t1, child1, child2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=LevelDB UNION(child1);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+ALTER TABLE t1 UNION = (child1,child2);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1
+DROP TABLE t1, child1, child2;
diff --git a/mysql-test/suite/leveldb/tbl_opt_union.test b/mysql-test/suite/leveldb/tbl_opt_union.test
new file mode 100644
index 0000000..cc8bf39
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_opt_union.test
@@ -0,0 +1,26 @@
+# 
+# Check whether UNION option 
+# is supported in CREATE and ALTER TABLE
+#
+# Note: the test does not check whether the option
+#       has any real effect on the table, only 
+#       that it's accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, child1, child2;
+--enable_warnings
+
+--disable_query_log
+CREATE TABLE child1 (a INT PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE child2 (a INT PRIMARY KEY) ENGINE=MyISAM;
+--enable_query_log
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=LevelDB UNION(child1);
+SHOW CREATE TABLE t1;
+
+ALTER TABLE t1 UNION = (child1,child2);
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1, child1, child2;
+
diff --git a/mysql-test/suite/leveldb/tbl_standard_opts.result b/mysql-test/suite/leveldb/tbl_standard_opts.result
new file mode 100644
index 0000000..e094692
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_standard_opts.result
@@ -0,0 +1,46 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB 
+DEFAULT CHARACTER SET = utf8
+COLLATE = utf8_general_ci
+COMMENT = 'standard table options'
+;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=utf8 COMMENT='standard table options'
+ALTER TABLE t1 COMMENT = 'table altered';
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=utf8 COMMENT='table altered'
+ALTER TABLE t1 ENGINE=MEMORY;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=MEMORY DEFAULT CHARSET=utf8 COMMENT='table altered'
+ALTER TABLE t1 ENGINE=LevelDB;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=utf8 COMMENT='table altered'
+ALTER TABLE t1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` char(8) CHARACTER SET utf8 DEFAULT NULL,
+  PRIMARY KEY (`a`)
+) ENGINE=LEVELDB DEFAULT CHARSET=latin1 COMMENT='table altered'
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/tbl_standard_opts.test b/mysql-test/suite/leveldb/tbl_standard_opts.test
new file mode 100644
index 0000000..9c3d0d4
--- /dev/null
+++ b/mysql-test/suite/leveldb/tbl_standard_opts.test
@@ -0,0 +1,40 @@
+# 
+# Standard options in CREATE and ALTER TABLE 
+#
+# Note: the test does not check whether the options
+#       have any real effect on the table, only 
+#       that they are accepted
+# 
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Create table with standard options
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB 
+  DEFAULT CHARACTER SET = utf8
+  COLLATE = utf8_general_ci
+  COMMENT = 'standard table options'
+;
+SHOW CREATE TABLE t1;  
+
+# Alter comment
+
+ALTER TABLE t1 COMMENT = 'table altered';
+SHOW CREATE TABLE t1;
+
+# Alter ENGINE value
+
+ALTER TABLE t1 ENGINE=MEMORY;
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ENGINE=LevelDB;
+SHOW CREATE TABLE t1;
+
+# Alter character set and collation
+
+ALTER TABLE t1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
+SHOW CREATE TABLE t1;
+
+DROP TABLE t1;
+  
diff --git a/mysql-test/suite/leveldb/transaction_isolation.inc b/mysql-test/suite/leveldb/transaction_isolation.inc
new file mode 100644
index 0000000..c8453b2
--- /dev/null
+++ b/mysql-test/suite/leveldb/transaction_isolation.inc
@@ -0,0 +1,92 @@
+#
+# Basic check for transaction isolation. 
+# The results should be different depending on the isolation level.
+# For some isolation levels, some statements will end with a timeout.
+# If the engine has its own timeout parameters, reduce them to minimum,
+# otherwise the test will take very long.
+# If the timeout value is greater than the testcase-timeout the test is run with,
+# it might fail due to the testcase timeout.
+#
+
+--enable_connect_log
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+connect (con1,localhost,root,,);
+eval SET SESSION TRANSACTION ISOLATION LEVEL $trx_isolation;
+connect (con2,localhost,root,,);
+eval SET SESSION TRANSACTION ISOLATION LEVEL $trx_isolation;
+
+connection con1;
+
+CREATE TABLE t1 (a INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+START TRANSACTION; 
+--sorted_result
+SELECT a FROM t1; # First snapshot
+
+connection con2;
+
+BEGIN;
+--error 0,ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a) VALUES(1); 
+
+connection con1;
+--sorted_result
+SELECT a FROM t1; # Second snapshot
+
+connection con2;
+--error 0,ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a) VALUES (2); 
+
+connection con1;
+--sorted_result
+SELECT a FROM t1; # Third snapshot
+
+--error 0,ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a) SELECT a+100 FROM t1; 
+
+--sorted_result
+SELECT a FROM t1;
+
+connection con2;
+--sorted_result
+SELECT a FROM t1; # Inside the transaction
+COMMIT;
+--sorted_result
+SELECT a FROM t1; # Outside the transaction
+
+connection con1;
+--sorted_result
+SELECT a FROM t1; # Inside the transaction
+
+# Note: INSERT .. SELECT might be tricky, for example for InnoDB
+# even with REPEATABLE-READ it works as if it is executed with READ COMMITTED.
+# The test will have a 'logical' result for repeatable read, even although
+# we currently don't have an engine which works this way.
+
+--error 0,ER_LOCK_WAIT_TIMEOUT
+INSERT INTO t1 (a) SELECT a+200 FROM t1; 
+
+--sorted_result
+SELECT a FROM t1;
+COMMIT;
+--sorted_result
+SELECT a FROM t1; # Outside the transaction
+
+connection con2;
+--sorted_result
+SELECT a FROM t1; # After both transactions have committed
+
+connection default;
+disconnect con1;
+disconnect con2;
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/suite/leveldb/truncate_table.result b/mysql-test/suite/leveldb/truncate_table.result
new file mode 100644
index 0000000..a5d1e95
--- /dev/null
+++ b/mysql-test/suite/leveldb/truncate_table.result
@@ -0,0 +1,33 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+TRUNCATE TABLE t1;
+INSERT INTO t1 (a,b) VALUES (1,'a'), (2,'b'), (3,'c');
+TRUNCATE TABLE t1;
+SELECT a,b FROM t1;
+a	b
+DROP TABLE t1;
+CREATE TABLE t1 (a INT KEY AUTO_INCREMENT, c CHAR(8)) ENGINE=LevelDB;
+SHOW TABLE STATUS LIKE 't1';
+Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
+t1	LEVELDB	10	Fixed	1000	0	0	0	0	0	0	NULL	NULL	NULL	latin1_swedish_ci	NULL		
+INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
+SHOW TABLE STATUS LIKE 't1';
+Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
+t1	LEVELDB	10	Fixed	1000	0	0	0	0	0	0	NULL	NULL	NULL	latin1_swedish_ci	NULL		
+TRUNCATE TABLE t1;
+SHOW TABLE STATUS LIKE 't1';
+Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
+t1	LEVELDB	10	Fixed	1000	0	0	0	0	0	0	NULL	NULL	NULL	latin1_swedish_ci	NULL		
+INSERT INTO t1 (c) VALUES ('d');
+SHOW TABLE STATUS LIKE 't1';
+Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
+t1	LEVELDB	10	Fixed	1000	0	0	0	0	0	0	NULL	NULL	NULL	latin1_swedish_ci	NULL		
+SELECT a,c FROM t1;
+a	c
+1	d
+DROP TABLE t1;
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c');
+HANDLER t1 OPEN AS h1;
+ERROR HY000: Table storage engine for 'h1' doesn't have this option
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/truncate_table.test b/mysql-test/suite/leveldb/truncate_table.test
new file mode 100644
index 0000000..97535fa
--- /dev/null
+++ b/mysql-test/suite/leveldb/truncate_table.test
@@ -0,0 +1,68 @@
+# 
+# TRUNCATE TABLE
+#
+
+########################################
+# TODO:
+# A part of the test is disabled because
+# HANDLER is not supported. If it ever
+# changes, the test will complain about
+# NOT producing ER_ILLEGAL_HA
+########################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+TRUNCATE TABLE t1;
+INSERT INTO t1 (a,b) VALUES (1,'a'), (2,'b'), (3,'c');
+TRUNCATE TABLE t1;
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+
+# Truncate resets auto-increment value on the table
+
+CREATE TABLE t1 (a INT KEY AUTO_INCREMENT, c CHAR(8)) ENGINE=LevelDB;
+
+#--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+SHOW TABLE STATUS LIKE 't1';
+
+INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
+#--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+SHOW TABLE STATUS LIKE 't1';
+
+TRUNCATE TABLE t1;
+#--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+SHOW TABLE STATUS LIKE 't1';
+
+INSERT INTO t1 (c) VALUES ('d');
+#--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 12 # 13 # 14 # 15 # 16 # 17 # 18 #
+SHOW TABLE STATUS LIKE 't1';
+
+--sorted_result
+SELECT a,c FROM t1;
+DROP TABLE t1;
+
+# Truncate closes handlers
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c');
+
+--error ER_ILLEGAL_HA
+HANDLER t1 OPEN AS h1;
+
+--disable_parsing
+
+HANDLER h1 READ FIRST;
+TRUNCATE TABLE t1;
+--error ER_UNKNOWN_TABLE
+HANDLER h1 READ NEXT;
+HANDLER t1 OPEN AS h2;
+HANDLER h2 READ FIRST;
+
+--enable_parsing
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_binary.inc b/mysql-test/suite/leveldb/type_binary.inc
new file mode 100644
index 0000000..4a53a1c
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_binary.inc
@@ -0,0 +1,45 @@
+#
+# BINARY column types
+#
+
+# $extra_col_options is set by a calling test
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  b BINARY $extra_col_opts,
+  b0 BINARY(0) $extra_col_opts,
+  b1 BINARY(1) $extra_col_opts,
+  b20 BINARY(20) $extra_col_opts,
+  b255 BINARY(255) $extra_col_opts,
+  pk BINARY PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Valid values 
+
+INSERT INTO t1 VALUES ('','','','','','');
+INSERT INTO t1 VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.','a');
+
+--sorted_result
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+
+# Invalid values
+
+INSERT INTO t1 VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256),'b');
+--error ER_DUP_ENTRY
+INSERT INTO t1 SELECT b255, b255, b255, b255, CONCAT('a',b255,b255), 'c' FROM t1;
+
+--sorted_result
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+
+--error ER_TOO_BIG_FIELDLENGTH
+eval ALTER TABLE t1 ADD COLUMN b257 BINARY(257) $extra_col_opts;
+
+SHOW COLUMNS IN t1;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_binary.result b/mysql-test/suite/leveldb/type_binary.result
new file mode 100644
index 0000000..ccee30a
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_binary.result
@@ -0,0 +1,48 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+b BINARY ,
+b0 BINARY(0) ,
+b1 BINARY(1) ,
+b20 BINARY(20) ,
+b255 BINARY(255) ,
+pk BINARY PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+b	binary(1)	YES		NULL	
+b0	binary(0)	YES		NULL	
+b1	binary(1)	YES		NULL	
+b20	binary(20)	YES		NULL	
+b255	binary(255)	YES		NULL	
+pk	binary(1)	NO	PRI	NULL	
+INSERT INTO t1 VALUES ('','','','','','');
+INSERT INTO t1 VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.','a');
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+HEX(b)	HEX(b0)	HEX(b1)	HEX(b20)	HEX(b255)	HEX(pk)
+00		00	0000000000000000000000000000000000000000	000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000	00
+61		62	616263646566676869206B6C6D6E6F7071727374	4372656174696E6720616E2061727469636C6520666F7220746865204B6E6F776C65646765626173652069732073696D696C617220746F2061736B696E67207175657374696F6E732E2046697273742C206E6176696761746520746F207468652063617465676F727920776865726520796F75206665656C207468652061727469636C652073686F756C642062652E204F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C726561647920657869737420776869636820776F756C6420776F726B2E00000000000000000000000000000000000000000000000000000000000000	61
+INSERT INTO t1 VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256),'b');
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b0' at row 1
+Warning	1265	Data truncated for column 'b1' at row 1
+Warning	1265	Data truncated for column 'b20' at row 1
+Warning	1265	Data truncated for column 'b255' at row 1
+INSERT INTO t1 SELECT b255, b255, b255, b255, CONCAT('a',b255,b255), 'c' FROM t1;
+ERROR 23000: Duplicate entry 'c' for key 'PRIMARY'
+SELECT HEX(b), HEX(b0), HEX(b1), HEX(b20), HEX(b255), HEX(pk) FROM t1 ORDER BY pk;
+HEX(b)	HEX(b0)	HEX(b1)	HEX(b20)	HEX(b255)	HEX(pk)
+00		00	0000000000000000000000000000000000000000	000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000	00
+61		61	6161616161616161616161616161616161616161	787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878	62
+61		62	616263646566676869206B6C6D6E6F7071727374	4372656174696E6720616E2061727469636C6520666F7220746865204B6E6F776C65646765626173652069732073696D696C617220746F2061736B696E67207175657374696F6E732E2046697273742C206E6176696761746520746F207468652063617465676F727920776865726520796F75206665656C207468652061727469636C652073686F756C642062652E204F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C726561647920657869737420776869636820776F756C6420776F726B2E00000000000000000000000000000000000000000000000000000000000000	61
+ALTER TABLE t1 ADD COLUMN b257 BINARY(257) ;
+ERROR 42000: Column length too big for column 'b257' (max = 255); use BLOB or TEXT instead
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+b	binary(1)	YES		NULL	
+b0	binary(0)	YES		NULL	
+b1	binary(1)	YES		NULL	
+b20	binary(20)	YES		NULL	
+b255	binary(255)	YES		NULL	
+pk	binary(1)	NO	PRI	NULL	
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_binary.test b/mysql-test/suite/leveldb/type_binary.test
new file mode 100644
index 0000000..7fbb180
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_binary.test
@@ -0,0 +1,6 @@
+#
+# BINARY column types
+#
+
+--source type_binary.inc
+
diff --git a/mysql-test/suite/leveldb/type_binary_indexes.result b/mysql-test/suite/leveldb/type_binary_indexes.result
new file mode 100644
index 0000000..1d9310e
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_binary_indexes.result
@@ -0,0 +1,85 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (b BINARY,
+b20 BINARY(20) PRIMARY KEY,
+v16 VARBINARY(16),
+v128 VARBINARY(128)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b20	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (b,b20,v16,v128) VALUES ('a','char1','varchar1a','varchar1b'),('a','char2','varchar2a','varchar2b'),('b','char3','varchar1a','varchar1b'),('c','char4','varchar3a','varchar3b');
+EXPLAIN SELECT HEX(b20) FROM t1 ORDER BY b20;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	20	NULL	1000	Using index
+SELECT HEX(b20) FROM t1 ORDER BY b20;
+HEX(b20)
+6368617231000000000000000000000000000000
+6368617232000000000000000000000000000000
+6368617233000000000000000000000000000000
+6368617234000000000000000000000000000000
+EXPLAIN SELECT HEX(b20) FROM t1 IGNORE INDEX (PRIMARY) ORDER BY b20 DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using filesort
+SELECT HEX(b20) FROM t1 ORDER BY b20 DESC;
+HEX(b20)
+6368617234000000000000000000000000000000
+6368617233000000000000000000000000000000
+6368617232000000000000000000000000000000
+6368617231000000000000000000000000000000
+DROP TABLE t1;
+CREATE TABLE t1 (b BINARY,
+b20 BINARY(20),
+v16 VARBINARY(16),
+v128 VARBINARY(128),
+UNIQUE INDEX b_v (b,v128),
+pk VARBINARY(10) PRIMARY KEY
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (b BINARY,
+b20 BINARY(20),
+v16 VARBINARY(16),
+v128 VARBINARY(128),
+pk VARBINARY(10) PRIMARY KEY,
+INDEX (v16(10))
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	v16	1	v16	A	NULL	10	NULL	YES	BTREE		
+INSERT INTO t1 (b,b20,v16,v128,pk) VALUES ('a','char1','varchar1a','varchar1b',1),('a','char2','varchar2a','varchar2b',2),('b','char3','varchar1a','varchar1b',3),('c','char4','varchar3a','varchar3b',4),('d','char5','varchar4a','varchar3b',5),('e','char6','varchar2a','varchar3b',6);
+INSERT INTO t1 (b,b20,v16,v128,pk) SELECT b,b20,v16,v128,pk+100 FROM t1;
+EXPLAIN SELECT HEX(SUBSTRING(v16,0,3)) FROM t1 WHERE v16 LIKE 'varchar%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	v16	v16	13	NULL	10	Using where
+SELECT HEX(SUBSTRING(v16,7,3)) FROM t1 WHERE v16 LIKE 'varchar%';
+HEX(SUBSTRING(v16,7,3))
+723161
+723161
+723161
+723161
+723261
+723261
+723261
+723261
+723361
+723361
+723461
+723461
+EXPLAIN SELECT HEX(SUBSTRING(v16,0,3)) FROM t1 FORCE INDEX (v16) WHERE v16 LIKE 'varchar%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	v16	v16	13	NULL	10	Using where
+SELECT HEX(SUBSTRING(v16,7,3)) FROM t1 FORCE INDEX (v16) WHERE v16 LIKE 'varchar%';
+HEX(SUBSTRING(v16,7,3))
+723161
+723161
+723161
+723161
+723261
+723261
+723261
+723261
+723361
+723361
+723461
+723461
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_binary_indexes.test b/mysql-test/suite/leveldb/type_binary_indexes.test
new file mode 100644
index 0000000..32bce42
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_binary_indexes.test
@@ -0,0 +1,86 @@
+#
+# BINARY and VARBINARY columns with indexes
+#
+
+#######################################
+# TODO: 
+# A part of the test is disabled 
+# because unique keys are not supported
+#######################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (b BINARY,
+  b20 BINARY(20) PRIMARY KEY,
+  v16 VARBINARY(16),
+  v128 VARBINARY(128)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (b,b20,v16,v128) VALUES ('a','char1','varchar1a','varchar1b'),('a','char2','varchar2a','varchar2b'),('b','char3','varchar1a','varchar1b'),('c','char4','varchar3a','varchar3b');
+
+EXPLAIN SELECT HEX(b20) FROM t1 ORDER BY b20;
+SELECT HEX(b20) FROM t1 ORDER BY b20;
+
+EXPLAIN SELECT HEX(b20) FROM t1 IGNORE INDEX (PRIMARY) ORDER BY b20 DESC;
+SELECT HEX(b20) FROM t1 ORDER BY b20 DESC;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (b BINARY,
+  b20 BINARY(20),
+  v16 VARBINARY(16),
+  v128 VARBINARY(128),
+  UNIQUE INDEX b_v (b,v128),
+  pk VARBINARY(10) PRIMARY KEY
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (b,b20,v16,v128) VALUES ('a','char1','varchar1a','varchar1b'),('a','char2','varchar2a','varchar2b'),('b','char3','varchar1a','varchar1b'),('c','char4','varchar3a','varchar3b');
+
+EXPLAIN SELECT HEX(b), HEX(v128) FROM t1 WHERE b != 'a' AND v128 > 'varchar';
+--sorted_result
+SELECT HEX(b), HEX(v128) FROM t1 WHERE b != 'a' AND v128 > 'varchar';
+
+EXPLAIN SELECT HEX(b), HEX(v128) FROM t1 USE INDEX (b_v) WHERE b != 'a' AND v128 > 'varchar';
+--sorted_result
+SELECT HEX(b), HEX(v128) FROM t1 USE INDEX (b_v) WHERE b != 'a' AND v128 > 'varchar';
+
+EXPLAIN SELECT HEX(v128), COUNT(*) FROM t1 GROUP BY HEX(v128);
+--sorted_result
+SELECT HEX(v128), COUNT(*) FROM t1 GROUP BY HEX(v128);
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (b BINARY,
+  b20 BINARY(20),
+  v16 VARBINARY(16),
+  v128 VARBINARY(128),
+  pk VARBINARY(10) PRIMARY KEY,
+  INDEX (v16(10))
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (b,b20,v16,v128,pk) VALUES ('a','char1','varchar1a','varchar1b',1),('a','char2','varchar2a','varchar2b',2),('b','char3','varchar1a','varchar1b',3),('c','char4','varchar3a','varchar3b',4),('d','char5','varchar4a','varchar3b',5),('e','char6','varchar2a','varchar3b',6);
+INSERT INTO t1 (b,b20,v16,v128,pk) SELECT b,b20,v16,v128,pk+100 FROM t1;
+
+EXPLAIN SELECT HEX(SUBSTRING(v16,0,3)) FROM t1 WHERE v16 LIKE 'varchar%';
+--sorted_result
+SELECT HEX(SUBSTRING(v16,7,3)) FROM t1 WHERE v16 LIKE 'varchar%';
+
+EXPLAIN SELECT HEX(SUBSTRING(v16,0,3)) FROM t1 FORCE INDEX (v16) WHERE v16 LIKE 'varchar%';
+--sorted_result
+SELECT HEX(SUBSTRING(v16,7,3)) FROM t1 FORCE INDEX (v16) WHERE v16 LIKE 'varchar%';
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_bit.inc b/mysql-test/suite/leveldb/type_bit.inc
new file mode 100644
index 0000000..ef4008c
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bit.inc
@@ -0,0 +1,53 @@
+#
+# BIT column type
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Valid values
+
+eval CREATE TABLE t1 (
+  a BIT $extra_col_opts,
+  b BIT(20) $extra_col_opts,
+  c BIT(64) $extra_col_opts,
+  d BIT(1) $extra_col_opts,
+  PRIMARY KEY (c)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+ALTER TABLE t1 DROP COLUMN d;
+eval ALTER TABLE t1 ADD COLUMN d BIT(0) $extra_col_opts;
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b,c,d) VALUES (0,POW(2,20)-1,b'1111111111111111111111111111111111111111111111111111111111111111',1);
+SELECT BIN(a), HEX(b), c+0 FROM t1 WHERE d>0;
+
+INSERT INTO t1 (a,b,c,d) VALUES (1,0,-2,0);
+--sorted_result
+SELECT a+0, b+0, c+0 FROM t1 WHERE d<100;
+
+INSERT INTO t1 (a,b,c,d) VALUES (b'1', 'f', 0xFF, 0x0);
+--sorted_result
+SELECT a+0, b+0, c+0 FROM t1 WHERE d IN (0, 2);
+
+DELETE FROM t1;
+
+# Out of range values
+# (should produce warnings)
+
+INSERT INTO t1 (a,b,c,d) VALUES (0x10,0,0,1);
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+
+INSERT INTO t1 (a,b,c,d) VALUES (0x01,0,0x10000000000000000,0);
+--sorted_result
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+
+DROP TABLE t1;
+
+--error ER_TOO_BIG_DISPLAYWIDTH
+eval CREATE TABLE t1 (pk INT PRIMARY KEY, a BIT(65) $extra_col_opts) ENGINE=LevelDB;
+
+
diff --git a/mysql-test/suite/leveldb/type_bit.result b/mysql-test/suite/leveldb/type_bit.result
new file mode 100644
index 0000000..a717725
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bit.result
@@ -0,0 +1,53 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a BIT ,
+b BIT(20) ,
+c BIT(64) ,
+d BIT(1) ,
+PRIMARY KEY (c)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	bit(1)	YES		NULL	
+b	bit(20)	YES		NULL	
+c	bit(64)	NO	PRI	b'0'	
+d	bit(1)	YES		NULL	
+ALTER TABLE t1 DROP COLUMN d;
+ALTER TABLE t1 ADD COLUMN d BIT(0) ;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	bit(1)	YES		NULL	
+b	bit(20)	YES		NULL	
+c	bit(64)	NO	PRI	b'0'	
+d	bit(1)	YES		NULL	
+INSERT INTO t1 (a,b,c,d) VALUES (0,POW(2,20)-1,b'1111111111111111111111111111111111111111111111111111111111111111',1);
+SELECT BIN(a), HEX(b), c+0 FROM t1 WHERE d>0;
+BIN(a)	HEX(b)	c+0
+0	FFFFF	18446744073709551615
+INSERT INTO t1 (a,b,c,d) VALUES (1,0,-2,0);
+SELECT a+0, b+0, c+0 FROM t1 WHERE d<100;
+a+0	b+0	c+0
+0	1048575	18446744073709551615
+1	0	18446744073709551614
+INSERT INTO t1 (a,b,c,d) VALUES (b'1', 'f', 0xFF, 0x0);
+SELECT a+0, b+0, c+0 FROM t1 WHERE d IN (0, 2);
+a+0	b+0	c+0
+1	0	18446744073709551614
+1	102	255
+DELETE FROM t1;
+INSERT INTO t1 (a,b,c,d) VALUES (0x10,0,0,1);
+Warnings:
+Warning	1264	Out of range value for column 'a' at row 1
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+a+0	b+0	c+0	d+0
+1	0	0	1
+INSERT INTO t1 (a,b,c,d) VALUES (0x01,0,0x10000000000000000,0);
+Warnings:
+Warning	1264	Out of range value for column 'c' at row 1
+SELECT a+0,b+0,c+0,d+0 FROM t1;
+a+0	b+0	c+0	d+0
+1	0	0	1
+1	0	18446744073709551615	0
+DROP TABLE t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY, a BIT(65) ) ENGINE=LevelDB;
+ERROR 42000: Display width out of range for column 'a' (max = 64)
diff --git a/mysql-test/suite/leveldb/type_bit.test b/mysql-test/suite/leveldb/type_bit.test
new file mode 100644
index 0000000..4247e40
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bit.test
@@ -0,0 +1,6 @@
+#
+# BIT column type
+#
+
+--source type_bit.inc
+
diff --git a/mysql-test/suite/leveldb/type_bit_indexes.result b/mysql-test/suite/leveldb/type_bit_indexes.result
new file mode 100644
index 0000000..c25c59e
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bit_indexes.result
@@ -0,0 +1,72 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a BIT,
+b BIT(20) PRIMARY KEY,
+c BIT(32),
+d BIT(64)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (a,b,c,d) VALUES 
+(0,0xFFFFF,0,1),(0,256,0xAAA,0x12345),(1,16,0,0xFFFFFFF),(0,11,12,13),
+(1,100,101,102),(0,12,13,14),(1,13,14,15),(0,101,201,202),(1,1000,1001,1002),
+(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+EXPLAIN SELECT b+0 FROM t1 ORDER BY b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	3	NULL	1000	Using index
+SELECT b+0 FROM t1 ORDER BY b;
+b+0
+11
+12
+13
+16
+100
+101
+256
+1000
+65535
+1048575
+DROP TABLE t1;
+CREATE TABLE t1 (
+a BIT,
+b BIT(20),
+c BIT(32),
+d BIT(64),
+pk BIT(10) PRIMARY KEY,
+UNIQUE INDEX b_c (b,c)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (
+a BIT,
+b BIT(20),
+c BIT(32),
+d BIT(64),
+pk BIT(10) PRIMARY KEY,
+INDEX(a)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+INSERT INTO t1 (a,b,c,d,pk) VALUES
+(0,0xFFFFF,0,1,1),(0,256,0xAAA,0x12345,2),(1,16,0,0xFFFFFFF,3),(0,11,12,13,4),
+(1,100,101,102,5),(0,12,13,14,6),(1,13,14,15,7),(0,101,201,202,8),(1,1000,1001,1002,9),
+(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF,10);
+EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary; Using filesort
+SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+a+0
+0
+1
+DROP TABLE t1;
+CREATE TABLE t1 (
+a BIT,
+b BIT(20),
+c BIT(32),
+d BIT(64),
+pk BIT(10) PRIMARY KEY,
+UNIQUE INDEX (d)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
diff --git a/mysql-test/suite/leveldb/type_bit_indexes.test b/mysql-test/suite/leveldb/type_bit_indexes.test
new file mode 100644
index 0000000..5bb64b5
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bit_indexes.test
@@ -0,0 +1,102 @@
+#
+# BIT columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  a BIT,
+  b BIT(20) PRIMARY KEY,
+  c BIT(32),
+  d BIT(64)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c,d) VALUES 
+(0,0xFFFFF,0,1),(0,256,0xAAA,0x12345),(1,16,0,0xFFFFFFF),(0,11,12,13),
+(1,100,101,102),(0,12,13,14),(1,13,14,15),(0,101,201,202),(1,1000,1001,1002),
+(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+
+EXPLAIN SELECT b+0 FROM t1 ORDER BY b;
+SELECT b+0 FROM t1 ORDER BY b;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  a BIT,
+  b BIT(20),
+  c BIT(32),
+  d BIT(64),
+  pk BIT(10) PRIMARY KEY,
+UNIQUE INDEX b_c (b,c)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c,d,pk) VALUES
+(0,0xFFFFF,0,1,1),(0,256,0xAAA,0x12345,2),(1,16,0,0xFFFFFFF,3),(0,11,12,13,4),
+(1,100,101,102,5),(0,12,13,14,6),(1,13,14,15,7),(0,101,201,202,8),(1,1000,1001,1002,9),
+(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF,10);
+
+EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
+--sorted_result
+SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  a BIT,
+  b BIT(20),
+  c BIT(32),
+  d BIT(64),
+  pk BIT(10) PRIMARY KEY,
+  INDEX(a)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c,d,pk) VALUES
+(0,0xFFFFF,0,1,1),(0,256,0xAAA,0x12345,2),(1,16,0,0xFFFFFFF,3),(0,11,12,13,4),
+(1,100,101,102,5),(0,12,13,14,6),(1,13,14,15,7),(0,101,201,202,8),(1,1000,1001,1002,9),
+(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF,10);
+
+EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  a BIT,
+  b BIT(20),
+  c BIT(32),
+  d BIT(64),
+  pk BIT(10) PRIMARY KEY,
+  UNIQUE INDEX (d)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c,d,pk) VALUES
+(0,0xFFFFF,0,1,1),(0,256,0xAAA,0x12345,2),(1,16,0,0xFFFFFFF,3),(0,11,12,13,4),
+(1,100,101,102,5),(0,12,13,14,6),(1,13,14,15,7),(0,101,201,202,8),(1,1000,1001,1002,9),
+(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF,10);
+
+EXPLAIN SELECT d FROM t1 WHERE d BETWEEN 1 AND 10000;
+--sorted_result
+SELECT d+0 FROM t1 WHERE d BETWEEN 1 AND 10000;
+
+DROP TABLE t1;
+
+--enable_parsing
+
diff --git a/mysql-test/suite/leveldb/type_blob.inc b/mysql-test/suite/leveldb/type_blob.inc
new file mode 100644
index 0000000..c3c8b3c
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_blob.inc
@@ -0,0 +1,49 @@
+#
+# BLOB column types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  b BLOB $extra_col_opts,
+  b0 BLOB(0) $extra_col_opts,
+  b1 BLOB(1) $extra_col_opts,
+  b300 BLOB(300) $extra_col_opts,
+  bm BLOB(65535) $extra_col_opts,
+  b70k BLOB(70000) $extra_col_opts,
+  b17m BLOB(17000000) $extra_col_opts,
+  t TINYBLOB $extra_col_opts,
+  m MEDIUMBLOB $extra_col_opts,
+  l LONGBLOB $extra_col_opts
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Valid values 
+# (cannot get MAX for all columns due to max_allowed_packet limitations)
+
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), HEX(REPEAT('g',1048576)), REPEAT('h',255), REPEAT('i',1048576), HEX(REPEAT('j',1048576)) );
+
+--sorted_result
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+
+# Invalid values (produce warnings, except for mediumblob and longblob columns for which the values are within limits)
+
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+
+--sorted_result
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+
+--error ER_TOO_BIG_DISPLAYWIDTH
+ALTER TABLE t1 ADD COLUMN bbb BLOB(4294967296);
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_blob.result b/mysql-test/suite/leveldb/type_blob.result
new file mode 100644
index 0000000..e22e392
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_blob.result
@@ -0,0 +1,57 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+b BLOB ,
+b0 BLOB(0) ,
+b1 BLOB(1) ,
+b300 BLOB(300) ,
+bm BLOB(65535) ,
+b70k BLOB(70000) ,
+b17m BLOB(17000000) ,
+t TINYBLOB ,
+m MEDIUMBLOB ,
+l LONGBLOB 
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+b	blob	YES		NULL	
+b0	blob	YES		NULL	
+b1	tinyblob	YES		NULL	
+b300	blob	YES		NULL	
+bm	blob	YES		NULL	
+b70k	mediumblob	YES		NULL	
+b17m	longblob	YES		NULL	
+t	tinyblob	YES		NULL	
+m	mediumblob	YES		NULL	
+l	longblob	YES		NULL	
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), HEX(REPEAT('g',1048576)), REPEAT('h',255), REPEAT('i',1048576), HEX(REPEAT('j',1048576)) );
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(b)	LENGTH(b0)	LENGTH(b1)	LENGTH(b300)	LENGTH(bm)	LENGTH(b70k)	LENGTH(b17m)	LENGTH(t)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	2097152	255	1048576	2097152
+INSERT INTO t1 (b,b0,b1,b300,bm,b70k,b17m,t,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'b0' at row 1
+Warning	1265	Data truncated for column 'b1' at row 1
+Warning	1265	Data truncated for column 'b300' at row 1
+Warning	1265	Data truncated for column 'bm' at row 1
+Warning	1265	Data truncated for column 't' at row 1
+SELECT LENGTH(b), LENGTH(b0), LENGTH(b1), LENGTH(b300), LENGTH(bm), LENGTH(b70k), LENGTH(b17m), LENGTH(t), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(b)	LENGTH(b0)	LENGTH(b1)	LENGTH(b300)	LENGTH(bm)	LENGTH(b70k)	LENGTH(b17m)	LENGTH(t)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+65535	65535	255	65535	65535	1048576	2097152	255	1048576	2097152
+ALTER TABLE t1 ADD COLUMN bbb BLOB(4294967296);
+ERROR 42000: Display width out of range for column 'bbb' (max = 4294967295)
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_blob.test b/mysql-test/suite/leveldb/type_blob.test
new file mode 100644
index 0000000..d642169
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_blob.test
@@ -0,0 +1,6 @@
+#
+# BLOB column types
+#
+
+--source type_blob.inc
+
diff --git a/mysql-test/suite/leveldb/type_blob_indexes.result b/mysql-test/suite/leveldb/type_blob_indexes.result
new file mode 100644
index 0000000..8e732e1
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_blob_indexes.result
@@ -0,0 +1,152 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (b BLOB <CUSTOM_COL_OPTIONS>,
+t TINYBLOB <CUSTOM_COL_OPTIONS>,
+m MEDIUMBLOB <CUSTOM_COL_OPTIONS>,
+l LONGBLOB <CUSTOM_COL_OPTIONS>,
+<CUSTOM_INDEX> b (b(32))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	1	#	1	b	#	#	32	NULL	#	#		
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+SELECT SUBSTRING(b,16) AS f FROM t1 WHERE b IN ('test1','test2') ORDER BY f;
+f
+
+
+SELECT SUBSTRING(b,16) AS f FROM t1 USE INDEX () WHERE b IN ('test1','test2') ORDER BY f;
+f
+
+
+DROP TABLE t1;
+CREATE TABLE t1 (b BLOB <CUSTOM_COL_OPTIONS>,
+t TINYBLOB <CUSTOM_COL_OPTIONS>,
+m MEDIUMBLOB <CUSTOM_COL_OPTIONS>,
+l LONGBLOB <CUSTOM_COL_OPTIONS>,
+PRIMARY KEY b (b(32))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	b	#	#	32	NULL	#	#		
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+EXPLAIN SELECT SUBSTRING(b,16) AS f FROM t1 WHERE b IN ('test1','test2') ORDER BY f;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	PRIMARY	#	#	#	#
+SELECT SUBSTRING(b,16) AS f FROM t1 WHERE b IN ('test1','test2') ORDER BY f;
+f
+
+
+EXPLAIN SELECT SUBSTRING(b,16) AS f FROM t1 USE INDEX () WHERE b IN ('test1','test2') ORDER BY f;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	NULL	#	#	#	#
+SELECT SUBSTRING(b,16) AS f FROM t1 USE INDEX () WHERE b IN ('test1','test2') ORDER BY f;
+f
+
+
+DROP TABLE t1;
+CREATE TABLE t1 (b BLOB <CUSTOM_COL_OPTIONS>,
+t TINYBLOB <CUSTOM_COL_OPTIONS>,
+m MEDIUMBLOB <CUSTOM_COL_OPTIONS>,
+l LONGBLOB <CUSTOM_COL_OPTIONS>,
+UNIQUE INDEX l_t (l(256),t(64))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	l_t	1	l	#	#	256	NULL	#	#		
+t1	0	l_t	2	t	#	#	64	NULL	#	#		
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+EXPLAIN SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	l_t	#	#	#	#	#
+SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+SUBSTRING(t,64)	SUBSTRING(l,256)
+	
+	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+	
+	
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff	
+	
+	
+	
+EXPLAIN SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	l_t	#	#	#	#	#
+SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+SUBSTRING(t,64)	SUBSTRING(l,256)
+	
+	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+	
+	
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff	
+	
+	
+	
+DROP TABLE t1;
+CREATE TABLE t1 (b BLOB <CUSTOM_COL_OPTIONS>,
+t TINYBLOB <CUSTOM_COL_OPTIONS>,
+m MEDIUMBLOB <CUSTOM_COL_OPTIONS>,
+l LONGBLOB <CUSTOM_COL_OPTIONS>,
+INDEX (m(128))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	1	m	1	m	#	#	128	NULL	#	#		
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+EXPLAIN SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	m	#	#	#	#
+SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+f
+EXPLAIN SELECT SUBSTRING(m,128) AS f FROM t1 IGNORE INDEX FOR ORDER BY (m) WHERE m = 'test1' ORDER BY f DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	m	#	#	#	#
+SELECT SUBSTRING(m,128) AS f FROM t1 IGNORE INDEX FOR ORDER BY (m) WHERE m = 'test1' ORDER BY f DESC;
+f
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_blob_indexes.test b/mysql-test/suite/leveldb/type_blob_indexes.test
new file mode 100644
index 0000000..006d74e
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_blob_indexes.test
@@ -0,0 +1,109 @@
+#
+# BLOB columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  b BLOB,
+  t TINYBLOB,
+  m MEDIUMBLOB,
+  l LONGBLOB,
+  PRIMARY KEY b (b(32))
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+
+--replace_column 1 # 2 # 3 # 4 # 5 # 7 # 8 # 9 # 10 #
+EXPLAIN SELECT SUBSTRING(b,16) AS f FROM t1 WHERE b IN ('test1','test2') ORDER BY f;
+SELECT SUBSTRING(b,16) AS f FROM t1 WHERE b IN ('test1','test2') ORDER BY f;
+
+--replace_column 1 # 2 # 3 # 4 # 5 # 7 # 8 # 9 # 10 #
+EXPLAIN SELECT SUBSTRING(b,16) AS f FROM t1 USE INDEX () WHERE b IN ('test1','test2') ORDER BY f;
+SELECT SUBSTRING(b,16) AS f FROM t1 USE INDEX () WHERE b IN ('test1','test2') ORDER BY f;
+
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (
+  b BLOB,
+  t TINYBLOB,
+  m MEDIUMBLOB,
+  l LONGBLOB,
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  UNIQUE INDEX l_t (l(256),t(64))
+) ENGINE=LevelDB;
+
+--replace_column 6 # 7 # 10 # 11 #
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+
+# Here we are getting possible key l_t, but not the final key
+EXPLAIN SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+
+EXPLAIN SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+SELECT SUBSTRING(t,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE t!=l AND l NOT IN ('test1') ORDER BY t, l DESC;
+
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (
+  b BLOB,
+  t TINYBLOB,
+  m MEDIUMBLOB,
+  l LONGBLOB,
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  INDEX (m(128))
+) ENGONE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (b,t,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+(HEX('abcd'),HEX('def'),HEX('a'),HEX('abc')),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+
+EXPLAIN SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+
+EXPLAIN SELECT SUBSTRING(m,128) AS f FROM t1 IGNORE INDEX FOR ORDER BY (m) WHERE m = 'test1' ORDER BY f DESC;
+SELECT SUBSTRING(m,128) AS f FROM t1 IGNORE INDEX FOR ORDER BY (m) WHERE m = 'test1' ORDER BY f DESC;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_bool.inc b/mysql-test/suite/leveldb/type_bool.inc
new file mode 100644
index 0000000..73b0e71
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bool.inc
@@ -0,0 +1,64 @@
+#
+# BOOLEAN column type
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  b1 BOOL $extra_col_opts,
+  b2 BOOLEAN $extra_col_opts
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Valid values 
+
+INSERT INTO t1 (b1,b2) VALUES (1,TRUE);
+SELECT b1,b2 FROM t1;
+
+INSERT INTO t1 (b1,b2) VALUES (FALSE,0);
+--sorted_result
+SELECT b1,b2 FROM t1;
+
+INSERT INTO t1 (b1,b2) VALUES (2,3);
+--sorted_result
+SELECT b1,b2 FROM t1;
+
+INSERT INTO t1 (b1,b2) VALUES (-1,-2);
+--sorted_result
+SELECT b1,b2 FROM t1;
+
+--sorted_result
+SELECT IF(b1,'true','false') AS a, IF(b2,'true','false') AS b FROM t1;
+
+--sorted_result
+SELECT b1,b2 FROM t1 WHERE b1 = TRUE;
+
+--sorted_result
+SELECT b1,b2 FROM t1 WHERE b2 = FALSE;
+
+# Invalid values
+
+INSERT INTO t1 (b1,b2) VALUES ('a','b');
+--sorted_result
+SELECT b1,b2 FROM t1;
+
+INSERT INTO t1 (b1,b2) VALUES (128,-129);
+--sorted_result
+SELECT b1,b2 FROM t1;
+
+# This is why we don't have zerofill and unsigned tests
+# for boolean columns:
+--error ER_PARSE_ERROR
+eval ALTER TABLE t1 ADD COLUMN b3 BOOLEAN UNSIGNED $extra_col_opts;
+
+--error ER_PARSE_ERROR
+eval ALTER TABLE ADD COLUMN b3 BOOL ZEROFILL $extra_col_opts;
+
+DROP TABLE t1;
+
+
+
diff --git a/mysql-test/suite/leveldb/type_bool.result b/mysql-test/suite/leveldb/type_bool.result
new file mode 100644
index 0000000..dfc73a0
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bool.result
@@ -0,0 +1,73 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+b1 BOOL ,
+b2 BOOLEAN 
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+b1	tinyint(1)	YES		NULL	
+b2	tinyint(1)	YES		NULL	
+INSERT INTO t1 (b1,b2) VALUES (1,TRUE);
+SELECT b1,b2 FROM t1;
+b1	b2
+1	1
+INSERT INTO t1 (b1,b2) VALUES (FALSE,0);
+SELECT b1,b2 FROM t1;
+b1	b2
+0	0
+1	1
+INSERT INTO t1 (b1,b2) VALUES (2,3);
+SELECT b1,b2 FROM t1;
+b1	b2
+0	0
+1	1
+2	3
+INSERT INTO t1 (b1,b2) VALUES (-1,-2);
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+1	1
+2	3
+SELECT IF(b1,'true','false') AS a, IF(b2,'true','false') AS b FROM t1;
+a	b
+false	false
+true	true
+true	true
+true	true
+SELECT b1,b2 FROM t1 WHERE b1 = TRUE;
+b1	b2
+1	1
+SELECT b1,b2 FROM t1 WHERE b2 = FALSE;
+b1	b2
+0	0
+INSERT INTO t1 (b1,b2) VALUES ('a','b');
+Warnings:
+Warning	1366	Incorrect integer value: 'a' for column 'b1' at row 1
+Warning	1366	Incorrect integer value: 'b' for column 'b2' at row 1
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+0	0
+1	1
+2	3
+INSERT INTO t1 (b1,b2) VALUES (128,-129);
+Warnings:
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b2' at row 1
+SELECT b1,b2 FROM t1;
+b1	b2
+-1	-2
+0	0
+0	0
+1	1
+127	-128
+2	3
+ALTER TABLE t1 ADD COLUMN b3 BOOLEAN UNSIGNED ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNSIGNED' at line 1
+ALTER TABLE ADD COLUMN b3 BOOL ZEROFILL ;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ADD COLUMN b3 BOOL ZEROFILL' at line 1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_bool.test b/mysql-test/suite/leveldb/type_bool.test
new file mode 100644
index 0000000..66611e9
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_bool.test
@@ -0,0 +1,6 @@
+#
+# BOOLEAN column type
+#
+
+--source type_bool.inc
+
diff --git a/mysql-test/suite/leveldb/type_char.inc b/mysql-test/suite/leveldb/type_char.inc
new file mode 100644
index 0000000..7061949
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_char.inc
@@ -0,0 +1,45 @@
+#
+# CHAR column types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  c CHAR $extra_col_opts,
+  c0 CHAR(0) $extra_col_opts,
+  c1 CHAR(1) $extra_col_opts,
+  c20 CHAR(20) $extra_col_opts,
+  c255 CHAR(255) $extra_col_opts,
+  PRIMARY KEY (c255)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Valid values 
+
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('','','','','');
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.');
+
+--sorted_result
+SELECT c,c0,c1,c20,c255 FROM t1;
+
+# Invalid values
+
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256));
+INSERT INTO t1 (c,c0,c1,c20,c255) SELECT c255, c255, c255, c255, CONCAT('a',c255,c1) FROM t1;
+
+--sorted_result
+SELECT c,c0,c1,c20,c255 FROM t1;
+
+--sorted_result
+SELECT DISTINCT c20, REPEAT('a',LENGTH(c20)), COUNT(*) FROM t1 GROUP BY c1, c20;
+
+--error ER_TOO_BIG_FIELDLENGTH
+eval ALTER TABLE t1 ADD COLUMN c257 CHAR(257) $extra_col_opts;
+
+DROP TABLE t1;
+
+
+
diff --git a/mysql-test/suite/leveldb/type_char.result b/mysql-test/suite/leveldb/type_char.result
new file mode 100644
index 0000000..deb61fb
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_char.result
@@ -0,0 +1,58 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c CHAR ,
+c0 CHAR(0) ,
+c1 CHAR(1) ,
+c20 CHAR(20) ,
+c255 CHAR(255) ,
+PRIMARY KEY (c255)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+c	char(1)	YES		NULL	
+c0	char(0)	YES		NULL	
+c1	char(1)	YES		NULL	
+c20	char(20)	YES		NULL	
+c255	char(255)	NO	PRI		
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('','','','','');
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('a','','b','abcdefghi klmnopqrst', 'Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn\'t already exist which would work.');
+SELECT c,c0,c1,c20,c255 FROM t1;
+c	c0	c1	c20	c255
+				
+a		b	abcdefghi klmnopqrst	Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.
+INSERT INTO t1 (c,c0,c1,c20,c255) VALUES ('abc', 'a', 'abc', REPEAT('a',21), REPEAT('x',256));
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 1
+Warning	1265	Data truncated for column 'c0' at row 1
+Warning	1265	Data truncated for column 'c1' at row 1
+Warning	1265	Data truncated for column 'c20' at row 1
+Warning	1265	Data truncated for column 'c255' at row 1
+INSERT INTO t1 (c,c0,c1,c20,c255) SELECT c255, c255, c255, c255, CONCAT('a',c255,c1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 5
+Warning	1265	Data truncated for column 'c0' at row 5
+Warning	1265	Data truncated for column 'c1' at row 5
+Warning	1265	Data truncated for column 'c20' at row 5
+Warning	1265	Data truncated for column 'c' at row 6
+Warning	1265	Data truncated for column 'c0' at row 6
+Warning	1265	Data truncated for column 'c1' at row 6
+Warning	1265	Data truncated for column 'c20' at row 6
+Warning	1265	Data truncated for column 'c255' at row 6
+SELECT c,c0,c1,c20,c255 FROM t1;
+c	c0	c1	c20	c255
+				
+				a
+C		C	Creating an article	aCreating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.b
+a		a	aaaaaaaaaaaaaaaaaaaa	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+a		b	abcdefghi klmnopqrst	Creating an article for the Knowledgebase is similar to asking questions. First, navigate to the category where you feel the article should be. Once there, double check that an article doesn't already exist which would work.
+x		x	xxxxxxxxxxxxxxxxxxxx	axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+SELECT DISTINCT c20, REPEAT('a',LENGTH(c20)), COUNT(*) FROM t1 GROUP BY c1, c20;
+c20	REPEAT('a',LENGTH(c20))	COUNT(*)
+		2
+Creating an article	aaaaaaaaaaaaaaaaaaa	1
+aaaaaaaaaaaaaaaaaaaa	aaaaaaaaaaaaaaaaaaaa	1
+abcdefghi klmnopqrst	aaaaaaaaaaaaaaaaaaaa	1
+xxxxxxxxxxxxxxxxxxxx	aaaaaaaaaaaaaaaaaaaa	1
+ALTER TABLE t1 ADD COLUMN c257 CHAR(257) ;
+ERROR 42000: Column length too big for column 'c257' (max = 255); use BLOB or TEXT instead
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_char.test b/mysql-test/suite/leveldb/type_char.test
new file mode 100644
index 0000000..f67f6b0
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_char.test
@@ -0,0 +1,6 @@
+#
+# CHAR column types
+#
+
+--source type_char.inc
+
diff --git a/mysql-test/suite/leveldb/type_char_indexes.result b/mysql-test/suite/leveldb/type_char_indexes.result
new file mode 100644
index 0000000..dcd9c5e
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_char_indexes.result
@@ -0,0 +1,79 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+c CHAR,
+c20 CHAR(20) PRIMARY KEY,
+v16 VARCHAR(16),
+v128 VARCHAR(128)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	c20	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (c,c20,v16,v128) VALUES ('a','char1','varchar1a','varchar1b'),('a','char2','varchar2a','varchar2b'),('b','char3','varchar1a','varchar1b'),('c','char4','varchar3a','varchar3b');
+EXPLAIN SELECT c20 FROM t1 ORDER BY c20;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	20	NULL	1000	Using index
+SELECT c20 FROM t1 ORDER BY c20;
+c20
+char1
+char2
+char3
+char4
+EXPLAIN SELECT c20 FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY c20;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	20	NULL	1000	Using index
+SELECT c20 FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY c20;
+c20
+char1
+char2
+char3
+char4
+DROP TABLE t1;
+CREATE TABLE t1 (
+c CHAR,
+c20 CHAR(20),
+v16 VARCHAR(16),
+v128 VARCHAR(128),
+pk CHAR(64) PRIMARY KEY,
+UNIQUE INDEX c_v (c,v128)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (
+c CHAR,
+c20 CHAR(20),
+v16 VARCHAR(16),
+v128 VARCHAR(128),
+pk VARCHAR(64) PRIMARY KEY,
+INDEX (v16)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	v16	1	v16	A	NULL	NULL	NULL	YES	BTREE		
+INSERT INTO t1 (c,c20,v16,v128,pk) VALUES ('a','char1','varchar1a','varchar1b','1'),('a','char2','varchar2a','varchar2b','2'),('b','char3','varchar1a','varchar1b','3'),('c','char4','varchar3a','varchar3b','4');
+EXPLAIN SELECT SUBSTRING(v16,0,3) FROM t1 WHERE v16 LIKE 'varchar%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	v16	v16	19	NULL	10	Using where
+SELECT SUBSTRING(v16,7,3) FROM t1 WHERE v16 LIKE 'varchar%';
+SUBSTRING(v16,7,3)
+r1a
+r1a
+r2a
+r3a
+EXPLAIN SELECT SUBSTRING(v16,0,3) FROM t1 IGNORE INDEX (v16) WHERE v16 LIKE 'varchar%';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using where
+SELECT SUBSTRING(v16,7,3) FROM t1 IGNORE INDEX (v16) WHERE v16 LIKE 'varchar%';
+SUBSTRING(v16,7,3)
+r1a
+r1a
+r2a
+r3a
+EXPLAIN SELECT c,c20,v16,v128 FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	v16	v16	19	NULL	20	Using where
+SELECT c,c20,v16,v128 FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16;
+c	c20	v16	v128
+a	char1	varchar1a	varchar1b
+b	char3	varchar1a	varchar1b
+c	char4	varchar3a	varchar3b
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_char_indexes.test b/mysql-test/suite/leveldb/type_char_indexes.test
new file mode 100644
index 0000000..d4a72b0
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_char_indexes.test
@@ -0,0 +1,92 @@
+#
+# CHAR and VARCHAR columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  c CHAR,
+  c20 CHAR(20) PRIMARY KEY,
+  v16 VARCHAR(16),
+  v128 VARCHAR(128)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (c,c20,v16,v128) VALUES ('a','char1','varchar1a','varchar1b'),('a','char2','varchar2a','varchar2b'),('b','char3','varchar1a','varchar1b'),('c','char4','varchar3a','varchar3b');
+
+EXPLAIN SELECT c20 FROM t1 ORDER BY c20;
+SELECT c20 FROM t1 ORDER BY c20;
+
+EXPLAIN SELECT c20 FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY c20;
+SELECT c20 FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY c20;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  c CHAR,
+  c20 CHAR(20),
+  v16 VARCHAR(16),
+  v128 VARCHAR(128),
+  pk CHAR(64) PRIMARY KEY,
+  UNIQUE INDEX c_v (c,v128)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (c,c20,v16,v128) VALUES ('a','char1','varchar1a','varchar1b'),('a','char2','varchar2a','varchar2b'),('b','char3','varchar1a','varchar1b'),('c','char4','varchar3a','varchar3b');
+
+EXPLAIN SELECT c, v128 FROM t1 WHERE c != 'a' AND v128 > 'varchar';
+--sorted_result
+SELECT c, v128 FROM t1 WHERE c != 'a' AND v128 > 'varchar';
+
+EXPLAIN SELECT v128, COUNT(*) FROM t1 GROUP BY v128;
+--sorted_result
+SELECT v128, COUNT(*) FROM t1 GROUP BY v128;
+
+EXPLAIN SELECT v128, COUNT(*) FROM t1 USE INDEX FOR GROUP BY (c_v) GROUP BY v128;
+--sorted_result
+SELECT v128, COUNT(*) FROM t1 USE INDEX FOR GROUP BY (c_v) GROUP BY v128;
+
+SET SESSION optimizer_switch = 'engine_condition_pushdown=on';
+EXPLAIN SELECT c,c20,v16,v128 FROM t1 WHERE c > 'a';
+--sorted_result
+SELECT c,c20,v16,v128 FROM t1 WHERE c > 'a';
+SET SESSION optimizer_switch = @@global.optimizer_switch;
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  c CHAR,
+  c20 CHAR(20),
+  v16 VARCHAR(16),
+  v128 VARCHAR(128),
+  pk VARCHAR(64) PRIMARY KEY,
+  INDEX (v16)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (c,c20,v16,v128,pk) VALUES ('a','char1','varchar1a','varchar1b','1'),('a','char2','varchar2a','varchar2b','2'),('b','char3','varchar1a','varchar1b','3'),('c','char4','varchar3a','varchar3b','4');
+
+EXPLAIN SELECT SUBSTRING(v16,0,3) FROM t1 WHERE v16 LIKE 'varchar%';
+--sorted_result
+SELECT SUBSTRING(v16,7,3) FROM t1 WHERE v16 LIKE 'varchar%';
+
+EXPLAIN SELECT SUBSTRING(v16,0,3) FROM t1 IGNORE INDEX (v16) WHERE v16 LIKE 'varchar%';
+--sorted_result
+SELECT SUBSTRING(v16,7,3) FROM t1 IGNORE INDEX (v16) WHERE v16 LIKE 'varchar%';
+
+EXPLAIN SELECT c,c20,v16,v128 FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16;
+--sorted_result
+SELECT c,c20,v16,v128 FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_date_time.inc b/mysql-test/suite/leveldb/type_date_time.inc
new file mode 100644
index 0000000..9238f3d
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_date_time.inc
@@ -0,0 +1,45 @@
+#
+# Date and time column types
+# (DATE, DATETIME, TIMESTAMP, TIME, YEAR)
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  d DATE $extra_col_opts,
+  dt DATETIME $extra_col_opts,
+  ts TIMESTAMP $extra_col_opts,
+  t TIME $extra_col_opts,
+  y YEAR $extra_col_opts,
+  y4 YEAR(4) $extra_col_opts,
+  y2 YEAR(2) $extra_col_opts,
+  pk DATETIME PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+SET @tm = '2012-04-09 05:27:00';
+
+# Valid values 
+# '1970-01-01 00:00:01'
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('1000-01-01', '1000-01-01 00:00:00', FROM_UNIXTIME(1), '-838:59:59', '1901', '1901', '00','2012-12-12 12:12:12'),
+('9999-12-31', '9999-12-31 23:59:59', FROM_UNIXTIME(2147483647), '838:59:59', '2155', '2155', '99','2012-12-12 12:12:13'),
+('0000-00-00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '00:00:00', '0', '0', '0','2012-12-12 12:12:14'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),YEAR(@tm),YEAR(@tm),'2012-12-12 12:12:15'); 
+
+--sorted_result
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+
+# Invalid values
+
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('999-13-32', '999-11-31 00:00:00', '0', '-839:00:00', '1900', '1900', '-1','2012-12-12 12:12:16');
+
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/type_date_time.result b/mysql-test/suite/leveldb/type_date_time.result
new file mode 100644
index 0000000..f53ceed
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_date_time.result
@@ -0,0 +1,53 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DATE ,
+dt DATETIME ,
+ts TIMESTAMP ,
+t TIME ,
+y YEAR ,
+y4 YEAR(4) ,
+y2 YEAR(2) ,
+pk DATETIME PRIMARY KEY
+) ENGINE=LevelDB;
+Warnings:
+Warning	1818	YEAR(2) column type is deprecated. Creating YEAR(4) column instead.
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	date	YES		NULL	
+dt	datetime	YES		NULL	
+ts	timestamp	YES		NULL	
+t	time	YES		NULL	
+y	year(4)	YES		NULL	
+y4	year(4)	YES		NULL	
+y2	year(4)	YES		NULL	
+pk	datetime	NO	PRI	NULL	
+SET @tm = '2012-04-09 05:27:00';
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('1000-01-01', '1000-01-01 00:00:00', FROM_UNIXTIME(1), '-838:59:59', '1901', '1901', '00','2012-12-12 12:12:12'),
+('9999-12-31', '9999-12-31 23:59:59', FROM_UNIXTIME(2147483647), '838:59:59', '2155', '2155', '99','2012-12-12 12:12:13'),
+('0000-00-00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '00:00:00', '0', '0', '0','2012-12-12 12:12:14'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),YEAR(@tm),YEAR(@tm),'2012-12-12 12:12:15');
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+d	dt	ts	t	y	y4	y2
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	00:00:00	2000	2000	2000
+1000-01-01	1000-01-01 00:00:00	1970-01-01 03:00:01	-838:59:59	1901	1901	2000
+2012-04-09	2012-04-09 05:27:00	2012-04-09 05:27:00	05:27:00	2012	2012	2012
+9999-12-31	9999-12-31 23:59:59	2038-01-19 06:14:07	838:59:59	2155	2155	1999
+INSERT INTO t1 (d,dt,ts,t,y,y4,y2,pk) VALUES
+('999-13-32', '999-11-31 00:00:00', '0', '-839:00:00', '1900', '1900', '-1','2012-12-12 12:12:16');
+Warnings:
+Warning	1265	Data truncated for column 'd' at row 1
+Warning	1264	Out of range value for column 'dt' at row 1
+Warning	1264	Out of range value for column 'ts' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 'y' at row 1
+Warning	1264	Out of range value for column 'y4' at row 1
+Warning	1264	Out of range value for column 'y2' at row 1
+SELECT d,dt,ts,t,y,y4,y2 FROM t1;
+d	dt	ts	t	y	y4	y2
+1000-01-01	1000-01-01 00:00:00	1970-01-01 03:00:01	-838:59:59	1901	1901	2000
+9999-12-31	9999-12-31 23:59:59	2038-01-19 06:14:07	838:59:59	2155	2155	1999
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	00:00:00	2000	2000	2000
+2012-04-09	2012-04-09 05:27:00	2012-04-09 05:27:00	05:27:00	2012	2012	2012
+0000-00-00	0000-00-00 00:00:00	0000-00-00 00:00:00	-838:59:59	0000	0000	0000
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_date_time.test b/mysql-test/suite/leveldb/type_date_time.test
new file mode 100644
index 0000000..0ca9e6b
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_date_time.test
@@ -0,0 +1,7 @@
+#
+# Date and time column types
+# (DATE, DATETIME, TIMESTAMP, TIME, YEAR)
+#
+
+--source type_date_time.inc
+
diff --git a/mysql-test/suite/leveldb/type_date_time_indexes.result b/mysql-test/suite/leveldb/type_date_time_indexes.result
new file mode 100644
index 0000000..692d86b
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_date_time_indexes.result
@@ -0,0 +1,126 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DATE,
+dt DATETIME PRIMARY KEY,
+ts TIMESTAMP,
+t TIME,
+y YEAR
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	dt	A	NULL	NULL	NULL		BTREE		
+SET @tm = '2012-04-09 05:27:00';
+INSERT INTO t1 (d,dt,ts,t,y) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm));
+EXPLAIN SELECT dt FROM t1 ORDER BY dt LIMIT 3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	5	NULL	3	Using index
+SELECT dt FROM t1 ORDER BY dt LIMIT 3;
+dt
+2010-11-22 11:43:14
+2010-11-22 12:33:54
+2011-08-27 21:33:56
+EXPLAIN SELECT dt FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY dt LIMIT 3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	5	NULL	3	Using index
+SELECT dt FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY dt LIMIT 3;
+dt
+2010-11-22 11:43:14
+2010-11-22 12:33:54
+2011-08-27 21:33:56
+INSERT INTO t1 (d,dt,ts,t,y) VALUES
+('2012-01-11', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000');
+ERROR 23000: Duplicate entry '2010-11-22 12:33:54' for key 'PRIMARY'
+DROP TABLE t1;
+CREATE TABLE t1 (
+d DATE,
+dt DATETIME,
+ts TIMESTAMP,
+t TIME,
+y YEAR,
+pk TIME PRIMARY KEY,
+INDEX (ts)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	ts	1	ts	A	NULL	NULL	NULL	YES	BTREE		
+SET @tm = '2012-04-09 05:27:00';
+INSERT INTO t1 (d,dt,ts,t,y,pk) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000','12:00:00'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001','12:01:00'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999','12:02:00'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998','12:03:00'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994','12:04:00'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),'12:05:00');
+EXPLAIN SELECT ts FROM t1 WHERE ts > NOW();
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	ts	ts	5	NULL	10	Using where
+SELECT ts FROM t1 WHERE ts > NOW();
+ts
+EXPLAIN SELECT ts FROM t1 USE INDEX () WHERE ts > NOW();
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using where
+SELECT ts FROM t1 USE INDEX () WHERE ts > NOW();
+ts
+DROP TABLE t1;
+CREATE TABLE t1 (
+d DATE,
+dt DATETIME,
+ts TIMESTAMP,
+t TIME,
+y YEAR,
+pk YEAR PRIMARY KEY,
+UNIQUE INDEX d_t (d,t)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (
+d DATE,
+dt DATETIME,
+ts TIMESTAMP,
+t TIME,
+y YEAR,
+pk TIME PRIMARY KEY,
+INDEX (y,t)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	y	1	y	A	NULL	NULL	NULL	YES	BTREE		
+t1	1	y	2	t	A	NULL	NULL	NULL	YES	BTREE		
+SET @tm = '2012-04-09 05:27:00';
+INSERT INTO t1 (d,dt,ts,t,y,pk) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000','18:18:18'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001','19:18:18'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999','20:18:18'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998','21:18:18'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994','22:18:18'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),'23:18:18');
+EXPLAIN SELECT y, COUNT(*) FROM t1 GROUP BY y;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary; Using filesort
+SELECT y, COUNT(*) FROM t1 GROUP BY y;
+y	COUNT(*)
+1994	1
+1998	1
+1999	1
+2000	1
+2001	1
+2012	1
+EXPLAIN SELECT y, COUNT(*) FROM t1 USE INDEX FOR GROUP BY () GROUP BY y;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary; Using filesort
+SELECT y, COUNT(*) FROM t1 USE INDEX FOR GROUP BY () GROUP BY y;
+y	COUNT(*)
+1994	1
+1998	1
+1999	1
+2000	1
+2001	1
+2012	1
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_date_time_indexes.test b/mysql-test/suite/leveldb/type_date_time_indexes.test
new file mode 100644
index 0000000..25da1e1
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_date_time_indexes.test
@@ -0,0 +1,143 @@
+#
+# Date and time columns with indexes
+# (DATE, DATETIME, TIMESTAMP, TIME, YEAR)
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+
+CREATE TABLE t1 (
+  d DATE,
+  dt DATETIME PRIMARY KEY,
+  ts TIMESTAMP,
+  t TIME,
+  y YEAR
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+SET @tm = '2012-04-09 05:27:00';
+
+INSERT INTO t1 (d,dt,ts,t,y) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm)); 
+
+EXPLAIN SELECT dt FROM t1 ORDER BY dt LIMIT 3;
+SELECT dt FROM t1 ORDER BY dt LIMIT 3;
+
+EXPLAIN SELECT dt FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY dt LIMIT 3;
+SELECT dt FROM t1 FORCE INDEX FOR ORDER BY (PRIMARY) ORDER BY dt LIMIT 3;
+
+--error ER_DUP_ENTRY
+INSERT INTO t1 (d,dt,ts,t,y) VALUES
+('2012-01-11', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000');
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+  d DATE,
+  dt DATETIME,
+  ts TIMESTAMP,
+  t TIME,
+  y YEAR,
+  pk TIME PRIMARY KEY,
+  INDEX (ts)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+SET @tm = '2012-04-09 05:27:00';
+
+INSERT INTO t1 (d,dt,ts,t,y,pk) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000','12:00:00'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001','12:01:00'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999','12:02:00'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998','12:03:00'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994','12:04:00'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),'12:05:00');
+
+EXPLAIN SELECT ts FROM t1 WHERE ts > NOW();
+--sorted_result
+SELECT ts FROM t1 WHERE ts > NOW();
+
+EXPLAIN SELECT ts FROM t1 USE INDEX () WHERE ts > NOW();
+--sorted_result
+SELECT ts FROM t1 USE INDEX () WHERE ts > NOW();
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  d DATE,
+  dt DATETIME,
+  ts TIMESTAMP,
+  t TIME,
+  y YEAR,
+  pk YEAR PRIMARY KEY,
+  UNIQUE INDEX d_t (d,t)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+SET @tm = '2012-04-09 05:27:00';
+
+INSERT INTO t1 (d,dt,ts,t,y,pk) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000','1990'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001','1991'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999','1992'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998','1993'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994','1994'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),'1995');
+
+EXPLAIN SELECT d, t FROM t1 WHERE CONCAT(d,' ',t) != CURRENT_DATE();
+--sorted_result
+SELECT d, t FROM t1 WHERE CONCAT(d,' ',t) != CURRENT_DATE();
+
+EXPLAIN SELECT d, t FROM t1 IGNORE INDEX (d_t) WHERE CONCAT(d,' ',t) != CURRENT_DATE();
+--sorted_result
+SELECT d, t FROM t1 IGNORE INDEX (d_t) WHERE CONCAT(d,' ',t) != CURRENT_DATE();
+
+--error ER_DUP_ENTRY
+INSERT INTO t1 (d,dt,ts,t,y) VALUES
+('2012-01-12', '2010-11-22 12:33:53', '2011-11-14 21:45:55', '00:12:33', '2000');
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  d DATE,
+  dt DATETIME,
+  ts TIMESTAMP,
+  t TIME,
+  y YEAR,
+  pk TIME PRIMARY KEY,
+  INDEX (y,t)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+SET @tm = '2012-04-09 05:27:00';
+
+INSERT INTO t1 (d,dt,ts,t,y,pk) VALUES
+('2012-01-12', '2010-11-22 12:33:54', '2011-11-14 21:45:55', '00:12:33', '2000','18:18:18'),
+('2012-01-12', '2010-11-22 11:43:14', '2011-11-14 21:45:55', '00:12:32', '2001','19:18:18'),
+('2012-03-31', '2011-08-28 21:33:56', '1999-04-30 19:11:08', '12:00:00', '1999','20:18:18'),
+('2012-03-13', '2011-08-27 21:33:56', '1999-03-30 19:11:08', '12:10:00', '1998','21:18:18'),
+('2011-03-31', '2011-08-28 20:33:56', '1997-01-31 11:54:01', '22:04:10', '1994','22:18:18'),
+(DATE(@tm), at tm,TIMESTAMP(@tm),TIME(@tm),YEAR(@tm),'23:18:18');
+
+EXPLAIN SELECT y, COUNT(*) FROM t1 GROUP BY y;
+--sorted_result
+SELECT y, COUNT(*) FROM t1 GROUP BY y;
+
+EXPLAIN SELECT y, COUNT(*) FROM t1 USE INDEX FOR GROUP BY () GROUP BY y;
+--sorted_result
+SELECT y, COUNT(*) FROM t1 USE INDEX FOR GROUP BY () GROUP BY y;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_enum.inc b/mysql-test/suite/leveldb/type_enum.inc
new file mode 100644
index 0000000..5bce2bb
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_enum.inc
@@ -0,0 +1,50 @@
+#
+# ENUM column type
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Valid values.
+# We cannot test the maximum of 65,536 here,
+# because mysqltest has the standard limit of MAX_QUERY=256K;
+# but we can at least try 257
+
+eval CREATE TABLE t1 (
+  a ENUM('') $extra_col_opts,
+  b ENUM('test1','test2','test3','test4','test5') $extra_col_opts,
+  c ENUM('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','
 5o','5p'
 ,'5q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75') $extra_col_opts,
+  PRIMARY KEY (b)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b,c) VALUES ('','test2','4'),('',5,2);
+SELECT a,b,c FROM t1;
+
+# Out of range values 
+# (should produce warnings)
+
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+--sorted_result
+SELECT a,b,c FROM t1;
+
+# Non-unique values in enum
+# (should produce a warning)
+eval ALTER TABLE t1 ADD COLUMN e ENUM('a','A') $extra_col_opts;
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b,c,e) VALUES ('','test3','75','A');
+--sorted_result
+SELECT a,b,c,e FROM t1;
+
+# Simple comparison
+
+--sorted_result
+SELECT a,b,c,e FROM t1 WHERE b='test2' OR a != '';
+
+DROP TABLE t1;
+
+
+
diff --git a/mysql-test/suite/leveldb/type_enum.result b/mysql-test/suite/leveldb/type_enum.result
new file mode 100644
index 0000000..51e51e3
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_enum.result
@@ -0,0 +1,47 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a ENUM('') ,
+b ENUM('test1','test2','test3','test4','test5') ,
+c ENUM('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o
 ','5p','
 5q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75') ,
+PRIMARY KEY (b)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	enum('')	YES		NULL	
+b	enum('test1','test2','test3','test4','test5')	NO	PRI	test1	
+c	enum('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o'
 ,'5p','5
 q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75')	YES		NULL	
+INSERT INTO t1 (a,b,c) VALUES ('','test2','4'),('',5,2);
+SELECT a,b,c FROM t1;
+a	b	c
+	test2	4
+	test5	2
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+Warnings:
+Warning	1265	Data truncated for column 'a' at row 1
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+		
+	test2	4
+	test5	2
+ALTER TABLE t1 ADD COLUMN e ENUM('a','A') ;
+Warnings:
+Note	1291	Column 'e' has duplicated value 'a' in ENUM
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	enum('')	YES		NULL	
+b	enum('test1','test2','test3','test4','test5')	NO	PRI	test1	
+c	enum('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i','3j','3k','3l','3m','3n','3o','3p','3q','3r','3s','3t','3u','3v','3w','3x','3y','3z','40','41','42','43','44','45','46','47','48','49','4a','4b','4c','4d','4e','4f','4g','4h','4i','4j','4k','4l','4m','4n','4o','4p','4q','4r','4s','4t','4u','4v','4w','4x','4y','4z','50','51','52','53','54','55','56','57','58','59','5a','5b','5c','5d','5e','5f','5g','5h','5i','5j','5k','5l','5m','5n','5o'
 ,'5p','5
 q','5r','5s','5t','5u','5v','5w','5x','5y','5z','60','61','62','63','64','65','66','67','68','69','6a','6b','6c','6d','6e','6f','6g','6h','6i','6j','6k','6l','6m','6n','6o','6p','6q','6r','6s','6t','6u','6v','6w','6x','6y','6z','70','71','72','73','74','75')	YES		NULL	
+e	enum('a','A')	YES		NULL	
+INSERT INTO t1 (a,b,c,e) VALUES ('','test3','75','A');
+SELECT a,b,c,e FROM t1;
+a	b	c	e
+			NULL
+	test2	4	NULL
+	test3	75	a
+	test5	2	NULL
+SELECT a,b,c,e FROM t1 WHERE b='test2' OR a != '';
+a	b	c	e
+	test2	4	NULL
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_enum.test b/mysql-test/suite/leveldb/type_enum.test
new file mode 100644
index 0000000..a527195
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_enum.test
@@ -0,0 +1,6 @@
+#
+# ENUM column type
+#
+
+--source type_enum.inc
+
diff --git a/mysql-test/suite/leveldb/type_enum_indexes.result b/mysql-test/suite/leveldb/type_enum_indexes.result
new file mode 100644
index 0000000..d794b69
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_enum_indexes.result
@@ -0,0 +1,74 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a ENUM('N.America','S.America','Africa','Europe','Australia','Asia','Antarctica'),
+b ENUM('test1','test2','test3','test4','test5'),
+c ENUM('1a','1b','1d','1j','4a','4z','5a','5b','6v','6z'),
+pk ENUM('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+UNIQUE KEY a_b (a,b)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (
+a ENUM('N.America','S.America','Africa','Europe','Australia','Asia','Antarctica'),
+b ENUM('test1','test2','test3','test4','test5'),
+c ENUM('1a','1b','1d','1j','4a','4z','5a','5b','6v','6z') PRIMARY KEY
+) ENGINE=LevelDB;
+INSERT INTO t1 (a,b,c) VALUES
+('N.America','test1','5a'),('Europe','test1','5b'),('Europe','test2','6v'),
+('Africa','test3','4z'),('Africa','test4','1j'),('Antarctica','test4','1d');
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	c	A	NULL	NULL	NULL		BTREE		
+EXPLAIN SELECT c FROM t1 WHERE c BETWEEN '1d' AND '6u';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	PRIMARY	PRIMARY	1	NULL	1000	Using where; Using index
+SELECT c FROM t1 WHERE c BETWEEN '1d' AND '6u';
+c
+1d
+1j
+4z
+5a
+5b
+EXPLAIN SELECT c FROM t1 USE INDEX () WHERE c BETWEEN '1d' AND '6u';
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using where
+SELECT c FROM t1 USE INDEX () WHERE c BETWEEN '1d' AND '6u';
+c
+1d
+1j
+4z
+5a
+5b
+DROP TABLE t1;
+CREATE TABLE t1 (
+a ENUM('N.America','S.America','Africa','Europe','Australia','Asia','Antarctica'),
+b ENUM('test1','test2','test3','test4','test5'),
+c ENUM('1a','1b','1d','1j','4a','4z','5a','5b','6v','6z'),
+pk ENUM('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+INDEX(b)
+) ENGINE=LevelDB;
+INSERT INTO t1 (a,b,c,pk) VALUES
+('N.America','test1','5a',1),('Europe','test1','5b',2),('Europe','test2','6v',3),
+('Africa','test3','4z',4),('Africa','test4','1j',5),('Antarctica','test4','1d',6);
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	b	1	b	A	NULL	NULL	NULL	YES	BTREE		
+EXPLAIN SELECT DISTINCT b FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary
+SELECT DISTINCT b FROM t1;
+b
+test1
+test2
+test3
+test4
+EXPLAIN SELECT DISTINCT b FROM t1 IGNORE INDEX (b);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary
+SELECT DISTINCT b FROM t1 IGNORE INDEX (b);
+b
+test1
+test2
+test3
+test4
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_enum_indexes.test b/mysql-test/suite/leveldb/type_enum_indexes.test
new file mode 100644
index 0000000..9ed41af
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_enum_indexes.test
@@ -0,0 +1,81 @@
+#
+# ENUM columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  a ENUM('N.America','S.America','Africa','Europe','Australia','Asia','Antarctica'),
+  b ENUM('test1','test2','test3','test4','test5'),
+  c ENUM('1a','1b','1d','1j','4a','4z','5a','5b','6v','6z'),
+  pk ENUM('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+  UNIQUE KEY a_b (a,b)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+INSERT INTO t1 (a,b,c,pk) VALUES
+('N.America','test1','5a',1),('Europe','test1','5b',2),('Europe','test2','6v',3),
+('Africa','test3','4z',4),('Africa','test4','1j',5),('Antarctica','test4','1d',6);
+
+SHOW INDEX IN t1;
+
+EXPLAIN SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
+SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
+
+EXPLAIN SELECT a FROM t1 FORCE INDEX (a_b) WHERE b > 'test2' ORDER BY a;
+SELECT a FROM t1 FORCE INDEX (a_b) WHERE b > 'test2' ORDER BY a;
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  a ENUM('N.America','S.America','Africa','Europe','Australia','Asia','Antarctica'),
+  b ENUM('test1','test2','test3','test4','test5'),
+  c ENUM('1a','1b','1d','1j','4a','4z','5a','5b','6v','6z') PRIMARY KEY
+) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b,c) VALUES
+('N.America','test1','5a'),('Europe','test1','5b'),('Europe','test2','6v'),
+('Africa','test3','4z'),('Africa','test4','1j'),('Antarctica','test4','1d');
+
+SHOW INDEX IN t1;
+
+EXPLAIN SELECT c FROM t1 WHERE c BETWEEN '1d' AND '6u';
+--sorted_result
+SELECT c FROM t1 WHERE c BETWEEN '1d' AND '6u';
+
+EXPLAIN SELECT c FROM t1 USE INDEX () WHERE c BETWEEN '1d' AND '6u';
+--sorted_result
+SELECT c FROM t1 USE INDEX () WHERE c BETWEEN '1d' AND '6u';
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+  a ENUM('N.America','S.America','Africa','Europe','Australia','Asia','Antarctica'),
+  b ENUM('test1','test2','test3','test4','test5'),
+  c ENUM('1a','1b','1d','1j','4a','4z','5a','5b','6v','6z'),
+  pk ENUM('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+  INDEX(b)
+) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b,c,pk) VALUES
+('N.America','test1','5a',1),('Europe','test1','5b',2),('Europe','test2','6v',3),
+('Africa','test3','4z',4),('Africa','test4','1j',5),('Antarctica','test4','1d',6);
+
+SHOW INDEX IN t1;
+
+EXPLAIN SELECT DISTINCT b FROM t1;
+--sorted_result
+SELECT DISTINCT b FROM t1;
+
+EXPLAIN SELECT DISTINCT b FROM t1 IGNORE INDEX (b);
+--sorted_result
+SELECT DISTINCT b FROM t1 IGNORE INDEX (b);
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_fixed.inc b/mysql-test/suite/leveldb/type_fixed.inc
new file mode 100644
index 0000000..138fe97
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_fixed.inc
@@ -0,0 +1,85 @@
+#
+# Fixed point types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  d DECIMAL $extra_col_opts,
+  d0 DECIMAL(0) $extra_col_opts,
+  d1_1 DECIMAL(1,1) $extra_col_opts,
+  d10_2 DECIMAL(10,2) $extra_col_opts,
+  d60_10 DECIMAL(60,10) $extra_col_opts,
+  n NUMERIC $extra_col_opts,
+  n0_0 NUMERIC(0,0) $extra_col_opts,
+  n1 NUMERIC(1) $extra_col_opts,
+  n20_4 NUMERIC(20,4) $extra_col_opts,
+  n65_4 NUMERIC(65,4) $extra_col_opts,
+  pk NUMERIC $extra_col_opts PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Always valid values 
+
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (100,123456,0.3,40000.25,123456789123456789.10001,1024,7000.0,8.0,999999.9,9223372036854775807,1);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.0,9999999999.0,0.9,99999999.99,99999999999999999999999999999999999999999999999999.9999999999,9999999999.0,9999999999.0,9.0,9999999999999999.9999,9999999999999999999999999999999999999999999999999999999999999.9999,3);
+
+--sorted_result
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+
+# Values which can be valid or not, 
+# depending on whether columns are SIGNED or UNSIGNED
+# (if not valid should produce warnings)
+
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-100,-123456,-0.3,-40000.25,-123456789123456789.10001,-1024,-7000.0,-8.0,-999999.9,-9223372036854775807,4);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-9999999999.0,-9999999999.0,-0.9,-99999999.99,-99999999999999999999999999999999999999999999999999.9999999999,-9999999999.0,-9999999999.0,-9.0,-9999999999999999.9999,-9999999999999999999999999999999999999999999999999999999999999.9999,5);
+
+--sorted_result
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+
+--sorted_result
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1 WHERE n20_4 = 9999999999999999.9999 OR d < 100;
+
+# Invalid values
+
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  6
+);
+
+--sorted_result
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (10000000000.0,10000000000.0,1.1,100000000.99,100000000000000000000000000000000000000000000000000.0,10000000000.0,10000000000.0,10.0,10000000000000000.9999,10000000000000000000000000000000000000000000000000000000000000.9999,7);
+--sorted_result
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.1,9999999999.1,1.9,99999999.001,99999999999999999999999999999999999999999999999999.99999999991,9999999999.1,9999999999.1,9.1,9999999999999999.00001,9999999999999999999999999999999999999999999999999999999999999.11111,8);
+--sorted_result
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+
+--error ER_TOO_BIG_PRECISION
+eval ALTER TABLE t1 ADD COLUMN n66 NUMERIC(66) $extra_col_opts;
+
+--error ER_TOO_BIG_PRECISION
+eval ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(66,6) $extra_col_opts;
+
+--error ER_TOO_BIG_SCALE
+eval ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(66,66) $extra_col_opts;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/suite/leveldb/type_fixed.result b/mysql-test/suite/leveldb/type_fixed.result
new file mode 100644
index 0000000..0c0ed90
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_fixed.result
@@ -0,0 +1,131 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d DECIMAL ,
+d0 DECIMAL(0) ,
+d1_1 DECIMAL(1,1) ,
+d10_2 DECIMAL(10,2) ,
+d60_10 DECIMAL(60,10) ,
+n NUMERIC ,
+n0_0 NUMERIC(0,0) ,
+n1 NUMERIC(1) ,
+n20_4 NUMERIC(20,4) ,
+n65_4 NUMERIC(65,4) ,
+pk NUMERIC  PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+d	decimal(10,0)	YES		NULL	
+d0	decimal(10,0)	YES		NULL	
+d1_1	decimal(1,1)	YES		NULL	
+d10_2	decimal(10,2)	YES		NULL	
+d60_10	decimal(60,10)	YES		NULL	
+n	decimal(10,0)	YES		NULL	
+n0_0	decimal(10,0)	YES		NULL	
+n1	decimal(1,0)	YES		NULL	
+n20_4	decimal(20,4)	YES		NULL	
+n65_4	decimal(65,4)	YES		NULL	
+pk	decimal(10,0)	NO	PRI	NULL	
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (100,123456,0.3,40000.25,123456789123456789.10001,1024,7000.0,8.0,999999.9,9223372036854775807,1);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.0,9999999999.0,0.9,99999999.99,99999999999999999999999999999999999999999999999999.9999999999,9999999999.0,9999999999.0,9.0,9999999999999999.9999,9999999999999999999999999999999999999999999999999999999999999.9999,3);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-100,-123456,-0.3,-40000.25,-123456789123456789.10001,-1024,-7000.0,-8.0,-999999.9,-9223372036854775807,4);
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (-9999999999.0,-9999999999.0,-0.9,-99999999.99,-99999999999999999999999999999999999999999999999999.9999999999,-9999999999.0,-9999999999.0,-9.0,-9999999999999999.9999,-9999999999999999999999999999999999999999999999999999999999999.9999,5);
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1 WHERE n20_4 = 9999999999999999.9999 OR d < 100;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+6
+);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (10000000000.0,10000000000.0,1.1,100000000.99,100000000000000000000000000000000000000000000000000.0,10000000000.0,10000000000.0,10.0,10000000000000000.9999,10000000000000000000000000000000000000000000000000000000000000.9999,7);
+Warnings:
+Warning	1264	Out of range value for column 'd' at row 1
+Warning	1264	Out of range value for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Warning	1264	Out of range value for column 'd10_2' at row 1
+Warning	1264	Out of range value for column 'd60_10' at row 1
+Warning	1264	Out of range value for column 'n' at row 1
+Warning	1264	Out of range value for column 'n0_0' at row 1
+Warning	1264	Out of range value for column 'n1' at row 1
+Warning	1264	Out of range value for column 'n20_4' at row 1
+Warning	1264	Out of range value for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+INSERT INTO t1 (d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4,pk) VALUES (9999999999.1,9999999999.1,1.9,99999999.001,99999999999999999999999999999999999999999999999999.99999999991,9999999999.1,9999999999.1,9.1,9999999999999999.00001,9999999999999999999999999999999999999999999999999999999999999.11111,8);
+Warnings:
+Note	1265	Data truncated for column 'd' at row 1
+Note	1265	Data truncated for column 'd0' at row 1
+Warning	1264	Out of range value for column 'd1_1' at row 1
+Note	1265	Data truncated for column 'd10_2' at row 1
+Note	1265	Data truncated for column 'd60_10' at row 1
+Note	1265	Data truncated for column 'n' at row 1
+Note	1265	Data truncated for column 'n0_0' at row 1
+Note	1265	Data truncated for column 'n1' at row 1
+Note	1265	Data truncated for column 'n20_4' at row 1
+Note	1265	Data truncated for column 'n65_4' at row 1
+SELECT d,d0,d1_1,d10_2,d60_10,n,n0_0,n1,n20_4,n65_4 FROM t1;
+d	d0	d1_1	d10_2	d60_10	n	n0_0	n1	n20_4	n65_4
+-100	-123456	-0.3	-40000.25	-123456789123456789.1000100000	-1024	-7000	-8	-999999.9000	-9223372036854775807.0000
+-9999999999	-9999999999	-0.9	-99999999.99	-99999999999999999999999999999999999999999999999999.9999999999	-9999999999	-9999999999	-9	-9999999999999999.9999	-9999999999999999999999999999999999999999999999999999999999999.9999
+0	0	0.0	0.00	0.0000000000	0	0	0	0.0000	0.0000
+100	123456	0.3	40000.25	123456789123456789.1000100000	1024	7000	8	999999.9000	9223372036854775807.0000
+9999999999	9999999999	0.9	99999999.00	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.0000	9999999999999999999999999999999999999999999999999999999999999.1111
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+9999999999	9999999999	0.9	99999999.99	99999999999999999999999999999999999999999999999999.9999999999	9999999999	9999999999	9	9999999999999999.9999	9999999999999999999999999999999999999999999999999999999999999.9999
+ALTER TABLE t1 ADD COLUMN n66 NUMERIC(66) ;
+ERROR 42000: Too big precision 66 specified for column 'n66'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(66,6) ;
+ERROR 42000: Too big precision 66 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(66,66) ;
+ERROR 42000: Too big scale 66 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_fixed.test b/mysql-test/suite/leveldb/type_fixed.test
new file mode 100644
index 0000000..2e486e2
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_fixed.test
@@ -0,0 +1,6 @@
+#
+# Fixed point types
+#
+
+--source type_fixed.inc
+
diff --git a/mysql-test/suite/leveldb/type_fixed_indexes.result b/mysql-test/suite/leveldb/type_fixed_indexes.result
new file mode 100644
index 0000000..33a4085
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_fixed_indexes.result
@@ -0,0 +1,99 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+d1 DECIMAL(10,2) PRIMARY KEY,
+d2 DECIMAL(60,10),
+n1 NUMERIC,
+n2 NUMERIC(65,4)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	d1	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (d1,d2,n1,n2) VALUES 
+(10.22,60.12345,123456,14.3456),
+(10.0,60.12345,123456,14),
+(11.14,15,123456,13),
+(100,100,1,2),
+(0,0,0,0),
+(4540424564.23,3343303441.0,12,13),
+(15,17,23,100000);
+Warnings:
+Warning	1264	Out of range value for column 'd1' at row 6
+EXPLAIN SELECT d1 FROM t1 ORDER BY d1 DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	5	NULL	1000	Using index
+SELECT d1 FROM t1 ORDER BY d1 DESC;
+d1
+99999999.99
+100.00
+15.00
+11.14
+10.22
+10.00
+0.00
+EXPLAIN SELECT d1 FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY d1 DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	5	NULL	1000	Using index; Using filesort
+SELECT d1 FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY d1 DESC;
+d1
+99999999.99
+100.00
+15.00
+11.14
+10.22
+10.00
+0.00
+DROP TABLE t1;
+CREATE TABLE t1 (
+d1 DECIMAL(10,2),
+d2 DECIMAL(60,10),
+n1 NUMERIC,
+n2 NUMERIC(65,4),
+pk NUMERIC PRIMARY KEY,
+UNIQUE INDEX n1_n2 (n1,n2)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (
+d1 DECIMAL(10,2),
+d2 DECIMAL(60,10),
+n1 NUMERIC,
+n2 NUMERIC(65,4),
+pk DECIMAL(20,10) PRIMARY KEY,
+INDEX (d2)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	d2	1	d2	A	NULL	NULL	NULL	YES	BTREE		
+INSERT INTO t1 (d1,d2,n1,n2,pk) VALUES
+(10.22,60.12345,123456,14.3456,1),
+(10.0,60.12345,123456,14,2),
+(11.14,15,123456,13,3),
+(100,100,1,2,4),
+(0,0,0,0,5),
+(4540424564.23,3343303441.0,12,13,6),
+(15,17,23,100000,7);
+Warnings:
+Warning	1264	Out of range value for column 'd1' at row 6
+EXPLAIN SELECT d2, COUNT(*) FROM t1 GROUP BY d2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary; Using filesort
+SELECT d2, COUNT(*) FROM t1 GROUP BY d2;
+d2	COUNT(*)
+0.0000000000	1
+100.0000000000	1
+15.0000000000	1
+17.0000000000	1
+3343303441.0000000000	1
+60.1234500000	2
+EXPLAIN SELECT d2, COUNT(*) FROM t1 IGNORE INDEX FOR GROUP BY (d2) GROUP BY d2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary; Using filesort
+SELECT d2, COUNT(*) FROM t1 IGNORE INDEX FOR GROUP BY (d2) GROUP BY d2;
+d2	COUNT(*)
+0.0000000000	1
+100.0000000000	1
+15.0000000000	1
+17.0000000000	1
+3343303441.0000000000	1
+60.1234500000	2
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_fixed_indexes.test b/mysql-test/suite/leveldb/type_fixed_indexes.test
new file mode 100644
index 0000000..475bffa
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_fixed_indexes.test
@@ -0,0 +1,96 @@
+#
+# Fixed point columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+
+CREATE TABLE t1 (
+  d1 DECIMAL(10,2) PRIMARY KEY,
+  d2 DECIMAL(60,10),
+  n1 NUMERIC,
+  n2 NUMERIC(65,4)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (d1,d2,n1,n2) VALUES 
+(10.22,60.12345,123456,14.3456),
+(10.0,60.12345,123456,14),
+(11.14,15,123456,13),
+(100,100,1,2),
+(0,0,0,0),
+(4540424564.23,3343303441.0,12,13),
+(15,17,23,100000);
+
+EXPLAIN SELECT d1 FROM t1 ORDER BY d1 DESC;
+SELECT d1 FROM t1 ORDER BY d1 DESC;
+
+EXPLAIN SELECT d1 FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY d1 DESC;
+SELECT d1 FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY d1 DESC;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  d1 DECIMAL(10,2),
+  d2 DECIMAL(60,10),
+  n1 NUMERIC,
+  n2 NUMERIC(65,4),
+  pk NUMERIC PRIMARY KEY,
+  UNIQUE INDEX n1_n2 (n1,n2)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (d1,d2,n1,n2,pk) VALUES
+(10.22,60.12345,123456,14.3456,1),
+(10.0,60.12345,123456,14,2),
+(11.14,15,123456,13,3),
+(100,100,1,2,4),
+(0,0,0,0,5),
+(4540424564.23,3343303441.0,12,13,6),
+(15,17,23,100000,7);
+
+EXPLAIN SELECT DISTINCT n1+n2 FROM t1;
+--sorted_result
+SELECT DISTINCT n1+n2 FROM t1;
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  d1 DECIMAL(10,2),
+  d2 DECIMAL(60,10),
+  n1 NUMERIC,
+  n2 NUMERIC(65,4),
+  pk DECIMAL(20,10) PRIMARY KEY,
+  INDEX (d2)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (d1,d2,n1,n2,pk) VALUES
+(10.22,60.12345,123456,14.3456,1),
+(10.0,60.12345,123456,14,2),
+(11.14,15,123456,13,3),
+(100,100,1,2,4),
+(0,0,0,0,5),
+(4540424564.23,3343303441.0,12,13,6),
+(15,17,23,100000,7);
+
+EXPLAIN SELECT d2, COUNT(*) FROM t1 GROUP BY d2;
+--sorted_result
+SELECT d2, COUNT(*) FROM t1 GROUP BY d2;
+
+EXPLAIN SELECT d2, COUNT(*) FROM t1 IGNORE INDEX FOR GROUP BY (d2) GROUP BY d2;
+--sorted_result
+SELECT d2, COUNT(*) FROM t1 IGNORE INDEX FOR GROUP BY (d2) GROUP BY d2;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_float.inc b/mysql-test/suite/leveldb/type_float.inc
new file mode 100644
index 0000000..6efff6b
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_float.inc
@@ -0,0 +1,108 @@
+#
+# Float types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  f FLOAT $extra_col_opts,
+  f0 FLOAT(0) $extra_col_opts,
+  r1_1 REAL(1,1) $extra_col_opts,
+  f23_0 FLOAT(23) $extra_col_opts,
+  f20_3 FLOAT(20,3) $extra_col_opts,
+  d DOUBLE $extra_col_opts,
+  d1_0 DOUBLE(1,0) $extra_col_opts,
+  d10_10 DOUBLE PRECISION (10,10) $extra_col_opts,
+  d53 DOUBLE(53,0) $extra_col_opts,
+  d53_10 DOUBLE(53,10) $extra_col_opts,
+  pk DOUBLE $extra_col_opts PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Always valid values 
+
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1);
+
+--sorted_result
+--query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1
+
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+  99999999999999999999999999999999999999,
+  99999999999999999999999999999999999999.9999999999999999,
+  0.9,
+  99999999999999999999999999999999999999.9,
+  99999999999999999.999,
+  999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+  9,
+  0.9999999999, 
+  1999999999999999999999999999999999999999999999999999999,
+  19999999999999999999999999999999999999999999.9999999999,
+  3
+);
+
+--sorted_result
+--query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1
+
+# Values which can be valid or not, 
+# depending on whether columns are SIGNED or UNSIGNED
+# (if not valid should produce warnings)
+
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4);
+
+--sorted_result
+--query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1
+
+--sorted_result
+--query_vertical SELECT MAX(f), MAX(f0), MAX(r1_1), MAX(f23_0), MAX(f20_3), MAX(d), MAX(d1_0), MAX(d10_10), MAX(d53), MAX(d53_10) FROM t1
+
+# Invalid values
+
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  9999999999999999999999999999999999999999999999999999999999999.9999,
+  5
+);
+
+--sorted_result
+--query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1
+
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+  999999999999999999999999999999999999999,
+  999999999999999999999999999999999999999.9999999999999999,
+  1.9,
+  999999999999999999999999999999999999999.9,
+  999999999999999999.999,
+  9999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+  99,
+  1.9999999999,
+  1999999999999999999999999999999999999999999999999999999,
+  19999999999999999999999999999999999999999999.9999999999,
+  6
+);
+
+--sorted_result
+--query_vertical SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1
+
+--error ER_TOO_BIG_DISPLAYWIDTH
+eval ALTER TABLE t1 ADD COLUMN d0_0 DOUBLE(0,0) $extra_col_opts;
+
+--error ER_TOO_BIG_PRECISION
+eval ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(256,1) $extra_col_opts;
+
+--error ER_TOO_BIG_SCALE
+eval ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(40,35) $extra_col_opts;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_float.result b/mysql-test/suite/leveldb/type_float.result
new file mode 100644
index 0000000..490bf37
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_float.result
@@ -0,0 +1,306 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+f FLOAT ,
+f0 FLOAT(0) ,
+r1_1 REAL(1,1) ,
+f23_0 FLOAT(23) ,
+f20_3 FLOAT(20,3) ,
+d DOUBLE ,
+d1_0 DOUBLE(1,0) ,
+d10_10 DOUBLE PRECISION (10,10) ,
+d53 DOUBLE(53,0) ,
+d53_10 DOUBLE(53,10) ,
+pk DOUBLE  PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+f	float	YES		NULL	
+f0	float	YES		NULL	
+r1_1	double(1,1)	YES		NULL	
+f23_0	float	YES		NULL	
+f20_3	float(20,3)	YES		NULL	
+d	double	YES		NULL	
+d1_0	double(1,0)	YES		NULL	
+d10_10	double(10,10)	YES		NULL	
+d53	double(53,0)	YES		NULL	
+d53_10	double(53,10)	YES		NULL	
+pk	double	NO	PRI	NULL	
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (12345.12345,12345.12345,0.9,123456789.123,56789.987,11111111.111,8.0,0.0123456789,1234566789123456789,99999999999999999.99999999,1);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	11111111.111
+d10_10	0.0123456789
+d1_0	8
+d53	1234566789123456800
+d53_10	100000000000000000.0000000000
+f0	12345.1
+f20_3	56789.988
+f23_0	123457000
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (0,0,0,0,0,0,0,0,0,0,2);
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+99999999999999999999999999999999999999,
+99999999999999999999999999999999999999.9999999999999999,
+0.9,
+99999999999999999999999999999999999999.9,
+99999999999999999.999,
+999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+9,
+0.9999999999, 
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+3
+);
+Warnings:
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	0
+d	11111111.111
+d	1e81
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	0
+d1_0	8
+d1_0	9
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	0
+f	1e38
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (-999999999999999999999999,-99999999999.999999999999,-0.9,-999.99999999999999999999,-99999999999999999.999,-999999999999999999999999999999999999999999999999999999999999-0.999,-9,-.9999999999,-999999999999999999999999999999.99999999999999999999999,-9999999999999999999999999999999999999999999.9999999999,4);
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+SELECT MAX(f), MAX(f0), MAX(r1_1), MAX(f23_0), MAX(f20_3), MAX(d), MAX(d1_0), MAX(d10_10), MAX(d53), MAX(d53_10) FROM t1;
+MAX(f)	9.999999680285692e37
+MAX(d)	1e81
+MAX(d10_10)	0.9999999999
+MAX(d1_0)	9
+MAX(d53)	100000000000000000000000000000000000000000000000000000
+MAX(d53_10)	10000000000000000000000000000000000000000000.0000000000
+MAX(f0)	9.999999680285692e37
+MAX(f20_3)	99999998430674940.000
+MAX(f23_0)	9.999999680285692e37
+MAX(r1_1)	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+9999999999999999999999999999999999999999999999999999999999999.9999,
+5
+);
+Warnings:
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e61
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f	3.40282e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+INSERT INTO t1 (f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10,pk) VALUES (
+999999999999999999999999999999999999999,
+999999999999999999999999999999999999999.9999999999999999,
+1.9,
+999999999999999999999999999999999999999.9,
+999999999999999999.999,
+9999999999999999999999999999999999999999999999999999999999999999999999999999999999,
+99,
+1.9999999999,
+1999999999999999999999999999999999999999999999999999999,
+19999999999999999999999999999999999999999999.9999999999,
+6
+);
+Warnings:
+Warning	1292	Truncated incorrect DECIMAL value: ''
+Warning	1264	Out of range value for column 'f' at row 1
+Warning	1264	Out of range value for column 'f0' at row 1
+Warning	1264	Out of range value for column 'r1_1' at row 1
+Warning	1264	Out of range value for column 'f23_0' at row 1
+Warning	1264	Out of range value for column 'f20_3' at row 1
+Warning	1264	Out of range value for column 'd1_0' at row 1
+Warning	1264	Out of range value for column 'd10_10' at row 1
+Warning	1264	Out of range value for column 'd53' at row 1
+Warning	1264	Out of range value for column 'd53_10' at row 1
+SELECT f,f0,r1_1,f23_0,f20_3,d,d1_0,d10_10,d53,d53_10 FROM t1;
+f	12345.1
+d	-1e60
+d	0
+d	11111111.111
+d	1e61
+d	1e65
+d	1e81
+d10_10	-0.9999999999
+d10_10	0.0000000000
+d10_10	0.0123456789
+d10_10	0.9999999999
+d10_10	0.9999999999
+d10_10	0.9999999999
+d1_0	-9
+d1_0	0
+d1_0	8
+d1_0	9
+d1_0	9
+d1_0	9
+d53	-1000000000000000000000000000000
+d53	0
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	100000000000000000000000000000000000000000000000000000
+d53	1234566789123456800
+d53_10	-10000000000000000000000000000000000000000000.0000000000
+d53_10	0.0000000000
+d53_10	100000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+d53_10	10000000000000000000000000000000000000000000.0000000000
+f	-1e24
+f	0
+f	1e38
+f	3.40282e38
+f	3.40282e38
+f0	-100000000000
+f0	0
+f0	12345.1
+f0	1e38
+f0	3.40282e38
+f0	3.40282e38
+f20_3	-99999998430674940.000
+f20_3	0.000
+f20_3	56789.988
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f20_3	99999998430674940.000
+f23_0	-1000
+f23_0	0
+f23_0	123457000
+f23_0	1e38
+f23_0	3.40282e38
+f23_0	3.40282e38
+r1_1	-0.9
+r1_1	0.0
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+r1_1	0.9
+ALTER TABLE t1 ADD COLUMN d0_0 DOUBLE(0,0) ;
+ERROR 42000: Display width out of range for column 'd0_0' (max = 255)
+ALTER TABLE t1 ADD COLUMN n66_6 DECIMAL(256,1) ;
+ERROR 42000: Too big precision 256 specified for column 'n66_6'. Maximum is 65.
+ALTER TABLE t1 ADD COLUMN n66_66 DECIMAL(40,35) ;
+ERROR 42000: Too big scale 35 specified for column 'n66_66'. Maximum is 30.
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_float.test b/mysql-test/suite/leveldb/type_float.test
new file mode 100644
index 0000000..638effb
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_float.test
@@ -0,0 +1,6 @@
+#
+# Float types
+#
+
+--source type_float.inc
+
diff --git a/mysql-test/suite/leveldb/type_float_indexes.result b/mysql-test/suite/leveldb/type_float_indexes.result
new file mode 100644
index 0000000..33f628d
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_float_indexes.result
@@ -0,0 +1,75 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+f FLOAT PRIMARY KEY,
+r REAL(20,3),
+d DOUBLE,
+dp DOUBLE PRECISION (64,10)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	f	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (f,r,d,dp) VALUES
+(1.2345,1422.22,1.2345,1234567.89),
+(0,0,0,0),
+(-1,-1,-1,-1),
+(17.5843,4953453454.44,29229114.0,1111111.23),
+(4644,1422.22,466664.999,0.5);
+EXPLAIN SELECT f FROM t1 ORDER BY f;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	4	NULL	1000	Using index
+SELECT f FROM t1 ORDER BY f;
+f
+-1
+0
+1.2345
+17.5843
+4644
+EXPLAIN SELECT f FROM t1 IGNORE INDEX (PRIMARY) ORDER BY f;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using filesort
+SELECT f FROM t1 IGNORE INDEX (PRIMARY) ORDER BY f;
+f
+-1
+0
+1.2345
+17.5843
+4644
+DROP TABLE t1;
+CREATE TABLE t1 (
+f FLOAT,
+r REAL(20,3),
+d DOUBLE,
+dp DOUBLE PRECISION (64,10),
+pk DOUBLE PRIMARY KEY,
+UNIQUE KEY r_dp (r,dp)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (
+f FLOAT,
+r REAL(20,3),
+d DOUBLE,
+dp DOUBLE PRECISION (64,10),
+pk FLOAT PRIMARY KEY,
+KEY(d)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	d	1	d	A	NULL	NULL	NULL	YES	BTREE		
+INSERT INTO t1 (f,r,d,dp,pk) VALUES
+(1.2345,1422.22,1.2345,1234567.89,1),
+(0,0,0,0,2),
+(-1,-1,-1,-1,3),
+(17.5843,4953453454.44,29229114.0,1111111.23,4),
+(4644,1422.22,466664.999,0.5,5);
+EXPLAIN SELECT DISTINCT d FROM t1 ORDER BY d;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using temporary; Using filesort
+SELECT DISTINCT d FROM t1 ORDER BY d;
+d
+-1
+0
+1.2345
+466664.999
+29229114
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_float_indexes.test b/mysql-test/suite/leveldb/type_float_indexes.test
new file mode 100644
index 0000000..d51d52d
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_float_indexes.test
@@ -0,0 +1,107 @@
+#
+# Float type columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  f FLOAT PRIMARY KEY,
+  r REAL(20,3),
+  d DOUBLE,
+  dp DOUBLE PRECISION (64,10)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (f,r,d,dp) VALUES
+(1.2345,1422.22,1.2345,1234567.89),
+(0,0,0,0),
+(-1,-1,-1,-1),
+(17.5843,4953453454.44,29229114.0,1111111.23),
+(4644,1422.22,466664.999,0.5);
+
+EXPLAIN SELECT f FROM t1 ORDER BY f;
+SELECT f FROM t1 ORDER BY f;
+
+EXPLAIN SELECT f FROM t1 IGNORE INDEX (PRIMARY) ORDER BY f;
+SELECT f FROM t1 IGNORE INDEX (PRIMARY) ORDER BY f;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  f FLOAT,
+  r REAL(20,3),
+  d DOUBLE,
+  dp DOUBLE PRECISION (64,10),
+  pk DOUBLE PRIMARY KEY,
+  UNIQUE KEY r_dp (r,dp)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+  
+INSERT INTO t1 (f,r,d,dp,pk) VALUES
+(1.2345,1422.22,1.2345,1234567.89,1),
+(0,0,0,0,2),
+(-1,-1,-1,-1,3),
+(17.5843,4953453454.44,29229114.0,1111111.23,4),
+(4644,1422.22,466664.999,0.5,5);
+
+EXPLAIN SELECT r, dp FROM t1 WHERE r > 0 or dp > 0;
+--sorted_result
+SELECT r, dp FROM t1 WHERE r > 0 or dp > 0;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+  f FLOAT,
+  r REAL(20,3),
+  d DOUBLE,
+  dp DOUBLE PRECISION (64,10),
+  pk FLOAT PRIMARY KEY,
+  UNIQUE KEY(d)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (f,r,d,dp,pk) VALUES
+(1.2345,1422.22,1.2345,1234567.89,1),
+(0,0,0,0,2),
+(-1,-1,-1,-1,3),
+(17.5843,4953453454.44,29229114.0,1111111.23,4),
+(4644,1422.22,466664.999,0.5,5);
+
+EXPLAIN SELECT DISTINCT d FROM t1 ORDER BY d;
+SELECT DISTINCT d FROM t1 ORDER BY d;
+
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  f FLOAT,
+  r REAL(20,3),
+  d DOUBLE,
+  dp DOUBLE PRECISION (64,10),
+  pk FLOAT PRIMARY KEY,
+  KEY(d)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (f,r,d,dp,pk) VALUES
+(1.2345,1422.22,1.2345,1234567.89,1),
+(0,0,0,0,2),
+(-1,-1,-1,-1,3),
+(17.5843,4953453454.44,29229114.0,1111111.23,4),
+(4644,1422.22,466664.999,0.5,5);
+
+EXPLAIN SELECT DISTINCT d FROM t1 ORDER BY d;
+SELECT DISTINCT d FROM t1 ORDER BY d;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_int.inc b/mysql-test/suite/leveldb/type_int.inc
new file mode 100644
index 0000000..76ce657
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_int.inc
@@ -0,0 +1,68 @@
+#
+# INT column types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  i INT $extra_col_opts,
+  i0 INT(0) $extra_col_opts,
+  i1 INT(1) $extra_col_opts,
+  i20 INT(20) $extra_col_opts,
+  t TINYINT $extra_col_opts,
+  t0 TINYINT(0) $extra_col_opts,
+  t1 TINYINT(1) $extra_col_opts,
+  t20 TINYINT(20) $extra_col_opts,
+  s SMALLINT $extra_col_opts,
+  s0 SMALLINT(0) $extra_col_opts,
+  s1 SMALLINT(1) $extra_col_opts,
+  s20 SMALLINT(20) $extra_col_opts,
+  m MEDIUMINT $extra_col_opts,
+  m0 MEDIUMINT(0) $extra_col_opts,
+  m1 MEDIUMINT(1) $extra_col_opts,
+  m20 MEDIUMINT(20) $extra_col_opts,
+  b BIGINT $extra_col_opts,
+  b0 BIGINT(0) $extra_col_opts,
+  b1 BIGINT(1) $extra_col_opts,
+  b20 BIGINT(20) $extra_col_opts,
+  pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Always valid values 
+
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (2147483647,2147483647,2147483647,2147483647,127,127,127,127,32767,32767,32767,32767,8388607,8388607,8388607,8388607,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807);
+--sorted_result
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+
+# Values which can be valid or not, 
+# depending on whether columns are SIGNED or UNSIGNED
+# (if not valid should produce warnings)
+
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483648,-2147483648,-2147483648,-2147483648,-128,-128,-128,-128,-32768,-32768,-32768,-32768,-8388608,-8388608,-8388608,-8388608,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967295,4294967295,4294967295,4294967295,255,255,255,255,65535,65535,65535,65535,16777215,16777215,16777215,16777215,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615);
+
+--sorted_result
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+
+# Invalid values
+
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483649,-2147483649,-2147483649,-2147483649,-129,-129,-129,-129,-32769,-32769,-32769,-32769,-8388609,-8388609,-8388609,-8388609,-9223372036854775809,-9223372036854775809,-9223372036854775809,-9223372036854775809);
+
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967296,4294967296,4294967296,4294967296,256,256,256,256,65536,65536,65536,65536,16777216,16777216,16777216,16777216,18446744073709551616,18446744073709551616,18446744073709551616,18446744073709551616);
+
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) SELECT b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b FROM t1 WHERE b IN (-9223372036854775808,9223372036854775807,18446744073709551615);
+
+--sorted_result
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+
+--error ER_TOO_BIG_DISPLAYWIDTH
+eval ALTER TABLE t1 ADD COLUMN i257 INT(257) $extra_col_opts;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_int.result b/mysql-test/suite/leveldb/type_int.result
new file mode 100644
index 0000000..3fe6b87
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_int.result
@@ -0,0 +1,212 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+i INT ,
+i0 INT(0) ,
+i1 INT(1) ,
+i20 INT(20) ,
+t TINYINT ,
+t0 TINYINT(0) ,
+t1 TINYINT(1) ,
+t20 TINYINT(20) ,
+s SMALLINT ,
+s0 SMALLINT(0) ,
+s1 SMALLINT(1) ,
+s20 SMALLINT(20) ,
+m MEDIUMINT ,
+m0 MEDIUMINT(0) ,
+m1 MEDIUMINT(1) ,
+m20 MEDIUMINT(20) ,
+b BIGINT ,
+b0 BIGINT(0) ,
+b1 BIGINT(1) ,
+b20 BIGINT(20) ,
+pk INT AUTO_INCREMENT PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+i	int(11)	YES		NULL	
+i0	int(11)	YES		NULL	
+i1	int(1)	YES		NULL	
+i20	int(20)	YES		NULL	
+t	tinyint(4)	YES		NULL	
+t0	tinyint(4)	YES		NULL	
+t1	tinyint(1)	YES		NULL	
+t20	tinyint(20)	YES		NULL	
+s	smallint(6)	YES		NULL	
+s0	smallint(6)	YES		NULL	
+s1	smallint(1)	YES		NULL	
+s20	smallint(20)	YES		NULL	
+m	mediumint(9)	YES		NULL	
+m0	mediumint(9)	YES		NULL	
+m1	mediumint(1)	YES		NULL	
+m20	mediumint(20)	YES		NULL	
+b	bigint(20)	YES		NULL	
+b0	bigint(20)	YES		NULL	
+b1	bigint(1)	YES		NULL	
+b20	bigint(20)	YES		NULL	
+pk	int(11)	NO	PRI	NULL	auto_increment
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (2147483647,2147483647,2147483647,2147483647,127,127,127,127,32767,32767,32767,32767,8388607,8388607,8388607,8388607,9223372036854775807,9223372036854775807,9223372036854775807,9223372036854775807);
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483648,-2147483648,-2147483648,-2147483648,-128,-128,-128,-128,-32768,-32768,-32768,-32768,-8388608,-8388608,-8388608,-8388608,-9223372036854775808,-9223372036854775808,-9223372036854775808,-9223372036854775808);
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967295,4294967295,4294967295,4294967295,255,255,255,255,65535,65535,65535,65535,16777215,16777215,16777215,16777215,18446744073709551615,18446744073709551615,18446744073709551615,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (-2147483649,-2147483649,-2147483649,-2147483649,-129,-129,-129,-129,-32769,-32769,-32769,-32769,-8388609,-8388609,-8388609,-8388609,-9223372036854775809,-9223372036854775809,-9223372036854775809,-9223372036854775809);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) VALUES (4294967296,4294967296,4294967296,4294967296,256,256,256,256,65536,65536,65536,65536,16777216,16777216,16777216,16777216,18446744073709551616,18446744073709551616,18446744073709551616,18446744073709551616);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 1
+Warning	1264	Out of range value for column 'i0' at row 1
+Warning	1264	Out of range value for column 'i1' at row 1
+Warning	1264	Out of range value for column 'i20' at row 1
+Warning	1264	Out of range value for column 't' at row 1
+Warning	1264	Out of range value for column 't0' at row 1
+Warning	1264	Out of range value for column 't1' at row 1
+Warning	1264	Out of range value for column 't20' at row 1
+Warning	1264	Out of range value for column 's' at row 1
+Warning	1264	Out of range value for column 's0' at row 1
+Warning	1264	Out of range value for column 's1' at row 1
+Warning	1264	Out of range value for column 's20' at row 1
+Warning	1264	Out of range value for column 'm' at row 1
+Warning	1264	Out of range value for column 'm0' at row 1
+Warning	1264	Out of range value for column 'm1' at row 1
+Warning	1264	Out of range value for column 'm20' at row 1
+Warning	1264	Out of range value for column 'b' at row 1
+Warning	1264	Out of range value for column 'b0' at row 1
+Warning	1264	Out of range value for column 'b1' at row 1
+Warning	1264	Out of range value for column 'b20' at row 1
+INSERT INTO t1 (i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20) SELECT b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b FROM t1 WHERE b IN (-9223372036854775808,9223372036854775807,18446744073709551615);
+Warnings:
+Warning	1264	Out of range value for column 'i' at row 8
+Warning	1264	Out of range value for column 'i0' at row 8
+Warning	1264	Out of range value for column 'i1' at row 8
+Warning	1264	Out of range value for column 'i20' at row 8
+Warning	1264	Out of range value for column 't' at row 8
+Warning	1264	Out of range value for column 't0' at row 8
+Warning	1264	Out of range value for column 't1' at row 8
+Warning	1264	Out of range value for column 't20' at row 8
+Warning	1264	Out of range value for column 's' at row 8
+Warning	1264	Out of range value for column 's0' at row 8
+Warning	1264	Out of range value for column 's1' at row 8
+Warning	1264	Out of range value for column 's20' at row 8
+Warning	1264	Out of range value for column 'm' at row 8
+Warning	1264	Out of range value for column 'm0' at row 8
+Warning	1264	Out of range value for column 'm1' at row 8
+Warning	1264	Out of range value for column 'm20' at row 8
+Warning	1264	Out of range value for column 'i' at row 9
+Warning	1264	Out of range value for column 'i0' at row 9
+Warning	1264	Out of range value for column 'i1' at row 9
+Warning	1264	Out of range value for column 'i20' at row 9
+Warning	1264	Out of range value for column 't' at row 9
+Warning	1264	Out of range value for column 't0' at row 9
+Warning	1264	Out of range value for column 't1' at row 9
+Warning	1264	Out of range value for column 't20' at row 9
+Warning	1264	Out of range value for column 's' at row 9
+Warning	1264	Out of range value for column 's0' at row 9
+Warning	1264	Out of range value for column 's1' at row 9
+Warning	1264	Out of range value for column 's20' at row 9
+Warning	1264	Out of range value for column 'm' at row 9
+Warning	1264	Out of range value for column 'm0' at row 9
+Warning	1264	Out of range value for column 'm1' at row 9
+Warning	1264	Out of range value for column 'm20' at row 9
+Warning	1264	Out of range value for column 'i' at row 10
+Warning	1264	Out of range value for column 'i0' at row 10
+Warning	1264	Out of range value for column 'i1' at row 10
+Warning	1264	Out of range value for column 'i20' at row 10
+Warning	1264	Out of range value for column 't' at row 10
+Warning	1264	Out of range value for column 't0' at row 10
+Warning	1264	Out of range value for column 't1' at row 10
+Warning	1264	Out of range value for column 't20' at row 10
+Warning	1264	Out of range value for column 's' at row 10
+Warning	1264	Out of range value for column 's0' at row 10
+Warning	1264	Out of range value for column 's1' at row 10
+Warning	1264	Out of range value for column 's20' at row 10
+Warning	1264	Out of range value for column 'm' at row 10
+Warning	1264	Out of range value for column 'm0' at row 10
+Warning	1264	Out of range value for column 'm1' at row 10
+Warning	1264	Out of range value for column 'm20' at row 10
+Warning	1264	Out of range value for column 'i' at row 11
+Warning	1264	Out of range value for column 'i0' at row 11
+Warning	1264	Out of range value for column 'i1' at row 11
+Warning	1264	Out of range value for column 'i20' at row 11
+Warning	1264	Out of range value for column 't' at row 11
+Warning	1264	Out of range value for column 't0' at row 11
+Warning	1264	Out of range value for column 't1' at row 11
+Warning	1264	Out of range value for column 't20' at row 11
+Warning	1264	Out of range value for column 's' at row 11
+Warning	1264	Out of range value for column 's0' at row 11
+Warning	1264	Out of range value for column 's1' at row 11
+Warning	1264	Out of range value for column 's20' at row 11
+Warning	1264	Out of range value for column 'm' at row 11
+Warning	1264	Out of range value for column 'm0' at row 11
+Warning	1264	Out of range value for column 'm1' at row 11
+Warning	1264	Out of range value for column 'm20' at row 11
+SELECT i,i0,i1,i20,t,t0,t1,t20,s,s0,s1,s20,m,m0,m1,m20,b,b0,b1,b20 FROM t1;
+i	i0	i1	i20	t	t0	t1	t20	s	s0	s1	s20	m	m0	m1	m20	b	b0	b1	b20
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+-2147483648	-2147483648	-2147483648	-2147483648	-128	-128	-128	-128	-32768	-32768	-32768	-32768	-8388608	-8388608	-8388608	-8388608	-9223372036854775808	-9223372036854775808	-9223372036854775808	-9223372036854775808
+0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
+1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18	19	20
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+2147483647	2147483647	2147483647	2147483647	127	127	127	127	32767	32767	32767	32767	8388607	8388607	8388607	8388607	9223372036854775807	9223372036854775807	9223372036854775807	9223372036854775807
+ALTER TABLE t1 ADD COLUMN i257 INT(257) ;
+ERROR 42000: Display width out of range for column 'i257' (max = 255)
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_int.test b/mysql-test/suite/leveldb/type_int.test
new file mode 100644
index 0000000..c7a86c0
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_int.test
@@ -0,0 +1,6 @@
+#
+# INT column types
+#
+
+--source type_int.inc
+
diff --git a/mysql-test/suite/leveldb/type_int_indexes.result b/mysql-test/suite/leveldb/type_int_indexes.result
new file mode 100644
index 0000000..60cd049
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_int_indexes.result
@@ -0,0 +1,61 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+i INT PRIMARY KEY,
+t TINYINT,
+s SMALLINT,
+m MEDIUMINT,
+b BIGINT
+) ENGINE=LevelDB;
+INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16);
+EXPLAIN SELECT i FROM t1 ORDER BY i;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	4	NULL	1000	Using index
+SELECT i FROM t1 ORDER BY i;
+i
+1
+2
+3
+5
+10
+11
+12
+101
+1000
+10001
+DROP TABLE t1;
+CREATE TABLE t1 (
+i INT,
+t TINYINT,
+s SMALLINT,
+m MEDIUMINT,
+b BIGINT,
+pk SMALLINT AUTO_INCREMENT PRIMARY KEY,
+INDEX s_m (s,m)
+) ENGINE=LevelDB;
+INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16);
+EXPLAIN SELECT s, m FROM t1 WHERE s != 10 AND m != 1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	range	s_m	s_m	3	NULL	20	Using where; Using index
+SELECT s, m FROM t1 WHERE s != 10 AND m != 1;
+s	m
+10000	1000000
+10000	1000000
+10002	10003
+103	104
+12	13
+13	14
+14	15
+3	4
+4	5
+5	6
+DROP TABLE t1;
+CREATE TABLE t1 (
+i INT,
+t TINYINT,
+s SMALLINT,
+m MEDIUMINT,
+b BIGINT,
+pk MEDIUMINT AUTO_INCREMENT PRIMARY KEY,
+UNIQUE KEY b_t (b,t)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
diff --git a/mysql-test/suite/leveldb/type_int_indexes.test b/mysql-test/suite/leveldb/type_int_indexes.test
new file mode 100644
index 0000000..1169f5f
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_int_indexes.test
@@ -0,0 +1,66 @@
+#
+# INT column types with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  i INT PRIMARY KEY,
+  t TINYINT,
+  s SMALLINT,
+  m MEDIUMINT,
+  b BIGINT
+) ENGINE=LevelDB;
+
+INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16);
+
+EXPLAIN SELECT i FROM t1 ORDER BY i;
+SELECT i FROM t1 ORDER BY i;
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+  i INT,
+  t TINYINT,
+  s SMALLINT,
+  m MEDIUMINT,
+  b BIGINT,
+  pk SMALLINT AUTO_INCREMENT PRIMARY KEY,
+  INDEX s_m (s,m)
+) ENGINE=LevelDB;
+
+INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16);
+
+EXPLAIN SELECT s, m FROM t1 WHERE s != 10 AND m != 1;
+--sorted_result
+SELECT s, m FROM t1 WHERE s != 10 AND m != 1;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  i INT,
+  t TINYINT,
+  s SMALLINT,
+  m MEDIUMINT,
+  b BIGINT,
+  pk MEDIUMINT AUTO_INCREMENT PRIMARY KEY,
+  UNIQUE KEY b_t (b,t)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+INSERT INTO t1 (i,t,s,m,b) VALUES (1,2,3,4,5),(1000,100,10000,1000000,1000000000000000000),(5,100,10000,1000000,100000000000000000),(2,3,4,5,6),(3,4,5,6,7),(101,102,103,104,105),(10001,103,10002,10003,10004),(10,11,12,13,14),(11,12,13,14,15),(12,13,14,15,16);
+
+# This query should use the index b_t, we just don't want to run EXPLAIN
+# (to avoid mismatches due to different subquery-related plans)
+SELECT b+t FROM t1 WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t;
+SELECT b+t FROM t1 FORCE INDEX (b_t) WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t;
+SELECT b+t FROM t1 IGNORE INDEX (b_t) WHERE (b,t) IN ( SELECT b, t FROM t1 WHERE i>1 ) ORDER BY b+t;
+
+DROP TABLE t1;
+
+--enable_parsing
+
diff --git a/mysql-test/suite/leveldb/type_set.inc b/mysql-test/suite/leveldb/type_set.inc
new file mode 100644
index 0000000..8789b2f
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_set.inc
@@ -0,0 +1,49 @@
+#
+# SET column type
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Valid values.
+
+eval CREATE TABLE t1 (
+  a SET('') $extra_col_opts,
+  b SET('test1','test2','test3','test4','test5') $extra_col_opts,
+  c SET('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64') $extra_col_opts,
+  PRIMARY KEY (c)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+INSERT INTO t1 (a,b,c) VALUES 
+('','test2,test3','01,34,44,,23'),
+('',5,2),
+(',','test4,test2','');
+--sorted_result
+SELECT a,b,c FROM t1;
+
+# Out of range values 
+# (should produce warnings)
+
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+--sorted_result
+SELECT a,b,c FROM t1;
+
+# Non-unique values in set
+# (should produce a warning)
+eval ALTER TABLE t1 ADD COLUMN e SET('a','A') $extra_col_opts;
+
+SHOW COLUMNS IN t1;
+
+--error ER_TOO_BIG_SET
+eval ALTER TABLE t1 ADD COLUMN f SET('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i') $extra_col_opts;
+
+# Simple comparison
+
+--sorted_result
+SELECT a,b,c,e FROM t1 WHERE FIND_IN_SET('test2',b)>0 OR a != '';
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_set.result b/mysql-test/suite/leveldb/type_set.result
new file mode 100644
index 0000000..bf28384
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_set.result
@@ -0,0 +1,49 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a SET('') ,
+b SET('test1','test2','test3','test4','test5') ,
+c SET('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64') ,
+PRIMARY KEY (c)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	set('')	YES		NULL	
+b	set('test1','test2','test3','test4','test5')	YES		NULL	
+c	set('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64')	NO	PRI		
+INSERT INTO t1 (a,b,c) VALUES 
+('','test2,test3','01,34,44,,23'),
+('',5,2),
+(',','test4,test2','');
+Warnings:
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+	test1,test3	02
+	test2,test3	01,23,34,44
+	test2,test4	
+INSERT INTO t1 (a,b,c) VALUES (0,'test6',-1);
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 1
+Warning	1265	Data truncated for column 'c' at row 1
+SELECT a,b,c FROM t1;
+a	b	c
+		01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50'51,52,53,54,55,56,57,58,59,60,61,62,63,64
+	test1,test3	02
+	test2,test3	01,23,34,44
+	test2,test4	
+ALTER TABLE t1 ADD COLUMN e SET('a','A') ;
+Warnings:
+Note	1291	Column 'e' has duplicated value 'a' in SET
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+a	set('')	YES		NULL	
+b	set('test1','test2','test3','test4','test5')	YES		NULL	
+c	set('01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50''51','52','53','54','55','56','57','58','59','60','61','62','63','64')	NO	PRI		
+e	set('a','A')	YES		NULL	
+ALTER TABLE t1 ADD COLUMN f SET('1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','11','12','13','14','15','16','17','18','19','1a','1b','1c','1d','1e','1f','1g','1h','1i','1j','1k','1l','1m','1n','1o','1p','1q','1r','1s','1t','1u','1v','1w','1x','1y','1z','20','21','22','23','24','25','26','27','28','29','2a','2b','2c','2d','2e','2f','2g','2h','2i','2j','2k','2l','2m','2n','2o','2p','2q','2r','2s','2t','2u','2v','2w','2x','2y','2z','30','31','32','33','34','35','36','37','38','39','3a','3b','3c','3d','3e','3f','3g','3h','3i') ;
+ERROR HY000: Too many strings for column f and SET
+SELECT a,b,c,e FROM t1 WHERE FIND_IN_SET('test2',b)>0 OR a != '';
+a	b	c	e
+	test2,test3	01,23,34,44	NULL
+	test2,test4		NULL
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_set.test b/mysql-test/suite/leveldb/type_set.test
new file mode 100644
index 0000000..ce6c4f4
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_set.test
@@ -0,0 +1,6 @@
+#
+# SET column type
+#
+
+--source type_set.inc
+
diff --git a/mysql-test/suite/leveldb/type_set_indexes.result b/mysql-test/suite/leveldb/type_set_indexes.result
new file mode 100644
index 0000000..a5f04f1
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_set_indexes.result
@@ -0,0 +1,85 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+a SET('N.America','S.America','Africa','Antarctica','Australia','Europe','Asia'),
+b SET('test1','test2','test3','test4','test5'),
+c SET('01','22','23','33','34','39','40','44','50','63','64') PRIMARY KEY
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	c	A	NULL	NULL	NULL		BTREE		
+INSERT INTO t1 (a,b,c) VALUES 
+('','test2,test3','01,34,44,23'),
+('',5,2),
+('N.America,Asia','test4,test2',''),
+('Africa,Europe,Asia','test2,test3','01'),
+('Antarctica','test3','34,44'),
+('Asia','test5','50'),
+('Europe,S.America','test1,','39');
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 7
+EXPLAIN SELECT c FROM t1 ORDER BY c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	2	NULL	1000	Using index
+SELECT c FROM t1 ORDER BY c;
+c
+
+01
+22
+39
+34,44
+01,23,34,44
+50
+EXPLAIN SELECT c FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY c;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	NULL	PRIMARY	2	NULL	1000	Using index; Using filesort
+SELECT c FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY c;
+c
+
+01
+22
+39
+34,44
+01,23,34,44
+50
+INSERT INTO t1 (a,b,c) VALUES ('Antarctica','test3','02');
+ERROR 23000: Duplicate entry '22' for key 'PRIMARY'
+INSERT INTO t1 (a,b,c) VALUES ('','test1','34,44');
+ERROR 23000: Duplicate entry '34,44' for key 'PRIMARY'
+DROP TABLE t1;
+CREATE TABLE t1 (
+a SET('N.America','S.America','Africa','Antarctica','Australia','Europe','Asia'),
+b SET('test1','test2','test3','test4','test5'),
+c SET('01','22','23','33','34','39','40','44','50','63','64'),
+pk SET('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+INDEX(a)
+) ENGINE=LevelDB;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	pk	A	NULL	NULL	NULL		BTREE		
+t1	1	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+INSERT INTO t1 (a,b,c,pk) VALUES
+('','test2,test3','01,34,44,23',1),
+('',5,2,2),
+('N.America,Asia','test4,test2','',3),
+('Africa,Europe,Asia','test2,test3','01',4),
+('Antarctica','test3','34,44',5),
+('Asia','test5','50',6),
+('Europe,S.America','test1,','39',7);
+Warnings:
+Warning	1265	Data truncated for column 'b' at row 7
+EXPLAIN SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	1000	Using where
+SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+a
+Africa,Europe,Asia
+S.America,Europe
+DROP TABLE t1;
+CREATE TABLE t1 (
+a SET('N.America','S.America','Africa','Antarctica','Australia','Europe','Asia'),
+b SET('test1','test2','test3','test4','test5'),
+c SET('01','22','23','33','34','39','40','44','50','63','64'),
+pk SET('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+UNIQUE INDEX b_a (b,a)
+) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
diff --git a/mysql-test/suite/leveldb/type_set_indexes.test b/mysql-test/suite/leveldb/type_set_indexes.test
new file mode 100644
index 0000000..253304e
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_set_indexes.test
@@ -0,0 +1,94 @@
+#
+# SET columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (
+  a SET('N.America','S.America','Africa','Antarctica','Australia','Europe','Asia'),
+  b SET('test1','test2','test3','test4','test5'),
+  c SET('01','22','23','33','34','39','40','44','50','63','64') PRIMARY KEY
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c) VALUES 
+('','test2,test3','01,34,44,23'),
+('',5,2),
+('N.America,Asia','test4,test2',''),
+('Africa,Europe,Asia','test2,test3','01'),
+('Antarctica','test3','34,44'),
+('Asia','test5','50'),
+('Europe,S.America','test1,','39');
+
+EXPLAIN SELECT c FROM t1 ORDER BY c;
+SELECT c FROM t1 ORDER BY c;
+
+EXPLAIN SELECT c FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY c;
+SELECT c FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY) ORDER BY c;
+
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b,c) VALUES ('Antarctica','test3','02');
+
+--error ER_DUP_ENTRY
+INSERT INTO t1 (a,b,c) VALUES ('','test1','34,44');
+
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+  a SET('N.America','S.America','Africa','Antarctica','Australia','Europe','Asia'),
+  b SET('test1','test2','test3','test4','test5'),
+  c SET('01','22','23','33','34','39','40','44','50','63','64'),
+  pk SET('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+  INDEX(a)
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c,pk) VALUES
+('','test2,test3','01,34,44,23',1),
+('',5,2,2),
+('N.America,Asia','test4,test2','',3),
+('Africa,Europe,Asia','test2,test3','01',4),
+('Antarctica','test3','34,44',5),
+('Asia','test5','50',6),
+('Europe,S.America','test1,','39',7);
+
+EXPLAIN SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+--sorted_result
+SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  a SET('N.America','S.America','Africa','Antarctica','Australia','Europe','Asia'),
+  b SET('test1','test2','test3','test4','test5'),
+  c SET('01','22','23','33','34','39','40','44','50','63','64'),
+  pk SET('1','2','3','4','5','6','7','8','9') PRIMARY KEY,
+  UNIQUE INDEX b_a (b,a)
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (a,b,c) VALUES
+('','test2,test3','01,34,44,23'),
+('',5,2),
+('N.America,Asia','test4,test2',''),
+('Africa,Europe,Asia','test2,test3','01'),
+('Antarctica','test3','34,44'),
+('Asia','test5','50'),
+('Europe,S.America','test1,','39');
+
+EXPLAIN SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
+--sorted_result
+SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
+
+DROP TABLE t1;
+
+--enable_parsing
+
diff --git a/mysql-test/suite/leveldb/type_text.inc b/mysql-test/suite/leveldb/type_text.inc
new file mode 100644
index 0000000..6bde0b0
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_text.inc
@@ -0,0 +1,49 @@
+#
+# TEXT column types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  pk INT AUTO_INCREMENT PRIMARY KEY,
+  t TEXT $extra_col_opts,
+  t0 TEXT(0) $extra_col_opts,
+  t1 TEXT(1) $extra_col_opts,
+  t300 TEXT(300) $extra_col_opts,
+  tm TEXT(65535) $extra_col_opts,
+  t70k TEXT(70000) $extra_col_opts,
+  t17m TEXT(17000000) $extra_col_opts,
+  tt TINYTEXT $extra_col_opts,
+  m MEDIUMTEXT $extra_col_opts,
+  l LONGTEXT $extra_col_opts
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+# Valid values 
+# (cannot get MAX for all columns due to max_allowed_packet limitations)
+
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',255), REPEAT('i',1048576), REPEAT('j',1048576) );
+
+--sorted_result
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+
+# Invalid values (produce warnings, except for mediumtext and longtext columns for which the values are within limits)
+
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+
+--sorted_result
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+
+--error ER_TOO_BIG_DISPLAYWIDTH
+eval ALTER TABLE t1 ADD COLUMN ttt TEXT(4294967296) $extra_col_opts;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_text.result b/mysql-test/suite/leveldb/type_text.result
new file mode 100644
index 0000000..2f744f1
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_text.result
@@ -0,0 +1,57 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+pk INT AUTO_INCREMENT PRIMARY KEY,
+t TEXT ,
+t0 TEXT(0) ,
+t1 TEXT(1) ,
+t300 TEXT(300) ,
+tm TEXT(65535) ,
+t70k TEXT(70000) ,
+t17m TEXT(17000000) ,
+tt TINYTEXT ,
+m MEDIUMTEXT ,
+l LONGTEXT 
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+pk	int(11)	NO	PRI	NULL	auto_increment
+t	text	YES		NULL	
+t0	text	YES		NULL	
+t1	tinytext	YES		NULL	
+t300	text	YES		NULL	
+tm	text	YES		NULL	
+t70k	mediumtext	YES		NULL	
+t17m	longtext	YES		NULL	
+tt	tinytext	YES		NULL	
+m	mediumtext	YES		NULL	
+l	longtext	YES		NULL	
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+('','','','','','','','','',''),
+('a','b','c','d','e','f','g','h','i','j'),
+('test1','test2','test3','test4','test5','test6','test7','test8','test9','test10'),
+( REPEAT('a',65535), REPEAT('b',65535), REPEAT('c',255), REPEAT('d',65535), REPEAT('e',65535), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',255), REPEAT('i',1048576), REPEAT('j',1048576) );
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(t)	LENGTH(t0)	LENGTH(t1)	LENGTH(t300)	LENGTH(tm)	LENGTH(t70k)	LENGTH(t17m)	LENGTH(tt)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+INSERT INTO t1 (t,t0,t1,t300,tm,t70k,t17m,tt,m,l) VALUES
+( REPEAT('a',65536), REPEAT('b',65536), REPEAT('c',256), REPEAT('d',65536), REPEAT('e',65536), REPEAT('f',1048576), REPEAT('g',1048576), REPEAT('h',256), REPEAT('i',1048576), REPEAT('j',1048576) );
+Warnings:
+Warning	1265	Data truncated for column 't' at row 1
+Warning	1265	Data truncated for column 't0' at row 1
+Warning	1265	Data truncated for column 't1' at row 1
+Warning	1265	Data truncated for column 't300' at row 1
+Warning	1265	Data truncated for column 'tm' at row 1
+Warning	1265	Data truncated for column 'tt' at row 1
+SELECT LENGTH(t), LENGTH(t0), LENGTH(t1), LENGTH(t300), LENGTH(tm), LENGTH(t70k), LENGTH(t17m), LENGTH(tt), LENGTH(m), LENGTH(l) FROM t1;
+LENGTH(t)	LENGTH(t0)	LENGTH(t1)	LENGTH(t300)	LENGTH(tm)	LENGTH(t70k)	LENGTH(t17m)	LENGTH(tt)	LENGTH(m)	LENGTH(l)
+0	0	0	0	0	0	0	0	0	0
+1	1	1	1	1	1	1	1	1	1
+5	5	5	5	5	5	5	5	5	6
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+65535	65535	255	65535	65535	1048576	1048576	255	1048576	1048576
+ALTER TABLE t1 ADD COLUMN ttt TEXT(4294967296) ;
+ERROR 42000: Display width out of range for column 'ttt' (max = 4294967295)
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_text.test b/mysql-test/suite/leveldb/type_text.test
new file mode 100644
index 0000000..41e91b1
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_text.test
@@ -0,0 +1,6 @@
+#
+# TEXT column types
+#
+
+--source type_text.inc
+
diff --git a/mysql-test/suite/leveldb/type_text_indexes.result b/mysql-test/suite/leveldb/type_text_indexes.result
new file mode 100644
index 0000000..a23373e
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_text_indexes.result
@@ -0,0 +1,137 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (t TEXT <CUSTOM_COL_OPTIONS>,
+tt TINYTEXT <CUSTOM_COL_OPTIONS>,
+m MEDIUMTEXT <CUSTOM_COL_OPTIONS>,
+l LONGTEXT <CUSTOM_COL_OPTIONS>,
+<CUSTOM_INDEX> t (t(32))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	1	#	1	t	#	#	32	NULL	#	#		
+INSERT INTO t1 (t,tt,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+SELECT SUBSTRING(t,16) AS f FROM t1 WHERE t IN ('test1','test2') ORDER BY f;
+f
+
+
+DROP TABLE t1;
+CREATE TABLE t1 (t TEXT <CUSTOM_COL_OPTIONS>,
+tt TINYTEXT <CUSTOM_COL_OPTIONS>,
+m MEDIUMTEXT <CUSTOM_COL_OPTIONS>,
+l LONGTEXT <CUSTOM_COL_OPTIONS>,
+PRIMARY KEY t (t(32))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	PRIMARY	1	t	#	#	32	NULL	#	#		
+INSERT INTO t1 (t,tt,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+EXPLAIN SELECT SUBSTRING(t,16) AS f FROM t1 WHERE t IN ('test1','test2') ORDER BY f;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	PRIMARY	#	#	#	#
+SELECT SUBSTRING(t,16) AS f FROM t1 WHERE t IN ('test1','test2') ORDER BY f;
+f
+
+
+EXPLAIN SELECT SUBSTRING(t,16) AS f FROM t1 IGNORE INDEX (PRIMARY) WHERE t IN ('test1','test2') ORDER BY f;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	NULL	#	#	#	#
+SELECT SUBSTRING(t,16) AS f FROM t1 IGNORE INDEX (PRIMARY) WHERE t IN ('test1','test2') ORDER BY f;
+f
+
+
+DROP TABLE t1;
+CREATE TABLE t1 (t TEXT <CUSTOM_COL_OPTIONS>,
+tt TINYTEXT <CUSTOM_COL_OPTIONS>,
+m MEDIUMTEXT <CUSTOM_COL_OPTIONS>,
+l LONGTEXT <CUSTOM_COL_OPTIONS>,
+UNIQUE INDEX l_tt (l(256),tt(64))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	l_tt	1	l	#	#	256	NULL	#	#		
+t1	0	l_tt	2	tt	#	#	64	NULL	#	#		
+INSERT INTO t1 (t,tt,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+EXPLAIN SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	l_tt	#	#	#	#	#
+SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+SUBSTRING(tt,64)	SUBSTRING(l,256)
+	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+	
+	
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff	
+	
+	
+	
+EXPLAIN SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	l_tt	l_tt	#	#	#	#
+SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+SUBSTRING(tt,64)	SUBSTRING(l,256)
+	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb	
+	
+	
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff	
+	
+	
+	
+DROP TABLE t1;
+CREATE TABLE t1 (t TEXT <CUSTOM_COL_OPTIONS>,
+tt TINYTEXT <CUSTOM_COL_OPTIONS>,
+m MEDIUMTEXT <CUSTOM_COL_OPTIONS>,
+l LONGTEXT <CUSTOM_COL_OPTIONS>,
+INDEX (m(128))
+) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+SHOW INDEX IN t1;
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	1	m	1	m	#	#	128	NULL	#	#		
+INSERT INTO t1 (t,tt,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+EXPLAIN SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+#	#	#	#	#	m	#	#	#	#
+SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+f
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/type_text_indexes.test b/mysql-test/suite/leveldb/type_text_indexes.test
new file mode 100644
index 0000000..f55e549
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_text_indexes.test
@@ -0,0 +1,102 @@
+#
+# TEXT columns with indexes
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+
+CREATE TABLE t1 (
+  t TEXT,
+  tt TINYTEXT,
+  m MEDIUMTEXT,
+  l LONGTEXT,
+  PRIMARY KEY t (t(32))
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (t,tt,m,l) VALUES
+('','','',''),
+('a','b','c','d'),
+('b','d','c','b'),
+('test1','test2','test3','test4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128)),
+('abc','def','ghi','jkl'),
+('test2','test3','test4','test5'),
+('test3','test4','test5','test6'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128)),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128));
+
+EXPLAIN SELECT SUBSTRING(t,16) AS f FROM t1 WHERE t IN ('test1','test2') ORDER BY f;
+SELECT SUBSTRING(t,16) AS f FROM t1 WHERE t IN ('test1','test2') ORDER BY f;
+
+EXPLAIN SELECT SUBSTRING(t,16) AS f FROM t1 IGNORE INDEX (PRIMARY) WHERE t IN ('test1','test2') ORDER BY f;
+SELECT SUBSTRING(t,16) AS f FROM t1 IGNORE INDEX (PRIMARY) WHERE t IN ('test1','test2') ORDER BY f;
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (
+  t TEXT,
+  tt TINYTEXT,
+  m MEDIUMTEXT,
+  l LONGTEXT,
+  pk TINYTEXT PRIMARY KEY,
+  UNIQUE INDEX l_tt (l(256),tt(64))
+) ENGINE=LevelDB;
+
+--disable_parsing
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (t,tt,m,l,pk) VALUES
+('','','','','1'),
+('a','b','c','d','2'),
+('b','d','c','b','3'),
+('test1','test2','test3','test4','4'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128),'5'),
+('abc','def','ghi','jkl','6'),
+('test2','test3','test4','test5','7'),
+('test3','test4','test5','test6','8'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128),'9'),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128),'10');
+
+# Here we are getting possible key l_t, but not the final key
+EXPLAIN SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+
+EXPLAIN SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+SELECT SUBSTRING(tt,64), SUBSTRING(l,256) FROM t1 FORCE INDEX (l_t) WHERE tt!=l AND l NOT IN ('test1') ORDER BY tt, l DESC;
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (
+  t TEXT,
+  tt TINYTEXT,
+  m MEDIUMTEXT,
+  l LONGTEXT,
+  pk MEDIUMTEXT PRIMARY KEY,
+  INDEX (m(128))
+) ENGINE=LevelDB;
+
+SHOW INDEX IN t1;
+
+INSERT INTO t1 (t,tt,m,l,pk) VALUES
+('','','','','0'),
+('a','b','c','d','1'),
+('b','d','c','b','2'),
+('test1','test2','test3','test4','3'),
+(REPEAT('a',128),REPEAT('b',128),REPEAT('c',128),REPEAT('d',128),'4'),
+('abc','def','ghi','jkl','5'),
+('test2','test3','test4','test5','6'),
+('test3','test4','test5','test6','7'),
+(REPEAT('b',128),REPEAT('f',128),REPEAT('e',128),REPEAT('d',128),'8'),
+(REPEAT('c',128),REPEAT('b',128),REPEAT('c',128),REPEAT('e',128),'9');
+
+EXPLAIN SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+SELECT SUBSTRING(m,128) AS f FROM t1 WHERE m = 'test1' ORDER BY f DESC;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/type_varbinary.inc b/mysql-test/suite/leveldb/type_varbinary.inc
new file mode 100644
index 0000000..335aa98
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_varbinary.inc
@@ -0,0 +1,75 @@
+#
+# VARBINARY column types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  v0 VARBINARY(0) $extra_col_opts,
+  v1 VARBINARY(1) $extra_col_opts,
+  v64 VARBINARY(64) $extra_col_opts,
+  v65000 VARBINARY(65000) $extra_col_opts,
+  PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+eval CREATE TABLE t2 (v VARBINARY(65532) $extra_col_opts, PRIMARY KEY(v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+
+--sorted_result
+SELECT HEX(v0), HEX(v1), HEX(v64), HEX(v65000) FROM t1;
+
+# Invalid values
+
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+
+--sorted_result
+SELECT HEX(v0), HEX(v1), HEX(v64), LENGTH(HEX(v65000)) FROM t1;
+
+eval ALTER TABLE t1 ADD COLUMN v65536 VARBINARY(65536) $extra_col_opts;
+SHOW COLUMNS IN t1;
+
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/type_varbinary.result b/mysql-test/suite/leveldb/type_varbinary.result
new file mode 100644
index 0000000..f966fac
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_varbinary.result
@@ -0,0 +1,93 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+v0 VARBINARY(0) ,
+v1 VARBINARY(1) ,
+v64 VARBINARY(64) ,
+v65000 VARBINARY(65000) ,
+PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varbinary(0)	YES		NULL	
+v1	varbinary(1)	YES		NULL	
+v64	varbinary(64)	NO	PRI		
+v65000	varbinary(65000)	YES		NULL	
+CREATE TABLE t2 (v VARBINARY(65532) , PRIMARY KEY(v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+Field	Type	Null	Key	Default	Extra
+v	varbinary(65532)	NO	PRI		
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+SELECT HEX(v0), HEX(v1), HEX(v64), HEX(v65000) FROM t1;
+HEX(v0)	HEX(v1)	HEX(v64)	HEX(v65000)
+			
+	79	4F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C7265616479206578697374	486572652069732061206C697374206F66207265636F6D6D656E64656420626F6F6B73206F6E204D61726961444220616E64204D7953514C2E2057652776652070726F7669646564206C696E6B7320746F20416D617A6F6E2E636F6D206865726520666F7220636F6E76656E69656E63652C2062757420746865792063616E20626520666F756E64206174206D616E79206F7468657220626F6F6B73746F7265732C20626F7468206F6E6C696E6520616E64206F66662E0A0A2020496620796F752077616E7420746F206861766520796F7572206661766F72697465204D7953514C202F204D61726961444220626F6F6B206C697374656420686572652C20706C65617365206C65617665206120636F6D6D656E742E0A2020466F7220646576656C6F706572732077686F2077616E7420746F20636F6465206F6E204D617269614442206F72204D7953514C0A0A2020202020202A20556E6465727374616E64696E67204D7953514C20496E7465726E616C73206279205361736861205061636865762C20666F726D6572204D7953514C20646576656C6F706572206174204D7953514C2041422E0A2020202020
 20202020
 2020206F205468697320697320746865206F6E6C7920626F6F6B207765206B6E6F772061626F75742074686174206465736372696265732074686520696E7465726E616C73206F66204D617269614442202F204D7953514C2E2041206D757374206861766520666F7220616E796F6E652077686F2077616E747320746F20756E6465727374616E6420616E6420646576656C6F70206F6E204D617269614442210A2020202020202020202020206F204E6F7420616C6C20746F706963732061726520636F766572656420616E6420736F6D652070617274732061726520736C696768746C79206F757464617465642C20627574207374696C6C20746865206265737420626F6F6B206F6E207468697320746F7069632E200A2020202020202A204D7953514C20352E3120506C7567696E20446576656C6F706D656E742062792053657267656920476F6C75626368696B20616E6420416E64726577204875746368696E67730A2020202020202020202020206F2041206D757374207265616420666F7220616E796F6E652077616E74696E6720746F207772697465206120706C7567696E20666F72204D6172696144422C207772697474656E20627920746865205365726765692077686F2064657369676E65642074686520706C7567696E20696E7465726661636520666F72204
 D7953514
 C20616E64204D61726961444221200A0A2020466F72204D617269614442202F204D7953514C20656E642075736572730A0A2020202020202A204D61726961444220437261736820436F757273652062792042656E20466F7274610A2020202020202020202020206F204669727374204D61726961444220626F6F6B210A2020202020202020202020206F20466F722070656F706C652077686F2077616E7420746F206C6561726E2053514C20616E642074686520626173696373206F66204D6172696144422E0A2020202020202020202020206F204E6F77207368697070696E672E20507572636861736520617420416D617A6F6E2E636F6D206F7220796F7572206661766F7269746520626F6F6B73656C6C65722E200A0A2020202020202A2053514C2D393920436F6D706C6574652C205265616C6C792062792050657465722047756C75747A616E20262054727564792050656C7A65722E0A2020202020202020202020206F2045766572797468696E6720796F752077616E74656420746F206B6E6F772061626F7574207468652053514C203939207374616E646172642E20457863656C6C656E74207265666572656E636520626F6F6B210A2020202020202020202020206F204672656520746F207265616420696E20746865204B6E6F776C656467656261736521200A
 0A202020
 2020202A204D7953514C20283474682045646974696F6E29206279205061756C204475426F69730A2020202020202020202020206F20546865202764656661756C742720626F6F6B20746F207265616420696620796F7520776F6E7420746F206C6561726E20746F20757365204D7953514C202F204D6172696144422E200A0A2020202020202A204D7953514C20436F6F6B626F6F6B206279205061756C204475426F69730A2020202020202020202020206F2041206C6F74206F66206578616D706C6573206F6620686F7720746F20757365204D7953514C2E204173207769746820616C6C206F66205061756C277320626F6F6B732C206974277320776F727468206974732077656967687420696E20676F6C6420616E64206576656E20656E6A6F7961626C652072656164696E6720666F7220737563682061202764727927207375626A6563742E200A0A2020202020202A204869676820506572666F726D616E6365204D7953514C2C205365636F6E642045646974696F6E2C204279204261726F6E20536368776172747A2C205065746572205A6169747365762C20566164696D20546B616368656E6B6F2C204A6572656D7920442E205A61776F646E792C2041726A656E204C656E747A2C20446572656B204A2E2042616C6C696E672C20657420616C2E0A20202020202
 02020202
 020206F20224869676820506572666F726D616E6365204D7953514C2069732074686520646566696E697469766520677569646520746F206275696C64696E6720666173742C2072656C6961626C652073797374656D732077697468204D7953514C2E205772697474656E206279206E6F74656420657870657274732077697468207965617273206F66207265616C2D776F726C6420657870657269656E6365206275696C64696E672076657279206C617267652073797374656D732C207468697320626F6F6B20636F7665727320657665727920617370656374206F66204D7953514C20706572666F726D616E636520696E2064657461696C2C20616E6420666F6375736573206F6E20726F627573746E6573732C2073656375726974792C20616E64206461746120696E746567726974792E204C6561726E20616476616E63656420746563686E697175657320696E20646570746820736F20796F752063616E206272696E67206F7574204D7953514C27732066756C6C20706F7765722E22202846726F6D2074686520626F6F6B206465736372697074696F6E206174204F275265696C6C7929200A0A2020202020202A204D7953514C2041646D696E20436F6F6B626F6F6B0A2020202020202020202020206F204120717569636B20737465702D62792D7374657020677569
 64652066
 6F72204D7953514C20757365727320616E642064617461626173652061646D696E6973747261746F727320746F207461636B6C65207265616C2D776F726C64206368616C6C656E6765732077697468204D7953514C20636F6E66696775726174696F6E20616E642061646D696E697374726174696F6E200A0A2020202020202A204D7953514C20352E302043657274696669636174696F6E2053747564792047756964652C204279205061756C204475426F69732C2053746566616E2048696E7A2C204361727374656E20506564657273656E0A2020202020202020202020206F205468697320697320746865206F6666696369616C20677569646520746F20636F766572207468652070617373696E67206F66207468652074776F204D7953514C2043657274696669636174696F6E206578616D696E6174696F6E732E2049742069732076616C69642074696C6C2076657273696F6E20352E30206F6620746865207365727665722C20736F207768696C65206974206D697373657320616C6C2074686520666561747572657320617661696C61626C6520696E204D7953514C20352E3120616E6420677265617465722028696E636C7564696E67204D61726961444220352E3120616E642067726561746572292C2069742070726F7669646573206120676F6F6420626173696
 320756E6
 465727374616E64696E67206F66204D7953514C20666F722074686520656E642D757365722E20
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 1
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'v64' at row 1
+Warning	1265	Data truncated for column 'v65000' at row 1
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 5
+Warning	1265	Data truncated for column 'v1' at row 5
+Warning	1265	Data truncated for column 'v64' at row 5
+Warning	1265	Data truncated for column 'v0' at row 6
+Warning	1265	Data truncated for column 'v1' at row 6
+Warning	1265	Data truncated for column 'v64' at row 6
+Warning	1265	Data truncated for column 'v65000' at row 6
+SELECT HEX(v0), HEX(v1), HEX(v64), LENGTH(HEX(v65000)) FROM t1;
+HEX(v0)	HEX(v1)	HEX(v64)	LENGTH(HEX(v65000))
+			0
+		61	0
+	48	61486572652069732061206C697374206F66207265636F6D6D656E64656420626F6F6B73206F6E204D61726961444220616E64204D7953514C2E205765277665	5932
+	61	61616263646566676869206162636465666768692061626364656667686920616263646566676869206162636465666768692061626364656667686920616263	130000
+	79	4F6E63652074686572652C20646F75626C6520636865636B207468617420616E2061727469636C6520646F65736E277420616C7265616479206578697374	5930
+	79	63636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363	130000
+ALTER TABLE t1 ADD COLUMN v65536 VARBINARY(65536) ;
+Warnings:
+Note	1246	Converting column 'v65536' from VARBINARY to BLOB
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varbinary(0)	YES		NULL	
+v1	varbinary(1)	YES		NULL	
+v64	varbinary(64)	NO	PRI		
+v65000	varbinary(65000)	YES		NULL	
+v65536	mediumblob	YES		NULL	
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/type_varbinary.test b/mysql-test/suite/leveldb/type_varbinary.test
new file mode 100644
index 0000000..b56d1c5
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_varbinary.test
@@ -0,0 +1,6 @@
+#
+# VARBINARY column types
+#
+
+--source type_varbinary.inc
+
diff --git a/mysql-test/suite/leveldb/type_varchar.inc b/mysql-test/suite/leveldb/type_varchar.inc
new file mode 100644
index 0000000..59cb230
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_varchar.inc
@@ -0,0 +1,77 @@
+#
+# VARCHAR column types
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+  v0 VARCHAR(0) $extra_col_opts,
+  v1 VARCHAR(1) $extra_col_opts,
+  v64 VARCHAR(64) $extra_col_opts,
+  v65000 VARCHAR(65000) $extra_col_opts,
+  PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+
+SHOW COLUMNS IN t1;
+
+CREATE TABLE t2 (v VARCHAR(65532), PRIMARY KEY (v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+
+# Valid values 
+
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+
+--sorted_result
+SELECT v0,v1,v64,v65000 FROM t1;
+
+# Invalid values
+
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+
+--sorted_result
+SELECT v0, v1, v64, LENGTH(v65000) FROM t1;
+
+eval ALTER TABLE t1 ADD COLUMN v65536 VARCHAR(65536) $extra_col_opts;
+SHOW COLUMNS IN t1;
+
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/type_varchar.result b/mysql-test/suite/leveldb/type_varchar.result
new file mode 100644
index 0000000..1a09db5
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_varchar.result
@@ -0,0 +1,128 @@
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (
+v0 VARCHAR(0) ,
+v1 VARCHAR(1) ,
+v64 VARCHAR(64) ,
+v65000 VARCHAR(65000) ,
+PRIMARY KEY (v64)
+) ENGINE=LevelDB;
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varchar(0)	YES		NULL	
+v1	varchar(1)	YES		NULL	
+v64	varchar(64)	NO	PRI		
+v65000	varchar(65000)	YES		NULL	
+CREATE TABLE t2 (v VARCHAR(65532), PRIMARY KEY (v(255))) ENGINE=LevelDB;
+SHOW COLUMNS IN t2;
+Field	Type	Null	Key	Default	Extra
+v	varchar(65532)	NO	PRI		
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','','','');
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('','y','Once there, double check that an article doesn\'t already exist','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+  For developers who want to code on MariaDB or MySQL
+
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+
+  For MariaDB / MySQL end users
+
+      * MariaDB Crash Course by Ben Forta
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o Free to read in the Knowledgebase! 
+
+      * MySQL (4th Edition) by Paul DuBois
+            o The \'default\' book to read if you wont to learn to use MySQL / MariaDB. 
+
+      * MySQL Cookbook by Paul DuBois
+            o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject. 
+
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+            o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly) 
+
+      * MySQL Admin Cookbook
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ');
+SELECT v0,v1,v64,v65000 FROM t1;
+v0	v1	v64	v65000
+
+
+
+
+
+
+
+
+
+
+			
+	y	Once there, double check that an article doesn't already exist	Here is a list of recommended books on MariaDB and MySQL. We've provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+            o "High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL's full power." (From the book description at O'Reilly) 
+            o A lot of examples of how to use MySQL. As with all of Paul's books, it's worth its weight in gold and even enjoyable reading for such a 'dry' subject. 
+            o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB! 
+            o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration 
+            o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+            o First MariaDB book!
+            o For people who want to learn SQL and the basics of MariaDB.
+            o Free to read in the Knowledgebase! 
+            o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic. 
+            o Now shipping. Purchase at Amazon.com or your favorite bookseller. 
+            o The 'default' book to read if you wont to learn to use MySQL / MariaDB. 
+            o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. 
+            o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+      * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+      * MariaDB Crash Course by Ben Forta
+      * MySQL (4th Edition) by Paul DuBois
+      * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+      * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+      * MySQL Admin Cookbook
+      * MySQL Cookbook by Paul DuBois
+      * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+      * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+  For MariaDB / MySQL end users
+  For developers who want to code on MariaDB or MySQL
+  If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+INSERT INTO t1 (v0,v1,v64,v65000) VALUES ('y', 'yy', REPEAT('c',65), REPEAT('abcdefghi ',6501));
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 1
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'v64' at row 1
+Warning	1265	Data truncated for column 'v65000' at row 1
+INSERT INTO t1 (v0,v1,v64,v65000) SELECT v65000, v65000, CONCAT('a',v65000), CONCAT(v65000,v1) FROM t1;
+Warnings:
+Warning	1265	Data truncated for column 'v0' at row 5
+Warning	1265	Data truncated for column 'v1' at row 5
+Warning	1265	Data truncated for column 'v64' at row 5
+Warning	1265	Data truncated for column 'v65000' at row 5
+Warning	1265	Data truncated for column 'v0' at row 6
+Warning	1265	Data truncated for column 'v1' at row 6
+Warning	1265	Data truncated for column 'v64' at row 6
+SELECT v0, v1, v64, LENGTH(v65000) FROM t1;
+v0	v1	v64	LENGTH(v65000)
+			0
+		a	0
+	H	aHere is a list of recommended books on MariaDB and MySQL. We've	2966
+	a	aabcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abcdefghi abc	65000
+	y	Once there, double check that an article doesn't already exist	2965
+	y	cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc	65000
+ALTER TABLE t1 ADD COLUMN v65536 VARCHAR(65536) ;
+Warnings:
+Note	1246	Converting column 'v65536' from VARCHAR to TEXT
+SHOW COLUMNS IN t1;
+Field	Type	Null	Key	Default	Extra
+v0	varchar(0)	YES		NULL	
+v1	varchar(1)	YES		NULL	
+v64	varchar(64)	NO	PRI		
+v65000	varchar(65000)	YES		NULL	
+v65536	mediumtext	YES		NULL	
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/type_varchar.test b/mysql-test/suite/leveldb/type_varchar.test
new file mode 100644
index 0000000..002098a
--- /dev/null
+++ b/mysql-test/suite/leveldb/type_varchar.test
@@ -0,0 +1,6 @@
+#
+# VARCHAR column types
+#
+
+--source type_varchar.inc
+
diff --git a/mysql-test/suite/leveldb/update.result b/mysql-test/suite/leveldb/update.result
new file mode 100644
index 0000000..788f607
--- /dev/null
+++ b/mysql-test/suite/leveldb/update.result
@@ -0,0 +1,113 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+UPDATE t1 SET a=a+100;
+SELECT a,b FROM t1;
+a	b
+101	a
+101	a
+10100	foobar
+10100	foobar
+102	b
+102	b
+103	c
+103	c
+104	d
+104	d
+105	e
+105	e
+UPDATE t1 SET a=a-100, b=DEFAULT WHERE a>100;
+SELECT a,b FROM t1;
+a	b
+1	NULL
+1	NULL
+10000	NULL
+10000	NULL
+2	NULL
+2	NULL
+3	NULL
+3	NULL
+4	NULL
+4	NULL
+5	NULL
+5	NULL
+UPDATE t1 SET b = 'update' WHERE a <= 4 ORDER BY b DESC, a ASC LIMIT 1;
+SELECT a,b FROM t1;
+a	b
+1	NULL
+1	update
+10000	NULL
+10000	NULL
+2	NULL
+2	NULL
+3	NULL
+3	NULL
+4	NULL
+4	NULL
+5	NULL
+5	NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+BEGIN;
+UPDATE t1 SET a=a+100;
+UPDATE t1 SET a=a-50, b=DEFAULT WHERE a>100;
+COMMIT;
+SELECT * FROM t1 ORDER BY pk;
+a	b	pk
+10050	NULL	12
+10050	NULL	6
+51	NULL	1
+51	NULL	7
+52	NULL	2
+52	NULL	8
+53	NULL	3
+53	NULL	9
+54	NULL	10
+54	NULL	4
+55	NULL	11
+55	NULL	5
+BEGIN;
+UPDATE t1 SET b = 'update' WHERE a <= 4 ORDER BY a DESC, b ASC LIMIT 3;
+UPDATE t1 SET b = '';
+ROLLBACK;
+SELECT * FROM t1 ORDER BY pk;
+a	b	pk
+51	NULL	1
+52	NULL	2
+53	NULL	3
+54	NULL	4
+55	NULL	5
+10050	NULL	6
+51	NULL	7
+52	NULL	8
+53	NULL	9
+54	NULL	10
+55	NULL	11
+10050	NULL	12
+BEGIN;
+UPDATE t1 SET b = 'update2' WHERE a <= 100;
+SAVEPOINT spt1;
+ERROR 42000: The storage engine for the table doesn't support SAVEPOINT
+UPDATE t1 SET b = '';
+ROLLBACK TO SAVEPOINT spt1;
+ERROR 42000: SAVEPOINT spt1 does not exist
+UPDATE t1 SET b = 'upd' WHERE a = 10050;
+COMMIT;
+SELECT * FROM t1 ORDER BY pk;
+a	b	pk
+51		1
+52		2
+53		3
+54		4
+55		5
+10050	upd	6
+51		7
+52		8
+53		9
+54		10
+55		11
+10050	upd	12
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/update.test b/mysql-test/suite/leveldb/update.test
new file mode 100644
index 0000000..50b3849
--- /dev/null
+++ b/mysql-test/suite/leveldb/update.test
@@ -0,0 +1,70 @@
+# 
+# Basic UPDATE statements.
+# UPDATE LOW_PRIORITY is covered in update_low_prio test
+# UPDATE IGNORE is covered in update_ignore test
+# Multi-table update is covered in update_multi test
+#
+
+########################################
+# TODO:
+# The results of the transactional part
+# are unusual due to "can't-see-own-changes"
+########################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+UPDATE t1 SET a=a+100;
+--sorted_result
+SELECT a,b FROM t1;
+
+UPDATE t1 SET a=a-100, b=DEFAULT WHERE a>100;
+--sorted_result
+SELECT a,b FROM t1;
+
+# ORDER BY and LIMIT
+UPDATE t1 SET b = 'update' WHERE a <= 4 ORDER BY b DESC, a ASC LIMIT 1;
+--sorted_result
+SELECT a,b FROM t1;
+
+DROP TABLE t1;
+
+# 
+# Transactional UPDATE
+#
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+BEGIN;
+UPDATE t1 SET a=a+100;
+UPDATE t1 SET a=a-50, b=DEFAULT WHERE a>100;
+COMMIT;
+--sorted_result
+SELECT * FROM t1 ORDER BY pk;
+
+BEGIN;
+UPDATE t1 SET b = 'update' WHERE a <= 4 ORDER BY a DESC, b ASC LIMIT 3;
+UPDATE t1 SET b = '';
+ROLLBACK;
+SELECT * FROM t1 ORDER BY pk;
+
+BEGIN;
+UPDATE t1 SET b = 'update2' WHERE a <= 100;
+--error ER_CHECK_NOT_IMPLEMENTED
+SAVEPOINT spt1;
+UPDATE t1 SET b = '';
+--error ER_SP_DOES_NOT_EXIST
+ROLLBACK TO SAVEPOINT spt1;
+UPDATE t1 SET b = 'upd' WHERE a = 10050;
+COMMIT;
+SELECT * FROM t1 ORDER BY pk;
+
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/leveldb/update_ignore.result b/mysql-test/suite/leveldb/update_ignore.result
new file mode 100644
index 0000000..3623ac5
--- /dev/null
+++ b/mysql-test/suite/leveldb/update_ignore.result
@@ -0,0 +1,58 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+CREATE TABLE t2 (c CHAR(8), d INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+UPDATE IGNORE t1 SET b = 'upd1' WHERE b IS NOT NULL ORDER BY a LIMIT 1;
+SELECT a,b FROM t1 ORDER BY pk;
+a	b
+1	upd1
+2	b
+3	c
+4	d
+5	e
+10000	foobar
+1	a
+2	b
+3	c
+4	d
+5	e
+10000	foobar
+UPDATE t1, t2 SET b = 'upd2a', c = 'upd2b' 
+WHERE c < b OR a != ( SELECT 1 UNION SELECT 2 );
+ERROR 21000: Subquery returns more than 1 row
+UPDATE IGNORE t1, t2 SET b = 'upd2a', c = 'upd2b' 
+WHERE c < b OR a != ( SELECT 1 UNION SELECT 2 );
+Warnings:
+Error	1242	Subquery returns more than 1 row
+Error	1105	Unknown error
+SELECT a,b FROM t1 ORDER BY pk;
+a	b
+1	upd2a
+2	upd2a
+3	upd2a
+4	upd2a
+5	upd2a
+10000	upd2a
+1	a
+2	upd2a
+3	upd2a
+4	upd2a
+5	upd2a
+10000	upd2a
+SELECT c,d FROM t2 ORDER BY pk;
+c	d
+upd2b	1
+upd2b	2
+upd2b	3
+upd2b	4
+upd2b	5
+upd2b	10000
+upd2b	1
+upd2b	2
+upd2b	3
+upd2b	4
+upd2b	5
+upd2b	10000
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/update_ignore.test b/mysql-test/suite/leveldb/update_ignore.test
new file mode 100644
index 0000000..44463ac
--- /dev/null
+++ b/mysql-test/suite/leveldb/update_ignore.test
@@ -0,0 +1,33 @@
+# 
+# UPDATE IGNORE
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+CREATE TABLE t2 (c CHAR(8), d INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+
+UPDATE IGNORE t1 SET b = 'upd1' WHERE b IS NOT NULL ORDER BY a LIMIT 1;
+SELECT a,b FROM t1 ORDER BY pk;
+
+--error ER_SUBQUERY_NO_1_ROW
+UPDATE t1, t2 SET b = 'upd2a', c = 'upd2b' 
+  WHERE c < b OR a != ( SELECT 1 UNION SELECT 2 );
+
+UPDATE IGNORE t1, t2 SET b = 'upd2a', c = 'upd2b' 
+  WHERE c < b OR a != ( SELECT 1 UNION SELECT 2 );
+
+SELECT a,b FROM t1 ORDER BY pk;
+SELECT c,d FROM t2 ORDER BY pk;
+
+# Cleanup
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/update_multi.result b/mysql-test/suite/leveldb/update_multi.result
new file mode 100644
index 0000000..3ac059f
--- /dev/null
+++ b/mysql-test/suite/leveldb/update_multi.result
@@ -0,0 +1,65 @@
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+CREATE TABLE t2 (c CHAR(8), d INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+UPDATE t1, t2 SET t1.a = t2.d+100, t2.c = 'multi' WHERE c < b AND a + d != 1;
+SELECT a,b FROM t1;
+a	b
+1	a
+1	a
+101	b
+101	b
+101	c
+101	c
+101	d
+101	d
+101	e
+101	e
+101	foobar
+101	foobar
+SELECT c,d FROM t2;
+c	d
+foobar	10000
+foobar	10000
+multi	1
+multi	1
+multi	2
+multi	2
+multi	3
+multi	3
+multi	4
+multi	4
+multi	5
+multi	5
+UPDATE t2, t1 SET t2.d = DEFAULT WHERE c = 'foobar' and b = c;
+SELECT a,b FROM t1;
+a	b
+1	a
+1	a
+101	b
+101	b
+101	c
+101	c
+101	d
+101	d
+101	e
+101	e
+101	foobar
+101	foobar
+SELECT c,d FROM t2;
+c	d
+foobar	NULL
+foobar	NULL
+multi	1
+multi	1
+multi	2
+multi	2
+multi	3
+multi	3
+multi	4
+multi	4
+multi	5
+multi	5
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/leveldb/update_multi.test b/mysql-test/suite/leveldb/update_multi.test
new file mode 100644
index 0000000..9872e40
--- /dev/null
+++ b/mysql-test/suite/leveldb/update_multi.test
@@ -0,0 +1,30 @@
+# 
+# Multi-table UPDATE statements.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+INSERT INTO t1 (a,b) SELECT a, b FROM t1;
+
+CREATE TABLE t2 (c CHAR(8), d INT, pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t2 (c,d) SELECT b, a FROM t1;
+
+UPDATE t1, t2 SET t1.a = t2.d+100, t2.c = 'multi' WHERE c < b AND a + d != 1;
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+UPDATE t2, t1 SET t2.d = DEFAULT WHERE c = 'foobar' and b = c;
+--sorted_result
+SELECT a,b FROM t1;
+--sorted_result
+SELECT c,d FROM t2;
+
+# Cleanup
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/suite/leveldb/update_with_keys.result b/mysql-test/suite/leveldb/update_with_keys.result
new file mode 100644
index 0000000..88ac82a
--- /dev/null
+++ b/mysql-test/suite/leveldb/update_with_keys.result
@@ -0,0 +1,39 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, INDEX(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'x'),(7,'y'),(8,'z');
+UPDATE t1 SET a=100, b='f' WHERE b IN ('b','c');
+UPDATE t1 SET b='m' WHERE b = 'f';
+UPDATE t1 SET b='z' WHERE a < 2;
+UPDATE t1 SET b='';
+SELECT a,b FROM t1;
+a	b
+1	
+100	
+100	
+4	
+5	
+6	
+7	
+8	
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, UNIQUE INDEX(a)) ENGINE=LevelDB;
+ERROR HY000: Got error 187 'Unique indexes are not supported' from LEVELDB
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(0,'f'),(100,'a');
+UPDATE t1 SET a=a+200;
+UPDATE t1 SET a=0 WHERE a > 250;
+UPDATE t1 SET a=205 WHERE a=200;
+ERROR 23000: Duplicate entry '205' for key 'PRIMARY'
+UPDATE t1 SET a=12345 ORDER BY a DESC, b LIMIT 1;
+SELECT a,b FROM t1;
+a	b
+0	a
+12345	e
+200	f
+201	a
+202	b
+203	c
+204	d
+UPDATE t1 SET a=80 WHERE a IN (202,203);
+ERROR 23000: Duplicate entry '80' for key 'PRIMARY'
+DROP TABLE t1;
diff --git a/mysql-test/suite/leveldb/update_with_keys.test b/mysql-test/suite/leveldb/update_with_keys.test
new file mode 100644
index 0000000..95414da
--- /dev/null
+++ b/mysql-test/suite/leveldb/update_with_keys.test
@@ -0,0 +1,75 @@
+# 
+# UPDATE statements for tables with keys
+#
+
+#############################################
+# TODO:
+# The test doesn't work quite as expected,
+# apparently due to "can't see own changes"
+#############################################
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, INDEX(b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'x'),(7,'y'),(8,'z');
+UPDATE t1 SET a=100, b='f' WHERE b IN ('b','c');
+UPDATE t1 SET b='m' WHERE b = 'f';
+UPDATE t1 SET b='z' WHERE a < 2;
+UPDATE t1 SET b='';
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+--error ER_GET_ERRMSG
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, UNIQUE INDEX(a)) ENGINE=LevelDB;
+
+--disable_parsing
+
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(0,'f'),(100,'a');
+UPDATE t1 SET a=a+200;
+UPDATE t1 SET a=0 WHERE a > 250;
+--error ER_DUP_ENTRY
+UPDATE t1 SET a=205 WHERE a=200;
+UPDATE t1 SET a=12345 ORDER BY a, b LIMIT 1;
+--sorted_result
+SELECT a,b FROM t1;
+
+--error ER_DUP_ENTRY
+UPDATE t1 SET a=80 WHERE a IN (202,203);
+--sorted_result
+SELECT a,b FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT, b CHAR(8), pk INT AUTO_INCREMENT PRIMARY KEY, UNIQUE INDEX(a,b)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(100,'a'),(6,'f');
+UPDATE t1 SET a=6 WHERE a=3; 
+--error ER_DUP_ENTRY
+UPDATE t1 SET a=100 WHERE a=1;
+--error ER_DUP_ENTRY
+UPDATE t1 SET a=4, b='d' WHERE b='f';
+UPDATE t1 SET a=a+1;
+--sorted_result
+SELECT a,b FROM t1;
+--error ER_DUP_ENTRY
+UPDATE t1 SET b='z';
+DROP TABLE t1;
+
+--enable_parsing
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b CHAR(8)) ENGINE=LevelDB;
+INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(0,'f'),(100,'a');
+UPDATE t1 SET a=a+200;
+UPDATE t1 SET a=0 WHERE a > 250;
+--error ER_DUP_ENTRY
+UPDATE t1 SET a=205 WHERE a=200;
+UPDATE t1 SET a=12345 ORDER BY a DESC, b LIMIT 1;
+
+--sorted_result
+SELECT a,b FROM t1;
+
+--error ER_DUP_ENTRY
+UPDATE t1 SET a=80 WHERE a IN (202,203);
+DROP TABLE t1;
+
diff --git a/mysql-test/t/leveldb.test b/mysql-test/t/leveldb.test
new file mode 100644
index 0000000..b5806c4
--- /dev/null
+++ b/mysql-test/t/leveldb.test
@@ -0,0 +1,1053 @@
+#
+# LevelDB Storage Engine tests
+#
+select * from information_schema.engines where engine = 'leveldb';
+
+--disable_warnings
+drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+drop table if exists t11,t12,t13,t14,t15,t16,t17,t18,t19,t20;
+drop table if exists t21,t22,t23,t24,t25,t26,t27,t28,t29;
+drop table if exists t30,t31,t32,t33,t34,t35,t36,t37,t38,t39;
+drop table if exists t40,t41,t42,t43,t44,t45,t46,t47,t48,t49;
+--enable_warnings
+create table t0 (a int primary key) engine=leveldb;
+show create table t0;
+drop table t0;
+
+--echo # Try creating a table without PK:
+--error ER_REQUIRES_PRIMARY_KEY
+create table t1(a int) engine=leveldb;
+
+create table t1 (a int primary key, b int) engine=leveldb;
+insert into t1 values (1,1);
+insert into t1 values (2,2);
+
+select * from t1;
+
+--echo # Check that we can create another table and insert there
+create table t2 (a varchar(10) primary key, b varchar(10)) engine=leveldb;
+insert into t2 value ('abc','def');
+insert into t2 value ('hijkl','mnopq');
+select * from t2;
+
+--echo # Select again from t1 to see that records from different tables dont mix
+select * from t1;
+
+explain select * from t2 where a='no-such-key';
+explain select * from t2 where a='abc';
+select * from t2 where a='abc';
+
+--echo # Try a composite PK
+create table t3 (
+  pk1 int, 
+  pk2 varchar(10),
+  col1 varchar(10),
+  primary key(pk1, pk2)
+) engine=leveldb;
+
+insert into t3 values (2,'two', 'row#2');
+insert into t3 values (3,'three', 'row#3');
+insert into t3 values (1,'one', 'row#1');
+
+select * from t3;
+select * from t3 where pk1=3 and pk2='three';
+
+drop table t1, t2, t3;
+
+--echo # 
+--echo # Test blob values
+--echo #
+
+create table t4 (a int primary key, b blob) engine=leveldb;
+insert into t4 values (1, repeat('quux-quux', 60));
+insert into t4 values (10, repeat('foo-bar', 43));
+insert into t4 values (5, repeat('foo-bar', 200));
+
+insert into t4 values (2, NULL);
+
+
+select 
+ a,
+ (case a 
+   when 1  then b=repeat('quux-quux', 60)
+   when 10 then b=repeat('foo-bar', 43)
+   when 5  then b=repeat('foo-bar', 200)
+   when 2  then b is null
+   else 'IMPOSSIBLE!' end) as CMP
+from t4;
+
+drop table t4;
+
+--echo #
+--echo # Test blobs of various sizes
+--echo # 
+
+--echo # TINYBLOB
+create table t5 (a int primary key, b tinyblob) engine=leveldb;
+insert into t5 values (1, repeat('quux-quux', 6));
+insert into t5 values (10, repeat('foo-bar', 4));
+insert into t5 values (5, repeat('foo-bar', 2));
+select 
+ a,
+ (case a 
+   when 1  then b=repeat('quux-quux', 6)
+   when 10 then b=repeat('foo-bar', 4)
+   when 5  then b=repeat('foo-bar', 2)
+   else 'IMPOSSIBLE!' end) as CMP
+from t5;
+drop table t5;
+
+--echo # MEDIUMBLOB
+create table t6 (a int primary key, b mediumblob) engine=leveldb;
+insert into t6 values (1, repeat('AB', 65000));
+insert into t6 values (10, repeat('bbb', 40000));
+insert into t6 values (5, repeat('foo-bar', 2));
+select 
+ a,
+ (case a 
+   when 1  then b=repeat('AB', 65000)
+   when 10 then b=repeat('bbb', 40000)
+   when 5  then b=repeat('foo-bar', 2)
+   else 'IMPOSSIBLE!' end) as CMP
+from t6;
+drop table t6;
+
+--echo # LONGBLOB
+create table t7 (a int primary key, b longblob) engine=leveldb;
+insert into t7 values (1, repeat('AB', 65000));
+insert into t7 values (10, repeat('bbb', 40000));
+insert into t7 values (5, repeat('foo-bar', 2));
+select 
+ a,
+ (case a 
+   when 1  then b=repeat('AB', 65000)
+   when 10 then b=repeat('bbb', 40000)
+   when 5  then b=repeat('foo-bar', 2)
+   else 'IMPOSSIBLE!' end) as CMP
+from t7;
+drop table t7;
+
+
+--echo #
+--echo # Check if DELETEs work
+--echo # 
+create table t8 (a varchar(10) primary key, col1 varchar(12)) engine=leveldb;
+
+insert into t8 values 
+ ('one', 'eins'),
+ ('two', 'zwei'),
+ ('three', 'drei'),
+ ('four', 'vier'),
+ ('five', 'funf');
+
+--echo # Delete by PK
+explain delete from t8 where a='three';
+delete from t8 where a='three';
+
+select * from t8;
+
+--echo # Delete while doing a full table scan
+delete from t8 where col1='eins' or col1='vier';
+select * from t8;
+
+--echo # delete w/o WHERE:
+delete from t8;
+select * from t8;
+
+--echo #
+--echo # Test UPDATEs
+--echo #
+insert into t8 values 
+ ('one', 'eins'),
+ ('two', 'zwei'),
+ ('three', 'drei'),
+ ('four', 'vier'),
+ ('five', 'funf');
+
+update t8 set col1='dva' where a='two';
+
+update t8 set a='fourAAA' where col1='vier';
+
+select * from t8;
+delete from t8;
+
+--echo #
+--echo # Basic transactions tests
+--echo #
+begin; 
+insert into t8 values ('trx1-val1', 'data');
+insert into t8 values ('trx1-val2', 'data');
+rollback;
+select * from t8;
+
+begin; 
+insert into t8 values ('trx1-val1', 'data');
+insert into t8 values ('trx1-val2', 'data');
+commit;
+select * from t8;
+
+drop table t8;
+
+--echo #
+--echo # Check if DROP TABLE works
+--echo #
+create table t8 (a varchar(10) primary key, col1 varchar(12)) engine=leveldb;
+select * from t8;
+insert into t8 values ('foo','foo');
+drop table t8;
+create table t8 (a varchar(10) primary key, col1 varchar(12)) engine=leveldb;
+select * from t8;
+drop table t8;
+
+--echo #
+--echo # MDEV-3961: Assertion ... on creating a TEMPORARY LevelDB table
+--echo #
+--error ER_ILLEGAL_HA_CREATE_OPTION
+CREATE TEMPORARY TABLE t10 (pk INT PRIMARY KEY) ENGINE=LevelDB;
+
+--echo #
+--echo # MDEV-3963: JOIN or WHERE conditions involving keys on LevelDB tables don't work
+--echo #
+CREATE TABLE t10 (i INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t10 VALUES (1),(3);
+CREATE TABLE t11 (j INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t11 VALUES (1),(4);
+
+select * from t10;
+select * from t11;
+EXPLAIN
+SELECT * FROM t10, t11 WHERE i=j;
+SELECT * FROM t10, t11 WHERE i=j;
+
+DROP TABLE t10,t11;
+
+--echo #
+--echo # MDEV-3962: SELECT with ORDER BY causes "ERROR 1030 (HY000): Got error 122
+--echo #
+CREATE TABLE t12 (pk INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t12 VALUES (2),(1);
+SELECT * FROM t12 ORDER BY pk;
+DROP TABLE t12;
+
+--echo #
+--echo # MDEV-3964: Assertion `!pk_descr' fails in ha_leveldb::open on adding partitions ...
+--echo #
+create table t14 (pk int primary key) engine=LevelDB partition by hash(pk) partitions 2;
+#--error ER_GET_ERRNO
+#alter table t14 add partition partitions 2;
+# ^^ works, but causes weird warnings in error log.
+drop table t14;
+
+--echo #
+--echo # MDEV-3960: Server crashes on running DISCARD TABLESPACE on a LevelDB table
+--echo #
+create table t9 (i int primary key) engine=leveldb;
+--error ER_ILLEGAL_HA
+alter table t9 discard tablespace;
+drop table t9;
+
+--echo #
+--echo # MDEV-3959: Assertion `slice->size() == table->s->reclength' fails ...
+--echo #   on accessing a table after ALTER
+--echo #
+CREATE TABLE t15 (a INT, leveldb_pk INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t15 VALUES (1,1),(5,2);
+#--error ER_ILLEGAL_HA
+ALTER TABLE t15 DROP COLUMN a;
+DROP TABLE t15;
+
+--echo #
+--echo # MDEV-3968: UPDATE produces a wrong result while modifying a PK on a LevelDB table
+--echo #
+create table t16 (pk int primary key, a char(8)) engine=LevelDB;
+insert into t16 values (1,'a'),(2,'b'),(3,'c'),(4,'d');
+
+# 
+# Not anymore: The following query will still eat a record because of CANT-SEE-OWN-CHANGES
+# property. 
+#
+--error ER_DUP_ENTRY
+update t16 set pk=100, a = 'updated' where a in ('b','c');
+select * from t16;
+drop table t16;
+
+--echo #
+--echo # MDEV-3970: A set of assorted crashes on inserting a row into a LevelDB table 
+--echo #
+--disable_warnings
+drop table if exists t_very_long_table_name;
+--enable_warnings
+
+CREATE TABLE `t_very_long_table_name` (
+   `c` char(1) NOT NULL,
+   `c0` char(0) NOT NULL,
+   `c1` char(1) NOT NULL,
+   `c20` char(20) NOT NULL,
+   `c255` char(255) NOT NULL,
+   PRIMARY KEY (`c255`)
+ ) ENGINE=LevelDB DEFAULT CHARSET=latin1;
+INSERT INTO t_very_long_table_name VALUES ('a', '', 'c', REPEAT('a',20), REPEAT('x',255));
+drop table t_very_long_table_name;
+
+
+--echo #
+--echo # Test table locking and read-before-write checks.
+--echo #
+create table t17 (pk varchar(12) primary key, col1 varchar(12)) engine=leveldb;
+insert into t17 values ('row1', 'val1');
+
+--error ER_DUP_ENTRY
+insert into t17 values ('row1', 'val1-try2');
+--error ER_DUP_ENTRY
+insert into t17 values ('ROW1', 'val1-try2');
+
+insert into t17 values ('row2', 'val2');
+insert into t17 values ('row3', 'val3');
+
+--echo # This is ok
+update t17 set pk='row4' where pk='row1';
+
+--echo # This will try to overwrite another row:
+--error ER_DUP_ENTRY
+update t17 set pk='row3' where pk='row2';
+
+select * from t17;
+
+--echo #
+--echo # Locking tests
+--echo #
+
+connect (con1,localhost,root,,);
+
+--echo # First, make sure there's no locking when transactions update different rows
+connection con1;
+set autocommit=0;
+update t17 set col1='UPD1' where pk='row2';
+
+connection default;
+update t17 set col1='UPD2' where pk='row3';
+
+connection con1;
+commit;
+
+connection default;
+select * from t17;
+
+--echo # Check the variable
+show variables like 'leveldb_lock_wait_timeout';
+set leveldb_lock_wait_timeout=2; # seconds
+show variables like 'leveldb_lock_wait_timeout';
+
+--echo # Try updating the same row from two transactions
+connection con1;
+begin;
+update t17 set col1='UPD2-AA' where pk='row2';
+
+connection default;
+--error ER_LOCK_WAIT_TIMEOUT
+update t17 set col1='UPD2-BB' where pk='row2';
+
+set leveldb_lock_wait_timeout=1000; # seconds
+--send 
+  update t17 set col1='UPD2-CC' where pk='row2';
+
+connection con1;
+rollback;
+
+connection default;
+reap;
+select * from t17 where pk='row2';
+
+drop table t17;
+
+disconnect con1;
+--echo #
+--echo #  MDEV-4035: LevelDB: SELECT produces different results inside a transaction (read is not repeatable)
+--echo #
+--enable_connect_log
+
+create table t18 (pk int primary key, i int) engine=LevelDB;
+begin;
+select * from t18;
+select * from t18 where pk = 1;
+
+--connect (con1,localhost,root,,)
+insert into t18 values (1,100);
+
+--connection default
+select * from t18;
+select * from t18 where pk = 1;
+commit;
+
+drop table t18;
+
+--echo #
+--echo # MDEV-4036: LevelDB: INSERT .. ON DUPLICATE KEY UPDATE does not work, produces ER_DUP_KEY
+--echo #
+create table t19 (pk int primary key, i int) engine=LevelDB;
+insert into t19 values (1,1);
+insert into t19 values (1,100) on duplicate key update i = 102;
+select * from t19;
+drop table t19;
+
+--echo # MDEV-4037: LevelDB: REPLACE doesn't work, produces ER_DUP_KEY
+create table t20 (pk int primary key, i int) engine=LevelDB;
+insert into t20 values (1,1);
+replace into t20 values (1,100);
+select * from t20;
+drop table t20;
+
+--echo #
+--echo # MDEV-4041: Server crashes in Primary_key_comparator::get_hashnr on INSERT 
+--echo #
+create table t21 (v varbinary(16) primary key, i int) engine=LevelDB;
+insert into t21 values ('a',1);
+select * from t21;
+drop table t21;
+
+--echo #
+--echo # MDEV-4047: LevelDB: Assertion `0' fails in Protocol::end_statement() on multi-table INSERT IGNORE
+--echo #
+
+CREATE TABLE t22 (a int primary key) ENGINE=LevelDB;
+INSERT INTO t22 VALUES (1),(2);
+CREATE TABLE t23 (b int primary key) ENGINE=LevelDB;
+INSERT INTO t23 SELECT * FROM t22;
+DELETE IGNORE t22.*, t23.* FROM t22, t23 WHERE b < a;
+DROP TABLE t22,t23;
+
+--echo #
+--echo # MDEV-4046: LevelDB: Multi-table DELETE locks itself and ends with ER_LOCK_WAIT_TIMEOUT
+--echo #
+CREATE TABLE t24 (pk int primary key) ENGINE=LevelDB;
+INSERT INTO t24 VALUES (1),(2);
+
+CREATE TABLE t25 LIKE t24;
+INSERT INTO t25 SELECT * FROM t24;
+
+DELETE t25.* FROM t24, t25;
+DROP TABLE t24,t25;
+
+--echo #
+--echo # MDEV-4044: LevelDB: UPDATE or DELETE with ORDER BY locks itself
+--echo #
+create table t26 (pk int primary key, c char(1)) engine=LevelDB;
+insert into t26 values (1,'a'),(2,'b');
+update t26 set c = 'x' order by pk limit 1;
+delete from t26 order by pk limit 1;
+select * from t26;
+drop table t26;
+
+
+--echo #
+--echo # Test whether SELECT ... FOR UPDATE puts locks
+--echo #
+create table t27(pk varchar(10) primary key, col1 varchar(20)) engine=LevelDB;
+insert into t27 values 
+  ('row1', 'row1data'),
+  ('row2', 'row2data'),
+  ('row3', 'row3data');
+
+connection con1;
+begin;
+select * from t27 where pk='row3' for update;
+
+connection default;
+set leveldb_lock_wait_timeout=1;
+--error ER_LOCK_WAIT_TIMEOUT
+update t27 set col1='row2-modified' where pk='row3';
+
+connection con1;
+rollback;
+connection default;
+disconnect con1;
+
+drop table t27;
+
+--echo #
+--echo # MDEV-4060: LevelDB: Assertion `! trx->batch' fails in 
+--echo #
+create table t28 (pk int primary key, a int) engine=LevelDB;
+insert into t28 values (1,10),(2,20);
+begin;
+update t28 set a = 100 where pk = 3;
+rollback;
+select * from t28;
+drop table t28;
+
+
+--echo # 
+--echo # Secondary indexes
+--echo #
+create table t30 (
+  pk varchar(16) not null primary key, 
+  key1 varchar(16) not null, 
+  col1 varchar(16) not null,
+  key(key1)
+) engine=leveldb;
+
+insert into t30 values ('row1', 'row1-key', 'row1-data');
+insert into t30 values ('row2', 'row2-key', 'row2-data');
+insert into t30 values ('row3', 'row3-key', 'row3-data');
+
+explain
+select * from t30 where key1='row2-key';
+select * from t30 where key1='row2-key';
+
+explain 
+select * from t30 where key1='row1';
+--echo # This will produce nothing:
+select * from t30 where key1='row1';
+
+explain
+select key1 from t30;
+select key1 from t30;
+
+--echo # Create a duplicate record
+insert into t30 values ('row2a', 'row2-key', 'row2a-data');
+
+--echo # Can we see it?
+select * from t30 where key1='row2-key';
+
+delete from t30 where pk='row2';
+select * from t30 where key1='row2-key';
+
+--echo #
+--echo # Range scans on secondary index
+--echo #
+delete from t30;
+insert into t30 values 
+  ('row1', 'row1-key', 'row1-data'),
+  ('row2', 'row2-key', 'row2-data'),
+  ('row3', 'row3-key', 'row3-data'),
+  ('row4', 'row4-key', 'row4-data'),
+  ('row5', 'row5-key', 'row5-data');
+
+explain 
+select * from t30 where key1 <='row3-key'; 
+select * from t30 where key1 <='row3-key'; 
+
+explain 
+select * from t30 where key1 between 'row2-key' and 'row4-key';
+select * from t30 where key1 between 'row2-key' and 'row4-key';
+
+explain 
+select * from t30 where key1 in ('row2-key','row4-key');
+select * from t30 where key1 in ('row2-key','row4-key');
+
+explain 
+select key1 from t30 where key1 in ('row2-key','row4-key');
+select key1 from t30 where key1 in ('row2-key','row4-key');
+
+explain 
+select * from t30 where key1 > 'row1-key' and key1 < 'row4-key';
+select * from t30 where key1 > 'row1-key' and key1 < 'row4-key';
+
+explain 
+select * from t30 order by key1 limit 3;
+select * from t30 order by key1 limit 3;
+
+explain 
+select * from t30 order by key1 desc limit 3;
+select * from t30 order by key1 desc limit 3;
+
+--echo #
+--echo # Range scans on primary key
+--echo #
+explain 
+select * from t30 where pk <='row3'; 
+select * from t30 where pk <='row3'; 
+
+explain 
+select * from t30 where pk between 'row2' and 'row4';
+select * from t30 where pk between 'row2' and 'row4';
+
+explain 
+select * from t30 where pk in ('row2','row4');
+select * from t30 where pk in ('row2','row4');
+
+explain 
+select * from t30 order by pk limit 3;
+select * from t30 order by pk limit 3;
+
+drop table t30;
+
+
+--echo #
+--echo # MDEV-3841: LevelDB: Reading by PK prefix does not work
+--echo #
+create table t31 (i int, j int, k int, primary key(i,j,k)) engine=LevelDB;
+insert into t31 values (1,10,100),(2,20,200);
+select * from t31 where i = 1;
+select * from t31 where j = 10;
+select * from t31 where k = 100;
+select * from t31 where i = 1 and j = 10;
+select * from t31 where i = 1 and k = 100;
+select * from t31 where j = 10 and k = 100;
+select * from t31 where i = 1 and j = 10 and k = 100;
+drop table t31;
+
+--echo #
+--echo # MDEV-4055: LevelDB: UPDATE/DELETE by a multi-part PK does not work
+--echo #
+create table t32 (i int, j int, k int, primary key(i,j,k), a varchar(8)) engine=LevelDB;
+insert into t32 values 
+  (1,10,100,''),
+  (2,20,200,'');
+select * from t32 where i = 1 and j = 10 and k = 100;
+update t32 set a = 'updated' where i = 1 and j = 10 and k = 100;
+select * from t32;
+drop table t32;
+
+--echo #
+--echo # MDEV-3841: LevelDB: Assertion `0' fails in ha_leveldb::index_read_map on range select with ORDER BY .. DESC
+--echo #
+CREATE TABLE t33 (pk INT PRIMARY KEY, a CHAR(1)) ENGINE=LevelDB;
+INSERT INTO t33 VALUES (1,'a'),(2,'b');
+SELECT * FROM t33 WHERE pk <= 10 ORDER BY pk DESC;
+DROP TABLE t33;
+
+--echo #
+--echo # MDEV-4081: LevelDB throws error 122 on an attempt to create a table with unique index
+--echo #
+--error ER_GET_ERRMSG
+create table t33 (pk int primary key, u int, unique index(u)) engine=LevelDB;
+
+
+--echo #
+--echo # MDEV-4077: LevelDB: Wrong result (duplicate row) on select with range 
+--echo #
+CREATE TABLE t34 (pk INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t34 VALUES (10),(11);
+SELECT pk FROM t34 WHERE pk > 5 AND pk < 15;
+SELECT pk FROM t34 WHERE pk BETWEEN 5 AND 15;
+SELECT pk FROM t34 WHERE pk > 5;
+SELECT pk FROM t34 WHERE pk < 15;
+drop table t34;
+
+--echo #
+--echo # MDEV-4086: LevelDB does not allow a query with multi-part pk and index and ORDER BY .. DEC
+--echo #
+create table t35 (a int, b int, c int, d int, e int, primary key (a,b,c), key (a,c,d,e)) engine=LevelDB;
+insert into t35 values (1,1,1,1,1),(2,2,2,2,2);
+select * from t35 where a = 1 and c = 1 and d = 1 order by e desc;
+drop table t35;
+
+--echo #
+--echo # MDEV-4084: LevelDB: Wrong result on IN subquery with index
+--echo #
+CREATE TABLE t36 (pk INT PRIMARY KEY, a INT, KEY(a)) ENGINE=LevelDB;
+INSERT INTO t36 VALUES (1,10),(2,20);
+SELECT 3 IN ( SELECT a FROM t36 );
+drop table t36;
+
+--echo #
+--echo # MDEV-4084: LevelDB: Wrong result on IN subquery with index
+--echo #
+CREATE TABLE t37 (pk INT PRIMARY KEY, a INT, b CHAR(1), KEY(a), KEY(a,b)) 
+  ENGINE=LevelDB;
+INSERT INTO t37 VALUES (1,10,'x'), (2,20,'y');
+SELECT MAX(a) FROM t37 WHERE a < 100;
+DROP TABLE t37;
+
+--echo #
+--echo # MDEV-4090: LevelDB: Wrong result (duplicate rows) on range access with secondary key and ORDER BY DESC
+--echo #
+CREATE TABLE t38 (pk INT PRIMARY KEY, i INT, KEY(i)) ENGINE=LevelDB;
+INSERT INTO t38 VALUES (1,10), (2,20);
+SELECT i FROM t38 WHERE i NOT IN (8) ORDER BY i DESC;
+drop table t38;
+
+--echo #
+--echo # MDEV-4092: LevelDB: Assertion `in_table(pa, a_len)' fails in LDBSE_KEYDEF::cmp_full_keys 
+--echo #            with a multi-part key and ORDER BY .. DESC
+--echo #
+CREATE TABLE t40 (pk1 INT PRIMARY KEY, a INT, b VARCHAR(1), KEY(b,a)) ENGINE=LevelDB;
+INSERT INTO t40 VALUES (1, 7,'x'),(2,8,'y');
+
+CREATE TABLE t41 (pk2 INT PRIMARY KEY) ENGINE=LevelDB;
+INSERT INTO t41 VALUES (1),(2);
+
+SELECT * FROM t40, t41 WHERE pk1 = pk2 AND b = 'o' ORDER BY a DESC;
+DROP TABLE t40,t41;
+
+--echo #
+--echo # MDEV-4093: LevelDB: IN subquery by secondary key with NULL among values returns true instead of NULL
+--echo #
+CREATE TABLE t42 (pk INT PRIMARY KEY, a INT, KEY(a)) ENGINE=LevelDB;
+INSERT INTO t42 VALUES (1, NULL),(2, 8);
+SELECT ( 3 ) NOT IN ( SELECT a FROM t42 );
+DROP TABLE t42;
+
+--echo #
+--echo # MDEV-4094: LevelDB: Wrong result on SELECT and ER_KEY_NOT_FOUND on 
+--echo #            DELETE with search by NULL-able secondary key ...
+--echo #
+CREATE TABLE t43 (pk INT PRIMARY KEY, a INT, b CHAR(1), KEY(a)) ENGINE=LevelDB;
+INSERT INTO t43 VALUES (1,8,'g'),(2,9,'x');
+UPDATE t43 SET pk = 10 WHERE a = 8;
+REPLACE INTO t43 ( a ) VALUES ( 8 );
+REPLACE INTO t43 ( b ) VALUES ( 'y' );
+SELECT * FROM t43 WHERE a = 8;
+DELETE FROM t43 WHERE a = 8;
+DROP TABLE t43;
+
+--echo #
+--echo # Basic AUTO_INCREMENT tests
+--echo #
+create table t44(pk int primary key auto_increment, col1 varchar(12)) engine=leveldb;
+insert into t44 (col1) values ('row1');
+insert into t44 (col1) values ('row2');
+insert into t44 (col1) values ('row3');
+select * from t44;
+drop table t44;
+
+--echo #
+--echo # ALTER TABLE tests
+--echo #
+create table t45 (pk int primary key, col1 varchar(12)) engine=leveldb;
+insert into t45 values (1, 'row1');
+insert into t45 values (2, 'row2');
+alter table t45 rename t46;
+select * from t46;
+drop table t46;
+--error ER_BAD_TABLE_ERROR
+drop table t45;
+
+
+--echo #
+--echo # Check Bulk loading
+--echo #
+show variables like 'leveldb%';
+create table t47 (pk int primary key, col1 varchar(12)) engine=leveldb;
+insert into t47 values (1, 'row1');
+insert into t47 values (2, 'row2');
+set leveldb_bulk_load=1;
+insert into t47 values (1, 'row1-NEW'),(2, 'row2-NEW');
+set leveldb_bulk_load=0;
+select * from t47;
+drop table t47;
+
+--echo #
+--echo # Fix TRUNCATE over empty table (transaction is committed when it wasn't
+--echo # started)
+--echo #
+create table t48(pk int primary key auto_increment, col1 varchar(12)) engine=leveldb;
+set autocommit=0;
+#--error ER_ILLEGAL_HA
+truncate table t48;
+set autocommit=1;
+drop table t48;
+
+--echo #
+--echo # MDEV-4059: LevelDB: query waiting for a lock cannot be killed until query timeout exceeded
+--echo #
+--enable_connect_log
+
+create table t49 (pk int primary key, a int) engine=LevelDB;
+insert into t49 values (1,10),(2,20);
+begin;
+update t49 set a = 100 where pk = 1;
+
+--connect (con1,localhost,root,,)
+--let $con1_id = `SELECT CONNECTION_ID()`
+set leveldb_lock_wait_timeout=5000;
+set @var1= to_seconds(now());
+send update t49 set a = 1000 where pk = 1;
+
+--connect (con2,localhost,root,,)
+--echo kill query \$con1_id;
+--disable_query_log
+eval kill query $con1_id;
+--enable_query_log
+--connection con1
+--error ER_QUERY_INTERRUPTED
+--reap
+set @var2= to_seconds(now());
+
+select (@var2 - at var1) < 400;
+
+--connection default
+--disconnect con1
+
+commit;
+drop table t49;
+
+--echo #
+--echo # Index-only tests for INT-based columns
+--echo #
+create table t1 (pk int primary key, key1 int, col1 int, key(key1)) engine=leveldb;
+insert into t1 values (1,1,1);
+insert into t1 values (2,2,2);
+insert into t1 values (-5,-5,-5);
+--echo # INT column uses index-only:
+explain
+select key1 from t1 where key1=2;
+select key1 from t1 where key1=2;
+select key1 from t1 where key1=-5;
+drop table t1;
+
+
+create table t2 (pk int primary key, key1 int unsigned, col1 int, key(key1)) engine=leveldb;
+insert into t2 values (1,1,1), (2,2,2);
+--echo # INT UNSIGNED column uses index-only:
+explain
+select key1 from t2 where key1=2;
+select key1 from t2 where key1=2;
+drop table t2;
+
+
+create table t3 (pk bigint primary key, key1 bigint, col1 int, key(key1)) engine=leveldb;
+insert into t3 values (1,1,1), (2,2,2);
+--echo # BIGINT uses index-only:
+explain 
+select key1 from t3 where key1=2;
+select key1 from t3 where key1=2;
+drop table t3;
+
+--echo #
+--echo # Index-only reads for string columns
+--echo #
+create table t1 (
+  pk int primary key, 
+  key1 char(10) character set binary,
+  col1 int,
+  key (key1)
+) engine=leveldb;
+insert into t1 values(1, 'one',11), (2,'two',22);
+explain 
+select key1 from t1 where key1='one';
+--echo # The following will produce no rows. This looks like a bug,
+--echo #  but it is actually correct behavior. Binary strings are end-padded
+--echo #  with \0 character (and not space).  Comparison does not ignore
+--echo #   the tail of \0.
+select key1 from t1 where key1='one';
+explain
+select hex(key1) from t1 where key1='one\0\0\0\0\0\0\0';
+select hex(key1) from t1 where key1='one\0\0\0\0\0\0\0';
+drop table t1;
+
+
+create table t2 (
+  pk int primary key, 
+  key1 char(10) collate latin1_bin,
+  col1 int,
+  key (key1)
+) engine=leveldb;
+insert into t2 values(1, 'one',11), (2,'two',22);
+explain 
+select key1 from t2 where key1='one';
+select key1 from t2 where key1='one';
+drop table t2;
+
+
+create table t3 (
+  pk int primary key, 
+  key1 char(10) collate utf8_bin,
+  col1 int,
+  key (key1)
+) engine=leveldb;
+insert into t3 values(1, 'one',11), (2,'two',22);
+explain 
+select key1 from t3 where key1='one';
+select key1 from t3 where key1='one';
+drop table t3;
+
+
+--echo # a VARCHAR column
+create table t4 (
+  pk int primary key, 
+  key1 varchar(10) collate latin1_bin, 
+  key(key1)
+) engine=leveldb; 
+insert into t4 values(1, 'one'), (2,'two'),(3,'threee'),(55,'fifty-five');
+
+explain 
+select key1 from t4 where key1='two';
+select key1 from t4 where key1='two';
+
+select key1 from t4 where key1='fifty-five';
+
+explain 
+select key1 from t4 where key1 between 's' and 'u';
+select key1 from t4 where key1 between 's' and 'u';
+
+drop table t4;
+
+--echo # 
+--echo # MDEV-4305: LevelDB: Assertion `((keypart_map + 1) & keypart_map) == 0' fails in calculate_key_len
+--echo # 
+CREATE TABLE t1 (pk1 INT, pk2 CHAR(32), i INT, PRIMARY KEY(pk1,pk2), KEY(i)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,'test1',6),(2,'test2',8);
+SELECT * FROM t1 WHERE i != 3 OR  pk1 > 9;
+DROP TABLE t1;
+
+--echo # 
+--echo # MDEV-4298: LevelDB: Assertion `thd->is_error() || kill_errno' fails in ha_rows filesort
+--echo # 
+CREATE TABLE t1 (pk INT PRIMARY KEY, i INT, KEY(i)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,1),(2,2);
+BEGIN;
+UPDATE t1 SET i = 100;
+
+--connect (con1,localhost,root,,test)
+--error ER_LOCK_WAIT_TIMEOUT
+DELETE IGNORE FROM t1 ORDER BY i;
+--disconnect con1
+
+--connection default
+COMMIT;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-4313: LevelDB: Server crashes in LDBSE_KEYDEF::setup on dropping the primary key column
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, i INT NOT NULL, KEY(i)) ENGINE=LevelDB;
+--error ER_GET_ERRMSG
+ALTER TABLE t1 DROP COLUMN `pk`;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-4324: LevelDB: Valgrind "Use of uninitialised value" warnings on inserting value into varchar field
+--echo #  (testcase only)
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, c VARCHAR(4)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,'foo'), (2,'bar');
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-4304: LevelDB: Index-only scan by a field with utf8_bin collation returns garbage symbols
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, c1 CHAR(1), c2 CHAR(1), KEY(c1)) ENGINE=LevelDB CHARSET utf8 COLLATE utf8_bin;
+INSERT INTO t1 VALUES (1,'h','h');
+SELECT * FROM t1;
+SELECT c1 FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-4300: LevelDB: Server crashes in inline_mysql_mutex_lock on SELECT .. FOR UPDATE
+--echo #
+CREATE TABLE t2 (pk INT PRIMARY KEY, i INT, KEY (i)) ENGINE=LevelDB;
+INSERT INTO t2 VALUES (1,4),(2,5);
+SELECT 1 FROM t2 WHERE i < 0 FOR UPDATE;
+DROP TABLE t2;
+
+--echo #
+--echo # MDEV-4301: LevelDB: Assertion `pack_info != __null' fails in LDBSE_KEYDEF::unpack_record
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, i INT, c CHAR(1), KEY(c,i)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,4,'d'),(2,8,'e');
+SELECT MAX( pk ) FROM t1 WHERE i = 105 AND c = 'h';
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-4337: LevelDB: Inconsistent results comparing a char field with an int field
+--echo #
+create table t1 (c char(1), i int, primary key(c), key(i)) engine=LevelDB;
+insert into t1 values ('2',2),('6',6);
+select * from t1 where c = i;
+select * from t1 ignore index (i) where c = i;
+drop table t1;
+
+
+--echo #
+--echo # Test statement rollback inside a transaction
+--echo #
+create table t1 (pk varchar(12) primary key) engine=leveldb;
+insert into t1 values ('old-val1'),('old-val2');
+
+create table t2 (pk varchar(12) primary key) engine=leveldb;
+insert into t2 values ('new-val2'),('old-val1');
+
+begin;
+insert into t1 values ('new-val1');
+--error ER_DUP_ENTRY
+insert into t1 select * from t2;
+commit;
+
+select * from t1;
+drop table t1, t2;
+
+--echo #
+--echo # MDEV-4383: LevelDB: Wrong result of DELETE .. ORDER BY .. LIMIT: 
+--echo #   rows that should be deleted remain in the table
+--echo #
+CREATE TABLE t2 (pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY) ENGINE=LevelDB;
+
+INSERT INTO t1 (pk) VALUES (NULL),(NULL);
+BEGIN;
+INSERT INTO t2 (pk) VALUES (NULL),(NULL);
+INSERT INTO t1 (pk) VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+
+--enable_info
+SELECT * FROM t1 ORDER BY pk LIMIT 9; 
+DELETE FROM t1 ORDER BY pk LIMIT 9;
+SELECT * FROM t1 ORDER BY pk LIMIT 9;
+--disable_info
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-4374: LevelDB: Valgrind warnings 'Use of uninitialised value' on 
+--echo #   inserting into a varchar column
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, a VARCHAR(32)) ENGINE=LevelDB;
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-4061: LevelDB: Changes from an interrupted query are still applied
+--echo #
+
+--enable_connect_log
+
+create table t1 (pk int primary key, a int) engine=LevelDB;
+insert into t1 values (1,10),(2,20);
+
+--let $con_id = `select connection_id()`
+
+set autocommit = 1;
+--send
+update t1 set a = sleep(100) where pk = 1;
+
+--connect (con1,localhost,root,,)
+--echo kill query \$con_id;
+--disable_query_log
+eval kill query $con_id;
+--enable_query_log
+
+--connection default
+--error ER_QUERY_INTERRUPTED
+--reap
+
+select * from t1;
+--disconnect con1
+--disable_connect_log
+drop table t1;
+
+
+--echo #
+--echo # MDEV-4099: LevelDB: Wrong results with index and range access after INSERT IGNORE or REPLACE
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, a SMALLINT, b INT, KEY (a)) ENGINE=LevelDB;
+INSERT IGNORE INTO t1 VALUES (1, 157, 0), (2, 1898, -504403), (1, -14659,  0);
+SELECT * FROM t1;
+SELECT pk FROM t1;
+SELECT * FROM t1 WHERE a != 97;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Test @@leveldb_max_row_locks
+--echo #
+CREATE TABLE t1 (pk INT PRIMARY KEY, a int) ENGINE=LevelDB;
+set @a=-1;
+insert into t1 select (@a:=@a+1), 1234 from information_schema.session_variables limit 100;
+set @tmp1= @@leveldb_max_row_locks;
+set leveldb_max_row_locks= 20;
+--error ER_GET_ERRMSG
+update t1 set a=a+10;
+DROP TABLE t1;
+
diff --git a/mysql-test/t/leveldb_qcache-master.opt b/mysql-test/t/leveldb_qcache-master.opt
new file mode 100644
index 0000000..a00258b
--- /dev/null
+++ b/mysql-test/t/leveldb_qcache-master.opt
@@ -0,0 +1 @@
+--query_cache_type=1
diff --git a/mysql-test/t/leveldb_qcache.test b/mysql-test/t/leveldb_qcache.test
new file mode 100644
index 0000000..49e6af1
--- /dev/null
+++ b/mysql-test/t/leveldb_qcache.test
@@ -0,0 +1,28 @@
+# Important:
+# The test needs to be run with --mysqld=--query-cache-type=1
+
+-- source include/have_query_cache.inc
+--enable_connect_log
+
+create table t1 (pk int primary key, c char(8)) engine=LevelDB;
+insert into t1 values (1,'new'),(2,'new');
+
+select * from t1;
+
+--connect (con1,localhost,root,,)
+
+update t1 set c = 'updated';
+#select * from t1;
+
+--connection default
+flush status;
+show status like 'Qcache_hits';
+show global status like 'Qcache_hits';
+select * from t1;
+select sql_no_cache * from t1;
+select * from t1 where pk = 1;
+show status like 'Qcache_hits';
+show status like 'Qcache_not_cached';
+show global status like 'Qcache_hits';
+
+drop table t1;
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 34f4bcc..300b50b 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -1111,3 +1111,28 @@
    fun:gaih_inet
    fun:getaddrinfo
 }
+
+#
+# LevelDB Storage Engine suppressions
+#
+{
+   Still reachable for once-per-process intializations
+   Memcheck:Leak
+   ...
+   fun:_ZN7leveldb4port8InitOnceEPiPFvvE
+   fun:_ZN7leveldb18BytewiseComparatorEv
+   fun:_ZN7leveldb7OptionsC1Ev
+   fun:_ZL17leveldb_init_funcPv
+}
+
+{
+   Still reachable for once-per-process intializations (2)
+   Memcheck:Leak
+   ...
+   fun:_ZN7leveldbL14InitDefaultEnvEv
+   ...
+   fun:_ZN7leveldb3Env7DefaultEv
+   fun:_ZN7leveldb7OptionsC1Ev
+   fun:_ZL17leveldb_init_funcPv
+}
+
diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c
index 9f1f104..2afd8b1 100644
--- a/mysys/lf_hash.c
+++ b/mysys/lf_hash.c
@@ -72,7 +72,9 @@ typedef struct {
     cursor is positioned in either case
     pins[0..2] are used, they are NOT removed on return
 */
-static int lfind(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
+static int lfind(LF_SLIST * volatile *head, 
+                 CHARSET_INFO *cs, lf_key_comparison_func_t key_comp,
+                 uint32 hashnr,
                  const uchar *key, uint keylen, CURSOR *cursor, LF_PINS *pins)
 {
   uint32       cur_hashnr;
@@ -110,8 +112,11 @@ retry:
       {
         int r= 1;
         if (cur_hashnr > hashnr ||
-            (r= my_strnncoll(cs, (uchar*) cur_key, cur_keylen, (uchar*) key,
-                             keylen)) >= 0)
+            ((r= key_comp? 
+                 key_comp((uchar*) cur_key, cur_keylen, (uchar*) key, keylen): 
+                 my_strnncoll(cs, (uchar*) cur_key, cur_keylen, (uchar*) key, 
+                              keylen)))
+            >= 0)
           return !r;
       }
       cursor->prev= &(cursor->curr->link);
@@ -150,7 +155,7 @@ retry:
     it uses pins[0..2], on return all pins are removed.
     if there're nodes with the same key value, a new node is added before them.
 */
-static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs,
+static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs, lf_key_comparison_func_t key_comp,
                          LF_SLIST *node, LF_PINS *pins, uint flags)
 {
   CURSOR         cursor;
@@ -158,7 +163,7 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs,
 
   for (;;)
   {
-    if (lfind(head, cs, node->hashnr, node->key, node->keylen,
+    if (lfind(head, cs, key_comp, node->hashnr, node->key, node->keylen,
               &cursor, pins) &&
         (flags & LF_HASH_UNIQUE))
     {
@@ -201,7 +206,8 @@ static LF_SLIST *linsert(LF_SLIST * volatile *head, CHARSET_INFO *cs,
   NOTE
     it uses pins[0..2], on return all pins are removed.
 */
-static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
+static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, 
+                   lf_key_comparison_func_t key_comp, uint32 hashnr,
                    const uchar *key, uint keylen, LF_PINS *pins)
 {
   CURSOR cursor;
@@ -209,7 +215,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
 
   for (;;)
   {
-    if (!lfind(head, cs, hashnr, key, keylen, &cursor, pins))
+    if (!lfind(head, cs, key_comp, hashnr, key, keylen, &cursor, pins))
     {
       res= 1; /* not found */
       break;
@@ -233,7 +239,7 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
             (to ensure the number of "set DELETED flag" actions
             is equal to the number of "remove from the list" actions)
           */
-          lfind(head, cs, hashnr, key, keylen, &cursor, pins);
+          lfind(head, cs, key_comp, hashnr, key, keylen, &cursor, pins);
         }
         res= 0;
         break;
@@ -260,11 +266,12 @@ static int ldelete(LF_SLIST * volatile *head, CHARSET_INFO *cs, uint32 hashnr,
     all other pins are removed.
 */
 static LF_SLIST *lsearch(LF_SLIST * volatile *head, CHARSET_INFO *cs,
+                         lf_key_comparison_func_t key_comp,
                          uint32 hashnr, const uchar *key, uint keylen,
                          LF_PINS *pins)
 {
   CURSOR cursor;
-  int res= lfind(head, cs, hashnr, key, keylen, &cursor, pins);
+  int res= lfind(head, cs, key_comp, hashnr, key, keylen, &cursor, pins);
   if (res)
     _lf_pin(pins, 2, cursor.curr);
   _lf_unpin(pins, 0);
@@ -290,8 +297,15 @@ static inline const uchar* hash_key(const LF_HASH *hash,
 static inline uint calc_hash(LF_HASH *hash, const uchar *key, uint keylen)
 {
   ulong nr1= 1, nr2= 4;
-  hash->charset->coll->hash_sort(hash->charset, (uchar*) key, keylen,
-                                 &nr1, &nr2);
+  if (hash->hashfunc)
+  {
+    nr1= hash->hashfunc((const char*)key, keylen);
+  }
+  else
+  {
+    hash->charset->coll->hash_sort(hash->charset, (uchar*) key, keylen,
+                                   &nr1, &nr2);
+  }
   return nr1 & INT_MAX32;
 }
 
@@ -327,6 +341,9 @@ void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
   hash->key_offset= key_offset;
   hash->key_length= key_length;
   hash->get_key= get_key;
+
+  hash->key_comparator= NULL;
+  hash->hashfunc= NULL;
   DBUG_ASSERT(get_key ? !key_offset && !key_length : key_length);
 }
 
@@ -383,7 +400,7 @@ int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data)
   if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins)))
     return -1;
   node->hashnr= my_reverse_bits(hashnr) | 1; /* normal node */
-  if (linsert(el, hash->charset, node, pins, hash->flags))
+  if (linsert(el, hash->charset, hash->key_comparator, node, pins, hash->flags))
   {
     _lf_alloc_free(pins, node);
     lf_rwunlock_by_pins(pins);
@@ -426,7 +443,7 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
   */
   if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins)))
     return -1;
-  if (ldelete(el, hash->charset, my_reverse_bits(hashnr) | 1,
+  if (ldelete(el, hash->charset, hash->key_comparator, my_reverse_bits(hashnr) | 1,
               (uchar *)key, keylen, pins))
   {
     lf_rwunlock_by_pins(pins);
@@ -459,7 +476,7 @@ void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen)
     return MY_ERRPTR;
   if (*el == NULL && unlikely(initialize_bucket(hash, el, bucket, pins)))
     return MY_ERRPTR;
-  found= lsearch(el, hash->charset, my_reverse_bits(hashnr) | 1,
+  found= lsearch(el, hash->charset, hash->key_comparator, my_reverse_bits(hashnr) | 1,
                  (uchar *)key, keylen, pins);
   lf_rwunlock_by_pins(pins);
   return found ? found+1 : 0;
@@ -487,7 +504,7 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node,
   dummy->hashnr= my_reverse_bits(bucket) | 0; /* dummy node */
   dummy->key= dummy_key;
   dummy->keylen= 0;
-  if ((cur= linsert(el, hash->charset, dummy, pins, LF_HASH_UNIQUE)))
+  if ((cur= linsert(el, hash->charset, hash->key_comparator, dummy, pins, LF_HASH_UNIQUE)))
   {
     my_free(dummy);
     dummy= cur;
@@ -503,3 +520,103 @@ static int initialize_bucket(LF_HASH *hash, LF_SLIST * volatile *node,
   */
   return 0;
 }
+
+
+#if 0
+int debug_lcount(LF_SLIST * volatile *head, CURSOR *cursor, LF_PINS *pins) {
+  uint32       cur_hashnr;
+  const uchar  *cur_key;
+  uint         cur_keylen;
+  intptr       link;
+  
+  int RESULT=0;
+retry:
+  cursor->prev= (intptr *)head;
+  do { /* PTR() isn't necessary below, head is a dummy node */
+    cursor->curr= (LF_SLIST *)(*cursor->prev);
+    _lf_pin(pins, 1, cursor->curr);
+  } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF);
+  for (;;)
+  {
+    if (unlikely(!cursor->curr))
+      return 0; /* end of the list */
+    do {
+      /* QQ: XXX or goto retry ? */
+      link= cursor->curr->link;
+      cursor->next= PTR(link);
+      _lf_pin(pins, 0, cursor->next);
+    } while (link != cursor->curr->link && LF_BACKOFF);
+    cur_hashnr= cursor->curr->hashnr;
+    cur_key= cursor->curr->key;
+    cur_keylen= cursor->curr->keylen;
+    if (*cursor->prev != (intptr)cursor->curr)
+    {
+      (void)LF_BACKOFF;
+      goto retry;
+    }
+    if (!DELETED(link))
+    {
+#if 0      
+      if (cur_hashnr >= hashnr)
+      {
+        int r= 1;
+        if (cur_hashnr > hashnr ||
+            ((r= key_comp? 
+                 key_comp((uchar*) cur_key, cur_keylen, (uchar*) key, keylen): 
+                 my_strnncoll(cs, (uchar*) cur_key, cur_keylen, (uchar*) key, 
+                              keylen)))
+            >= 0)
+          return !r;
+      }
+#endif      
+      cursor->prev= &(cursor->curr->link);
+      _lf_pin(pins, 2, cursor->curr);
+      RESULT++;
+    }
+    else
+    {
+      /*
+        we found a deleted node - be nice, help the other thread
+        and remove this deleted node
+      */
+      if (my_atomic_casptr((void **)cursor->prev,
+                           (void **)&cursor->curr, cursor->next))
+        _lf_alloc_free(pins, cursor->curr);
+      else
+      {
+        (void)LF_BACKOFF;
+        goto retry;
+      }
+    }
+    cursor->curr= cursor->next;
+    _lf_pin(pins, 1, cursor->curr);
+  }
+
+  _lf_unpin(pins, 0);
+  _lf_unpin(pins, 1);
+  _lf_unpin(pins, 2);
+  return RESULT;
+}
+
+
+int debug_hash_count_elements(LF_HASH *hash, LF_PINS *pins)
+{
+  CURSOR dummy;
+  LF_SLIST * volatile *el;
+  int TOTAL_ELEMS=0;
+  int bucket;
+  for (bucket= 0; bucket < hash->size; bucket++)
+  {
+    el= _lf_dynarray_lvalue(&hash->array, bucket);
+    if (el)
+    {
+      int CNT= debug_lcount(el, &dummy, pins);
+      // Count number of elements in the bucket
+      TOTAL_ELEMS += CNT;
+    }
+  }
+  return TOTAL_ELEMS;
+}
+
+
+#endif
diff --git a/sql/handler.h b/sql/handler.h
index effe818..0ad3b94 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -390,6 +390,7 @@ enum legacy_db_type
   DB_TYPE_MEMCACHE,
   DB_TYPE_FALCON,
   DB_TYPE_MARIA,
+  DB_TYPE_LEVELDB, /* Need it here for extended keys to work */
   /** Performance schema engine. */
   DB_TYPE_PERFORMANCE_SCHEMA,
   DB_TYPE_FIRST_DYNAMIC=42,
diff --git a/sql/key.cc b/sql/key.cc
index 847eddd..d547195 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -132,15 +132,22 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
     {
       key_length-= HA_KEY_BLOB_LENGTH;
       length= min<uint>(key_length, key_part->length);
-      key_part->field->get_key_image(to_key, length, Field::itRAW);
+      Field *field= key_part->field;
+      my_ptrdiff_t ptrdiff= from_record - field->table->record[0];
+      field->move_field_offset(ptrdiff);
+      field->get_key_image(to_key, length, Field::itRAW);
+      field->move_field_offset(-ptrdiff);
       to_key+= HA_KEY_BLOB_LENGTH;
     }
     else
     {
       length= min<uint>(key_length, key_part->length);
       Field *field= key_part->field;
+      my_ptrdiff_t ptrdiff= from_record - field->table->record[0];
+      field->move_field_offset(ptrdiff);
       const CHARSET_INFO *cs= field->charset();
       uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+      field->move_field_offset(-ptrdiff);
       if (bytes < length)
         cs->cset->fill(cs, (char*) to_key + bytes, length - bytes, ' ');
     }
diff --git a/sql/table.cc b/sql/table.cc
index 3cdcbe7..ba94470 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1875,6 +1875,12 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
         if (key == primary_key)
         {
           field->flags|= PRI_KEY_FLAG;
+
+          /* 
+            LevelDB SE: we need to re-read to get correct value of 
+            HA_PRIMARY_KEY_IN_READ_INDEX
+          */
+          ha_option= handler_file->ha_table_flags();
           /*
             If this field is part of the primary key and all keys contains
             the primary key, then we can use any key to find this column
diff --git a/storage/leveldb/CMakeLists.txt b/storage/leveldb/CMakeLists.txt
new file mode 100644
index 0000000..41de2d6
--- /dev/null
+++ b/storage/leveldb/CMakeLists.txt
@@ -0,0 +1,54 @@
+# TODO: Copyrights
+#
+# Optional environment variables that may be used, if library
+# files are located in non-standard path:
+#
+# LEVELDB_INCLUDE=   # path to leveldb include directory
+# LEVELDB_LIBRARIES= # path to leveldb shared or static libraries
+
+SET(LEVELDB_SE_PLUGIN_STATIC  "leveldb")
+SET(LEVELDB_SE_PLUGIN_MANDATORY TRUE)
+
+FIND_PATH(Leveldb_INCLUDE_DIRS leveldb/db.h PATHS
+$ENV{LEVELDB_INCLUDE}      # environment variable to be used optionally
+${Leveldb_INCLUDE_DIR}     # this may be set
+/usr/local/include/leveldb # list of additional directories to look from
+/opt/local/include/leveldb
+/usr/include/leveldb
+/opt/include/leveldb
+)
+IF(NOT EXISTS ${Leveldb_INCLUDE_DIRS})
+  MESSAGE(SEND_ERROR "No leveldb include directory found! Consider using environment variable LEVELDB_INCLUDE=...")
+  RETURN()
+ENDIF()
+
+FIND_LIBRARY(Leveldb_LIBS NAMES leveldb
+             PATHS ${Leveldb_LIB_PATHS} ${Leveldb_LIB} $ENV{LEVELDB_LIBRARIES})
+IF(EXISTS ${Leveldb_LIBS})
+  GET_FILENAME_COMPONENT(LINK_DIR ${Leveldb_LIBS} ABSOLUTE)
+ELSE()
+  MESSAGE(SEND_ERROR "No leveldb library directory found! Consider using environment variable LEVELDB_LIBRARIES=...")
+  RETURN()
+ENDIF()
+
+INCLUDE_DIRECTORIES(AFTER ${Leveldb_INCLUDE_DIRS})
+SET(CMAKE_REQUIRED_INCLUDES ${Leveldb_INCLUDE_DIRS})
+
+CHECK_CXX_SOURCE_COMPILES(
+"
+#include <leveldb/db.h>
+int main() { return 0; }
+" LEVELDB_OK)
+
+IF(LEVELDB_OK)
+  SET(LEVELDB_SOURCES 
+      ha_leveldb.cc ha_leveldb.h 
+      ldb_datadic.cc ldb_datadic.h
+      ldb_locks.cc ldb_locks.h 
+      ldb_rowmods.cc ldb_rowmods.h
+      ldb_applyiter.cc ldb_applyiter.h)
+
+  MYSQL_ADD_PLUGIN(leveldb_se ${LEVELDB_SOURCES} STORAGE_ENGINE STATIC_ONLY MANDATORY LINK_LIBRARIES ${LINK_DIR})
+
+  ADD_SUBDIRECTORY(unittest)
+ENDIF(LEVELDB_OK)
diff --git a/storage/leveldb/ha_leveldb.cc b/storage/leveldb/ha_leveldb.cc
new file mode 100644
index 0000000..e7039fd
--- /dev/null
+++ b/storage/leveldb/ha_leveldb.cc
@@ -0,0 +1,2511 @@
+/* 
+   Copyright (c) 2012, Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation        // gcc: Class implementation
+#endif
+
+#include <mysql/plugin.h>
+#include "ha_leveldb.h"
+#include "sql_class.h"
+#include "sql_array.h"
+
+#include "my_bit.h"
+
+#include "ldb_datadic.h"
+#include "ldb_locks.h"
+#include "ldb_rowmods.h"
+
+void dbug_dump_database(leveldb::DB *db);
+
+static handler *leveldb_create_handler(handlerton *hton,
+                                       TABLE_SHARE *table, 
+                                       MEM_ROOT *mem_root);
+
+void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
+              uint key_length);
+
+handlerton *leveldb_hton;
+
+leveldb::DB *ldb= NULL;
+
+Table_ddl_manager ddl_manager;
+
+LockTable row_locks;
+
+/* 
+   Hash used to track the number of open tables; variable for example share
+   methods
+*/
+static HASH leveldb_open_tables;
+
+/* The mutex used to init the hash; variable for example share methods */
+mysql_mutex_t leveldb_mutex;
+
+
+//TODO: 0 means don't wait at all, and we don't support it yet?
+static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
+  "Number of seconds to wait for lock",
+  NULL, NULL, /*default*/ 1, /*min*/ 1, /*max*/ 1024*1024*1024, 0);
+
+static MYSQL_THDVAR_BOOL(bulk_load, PLUGIN_VAR_RQCMDARG,
+  "Use bulk-load mode for inserts", NULL, NULL, FALSE);
+
+static MYSQL_THDVAR_ULONG(max_row_locks, PLUGIN_VAR_RQCMDARG,
+  "Maximum number of locks a transaction can have",
+  NULL, NULL, /*default*/ 1024*1024*1024, /*min*/ 1, /*max*/ 1024*1024*1024, 0);
+
+static MYSQL_THDVAR_ULONG(bulk_load_size, PLUGIN_VAR_RQCMDARG,
+  "Max #records in a batch for bulk-load mode",
+  NULL, NULL, /*default*/ 1000, /*min*/ 1, /*max*/ 1024*1024*1024, 0);
+
+static struct st_mysql_sys_var* leveldb_system_variables[]= {
+  MYSQL_SYSVAR(lock_wait_timeout),
+  MYSQL_SYSVAR(max_row_locks),
+  MYSQL_SYSVAR(bulk_load),
+  MYSQL_SYSVAR(bulk_load_size),
+  NULL
+};
+
+
+#if 0
+static SHOW_VAR leveldb_status_variables[]= {
+  {"row_insert_batches",
+    (char*) &leveldb_counters.row_insert_batches,  SHOW_LONG},
+...
+  {NullS, NullS, SHOW_LONG}
+};
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+  @brief
+  Function we use in the creation of our hash to get key.
+*/
+
+static uchar* leveldb_get_key(LEVELDB_SHARE *share, size_t *length,
+                             my_bool not_used __attribute__((unused)))
+{
+  *length=share->table_name_length;
+  return (uchar*) share->table_name;
+}
+
+/* 
+  The following is needed as an argument for thd_enter_cond, irrespectively of
+  whether we're compiling with P_S or not.
+*/
+PSI_stage_info stage_waiting_on_row_lock= { 0, "Waiting for row lock", 0};
+
+static PSI_stage_info *all_leveldb_stages[]=
+{
+  & stage_waiting_on_row_lock
+};
+
+
+#ifdef HAVE_PSI_INTERFACE
+static PSI_mutex_key ex_key_mutex_example, ex_key_mutex_LEVELDB_SHARE_mutex;
+
+static PSI_mutex_info all_leveldb_mutexes[]=
+{
+  { &ex_key_mutex_example, "leveldb", PSI_FLAG_GLOBAL},
+  { &ex_key_mutex_LEVELDB_SHARE_mutex, "LEVELDB_SHARE::mutex", 0}
+};
+
+static void init_leveldb_psi_keys()
+{
+  const char* category= "leveldb";
+  int count;
+
+  if (PSI_server == NULL)
+    return;
+
+  count= array_elements(all_leveldb_mutexes);
+  PSI_server->register_mutex(category, all_leveldb_mutexes, count);
+
+  count= array_elements(all_leveldb_stages);
+  mysql_stage_register(category, all_leveldb_stages, count);
+}
+#endif
+
+
+/*
+  The keys are in form: {index_number} {mem-comparable-key}
+
+  (todo: knowledge about this format is shared between this class and 
+   LDBSE_KEYDEF)
+*/
+
+class Primary_key_comparator : public leveldb::Comparator
+{
+public:
+  int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const
+  {
+    size_t a_size= a.size();
+    size_t b_size= b.size();
+    size_t len= (a_size < b_size) ? a_size : b_size;
+    int res;
+    
+    if ((res= memcmp(a.data(), b.data(), len)))
+      return res;
+
+    /* Ok, res== 0 */
+    if (a_size != b_size)
+    {
+      return a_size < b_size? -1 : 1;
+    }
+    return 0;
+  }
+
+  /* The following is not needed by LevelDB, but conceptually should be here: */
+  static ulong get_hashnr(const char *key, size_t key_len);
+  const char* Name() const { return "LevelDB_SE_v2.2"; }
+
+  //TODO: advanced funcs:
+  // - FindShortestSeparator
+  // - FindShortSuccessor
+  // for now, do-nothing implementations:
+  void FindShortestSeparator(std::string* start, const leveldb::Slice& limit) const {}
+  void FindShortSuccessor(std::string* key) const {}
+};
+
+Primary_key_comparator primary_key_comparator;
+
+int compare_mem_comparable_keys(const uchar *a, size_t a_len, const uchar *b, size_t b_len)
+{
+  leveldb::Slice a_slice((char*)a, a_len);
+  leveldb::Slice b_slice((char*)b, b_len);
+  return primary_key_comparator.Compare(a_slice, b_slice);
+}
+
+
+
+/*
+  This is a leveldb connection. Its members represent the current transaction,
+  which consists of:
+  - the snapshot
+  - the changes we've made but are not seeing yet.
+  
+  The changes are made to individual tables, which store them here and then
+  this object commits them on commit.
+*/
+
+class Ldb_transaction
+{
+public:
+  /* The snapshot the transaction is used */
+  const leveldb::Snapshot *snapshot;
+
+  /* The changes made by this transaction (and not yet applied) */
+  Row_table changes;
+
+  uint n_writes;
+
+  /* 
+    These are needed to use LF-Hash. They are allocated per-thread. Logically,
+    they are not part of the transaction but it's convenient to have them here.
+  */
+  LF_PINS *pins;
+
+  /* Row locks taken by this transaction */
+  Dynamic_array<Row_lock*> trx_locks;
+
+  int timeout_sec; /* Cached value of @@leveldb_lock_wait_timeout */
+  int max_row_locks;
+
+  void set_params(int timeout_sec_arg, int max_row_locks_arg)
+  {
+    timeout_sec= timeout_sec_arg;
+    max_row_locks= max_row_locks_arg;
+  }
+
+  Row_lock *get_lock(const uchar* key, size_t keylen, bool *timed_out)
+  {
+    Row_lock *lock;
+    if (trx_locks.elements() > max_row_locks)
+    {
+      *timed_out= false;
+      return NULL;
+    }
+    if (!(lock= row_locks.get_lock(pins, key, keylen, timeout_sec)))
+    {
+      *timed_out= true;
+      return NULL;
+    }
+    return lock;
+  }
+
+  void add_lock(Row_lock* lock)
+  {
+    trx_locks.append(lock);
+  }
+
+  void release_last_lock()
+  {
+    row_locks.release_lock(pins, trx_locks.at(trx_locks.elements() - 1));
+    trx_locks.pop();
+  }
+
+  void release_locks()
+  {
+    int size= trx_locks.elements();
+    for (int i= 0; i < size; i++)
+      row_locks.release_lock(pins, trx_locks.at(i));
+    trx_locks.clear();
+  }
+  
+  bool commit()
+  {
+    bool res= false;
+    flush_batch();
+    /* rollback() will delete snapshot, batch and locks */
+    rollback();
+    return res;
+  }
+
+private:
+
+  int flush_batch_intern()
+  {
+    bool res= false;
+    leveldb::WriteBatch batch;
+
+    if (changes.is_empty())
+      return false;
+
+    Row_table_iter iter(&changes);
+
+    for (iter.SeekToFirst(); iter.Valid(); iter.Next())
+    {
+      if (iter.is_tombstone())
+      {
+        batch.Delete(iter.key());
+      }
+      else
+      {
+        batch.Put(iter.key(), iter.value());
+      }
+    }
+    leveldb::Status s= ldb->Write(leveldb::WriteOptions(), &batch);
+    res= !s.ok(); // we return true when something failed
+    return res;
+  }
+
+public:
+  int flush_batch()
+  {
+    bool bres= flush_batch_intern();
+    changes.reinit();
+    n_writes= 0;
+    return bres;
+  }
+
+  void prepare_for_write()
+  {
+    /* Currently, we don't do anything here */
+  }
+   
+  /* 
+    This must be called when last statement is rolled back, but the transaction 
+    continues
+  */
+  void rollback_stmt() { changes.rollback_stmt(); }
+
+  void start_stmt() { changes.start_stmt(); } 
+  void rollback()
+  {
+    if (snapshot)
+    {
+      ldb->ReleaseSnapshot(snapshot);
+      snapshot= NULL;
+    }
+
+    changes.reinit();
+    release_locks();
+    n_writes= 0;
+  }
+
+  Ldb_transaction() : 
+    snapshot(NULL), n_writes(0), pins(NULL)
+  {
+    changes.init();
+  }
+
+  ~Ldb_transaction() 
+  { 
+    if (snapshot)
+    {
+      ldb->ReleaseSnapshot(snapshot);
+      snapshot= NULL;
+    }
+    changes.cleanup();
+  }
+};
+
+
+static Ldb_transaction* &get_trx_from_thd(THD *thd)
+{
+  return *(Ldb_transaction**) thd_ha_data(thd, leveldb_hton);
+}
+
+
+/* 
+  TODO: maybe, call this in external_lock() and store in ha_leveldb.. 
+*/
+
+static Ldb_transaction *get_or_create_trx(THD *thd)
+{
+  Ldb_transaction*& trx= get_trx_from_thd(thd);
+  if (trx == NULL)
+  {
+    if (!(trx= new Ldb_transaction))
+      return NULL;
+    trx->pins= row_locks.get_pins();
+    trx->snapshot= ldb->GetSnapshot();
+  }
+  else
+  {
+    if (!trx->snapshot)
+      trx->snapshot= ldb->GetSnapshot();
+  }
+  return trx;
+}
+
+
+static int leveldb_close_connection(handlerton* hton, THD* thd)
+{
+  Ldb_transaction*& trx= get_trx_from_thd(thd);
+  if (trx && trx->pins)
+    row_locks.put_pins(trx->pins);
+  delete trx;
+  trx= NULL;
+  return 0;
+}
+
+
+static int leveldb_commit(handlerton* hton, THD* thd, bool commit_trx)
+{
+  if (commit_trx)
+  {
+    Ldb_transaction*& trx= get_trx_from_thd(thd);
+    if (trx)
+      trx->commit(); // todo: return error code.
+  }
+  else
+  {
+    /*
+      Committing a statement within a transaction. We don't need to do anything
+      here. trx->start_stmt() will notify Ldb_transaction that another
+      statement has started.
+    */
+  }
+  return 0;
+}
+
+
+static int leveldb_rollback(handlerton* hton, THD* thd, bool rollback_trx)
+{
+  if (rollback_trx)
+  {
+    /* Discard the changes made by the transaction */
+    Ldb_transaction*& trx= get_trx_from_thd(thd);
+    if (trx)
+      trx->rollback();
+  }
+  else
+  {
+    Ldb_transaction*& trx= get_trx_from_thd(thd);
+    if (trx)
+      trx->rollback_stmt();
+  }
+  return 0;
+}
+
+
+static int leveldb_init_func(void *p)
+{
+  DBUG_ENTER("leveldb_init_func");
+  
+#ifdef HAVE_PSI_INTERFACE
+  init_leveldb_psi_keys();
+#endif
+
+  leveldb_hton= (handlerton *)p;
+  mysql_mutex_init(ex_key_mutex_example, &leveldb_mutex, MY_MUTEX_INIT_FAST);
+  (void) my_hash_init(&leveldb_open_tables,system_charset_info,32,0,0,
+                      (my_hash_get_key) leveldb_get_key,0,0);
+
+  leveldb_hton->state=    SHOW_OPTION_YES;
+  leveldb_hton->create=   leveldb_create_handler;
+  leveldb_hton->close_connection= leveldb_close_connection;
+  leveldb_hton->commit=   leveldb_commit;
+  leveldb_hton->rollback= leveldb_rollback;
+  leveldb_hton->db_type=  DB_TYPE_LEVELDB;
+
+  /* 
+    Don't specify HTON_CAN_RECREATE in flags. re-create is used by TRUNCATE
+    TABLE to create an empty table from scratch. LevelDB cannot efficiently
+    re-create a table.
+  */
+  leveldb_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED;
+
+  /*
+    As for the datadir, innobase_init() uses mysql_real_data_home for
+    embedded server, and current directory for the "full server".
+  */
+  DBUG_ASSERT(!mysqld_embedded);
+  
+  row_locks.init(compare_mem_comparable_keys, 
+                 Primary_key_comparator::get_hashnr);
+
+  leveldb::Options main_opts;
+  main_opts.create_if_missing = true;
+  main_opts.comparator= &primary_key_comparator;
+  leveldb::Status status;
+  status= leveldb::DB::Open(main_opts, "./leveldb", &ldb);
+
+  if (!status.ok())
+  {
+    std::string err_text= status.ToString();
+    sql_print_error("LevelDB: Error opening instance: %s", err_text.c_str());
+    DBUG_RETURN(1);
+  }
+
+  if (ddl_manager.init(ldb))
+    DBUG_RETURN(1);
+
+  sql_print_information("LevelDB instance opened");
+  DBUG_RETURN(0);
+}
+
+
+static int leveldb_done_func(void *p)
+{
+  int error= 0;
+  DBUG_ENTER("leveldb_done_func");
+  if (leveldb_open_tables.records)
+    error= 1;
+  my_hash_free(&leveldb_open_tables);
+  mysql_mutex_destroy(&leveldb_mutex);
+
+  row_locks.cleanup();
+  ddl_manager.cleanup();
+
+  delete ldb;
+  ldb= NULL;
+
+  DBUG_RETURN(error);
+}
+
+
+/**
+  @brief
+  Example of simple lock controls. The "share" it creates is a
+  structure we will pass to each leveldb handler. Do you have to have
+  one of these? Well, you have pieces that are used for locking, and
+  they are needed to function.
+*/
+
+static LEVELDB_SHARE *get_share(const char *table_name, TABLE *table)
+{
+  LEVELDB_SHARE *share;
+  uint length;
+  char *tmp_name;
+
+  mysql_mutex_lock(&leveldb_mutex);
+  length=(uint) strlen(table_name);
+
+  if (!(share=(LEVELDB_SHARE*) my_hash_search(&leveldb_open_tables,
+                                              (uchar*) table_name,
+                                              length)))
+  {
+    if (!(share=(LEVELDB_SHARE *)
+          my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+                          &share, sizeof(*share),
+                          &tmp_name, length+1,
+                          NullS)))
+    {
+      mysql_mutex_unlock(&leveldb_mutex);
+      return NULL;
+    }
+
+    share->use_count=0;
+    share->table_name_length=length;
+    share->table_name=tmp_name;
+    strmov(share->table_name,table_name);
+
+    if (my_hash_insert(&leveldb_open_tables, (uchar*) share))
+      goto error;
+    thr_lock_init(&share->lock);
+    //mysql_mutex_init(ex_key_mutex_LEVELDB_SHARE_mutex,
+    //                 &share->mutex, MY_MUTEX_INIT_FAST);
+  }
+  share->use_count++;
+  mysql_mutex_unlock(&leveldb_mutex);
+
+  return share;
+
+error:
+ // mysql_mutex_destroy(&share->mutex);
+  my_free(share);
+
+  return NULL;
+}
+
+
+void ha_leveldb::load_auto_incr_value()
+{
+  int save_active_index= active_index;
+  active_index= table->s->primary_key;
+  uint8 save_table_status= table->status;
+
+  // Do a lookup.
+  if (!index_last(table->record[0]))
+    update_auto_incr_val();
+
+  table->status= save_table_status;
+  active_index= save_active_index;
+
+  /* 
+    Do what ha_leveldb::index_end() does.
+    (Why don't we use index_init/index_end? class handler defines index_init
+     as private, for some reason).
+  */
+  if (scan_it)
+  {
+    delete scan_it;
+    scan_it= NULL;
+  }
+}
+
+
+/* Get PK value from table->record[0]. */
+void ha_leveldb::update_auto_incr_val()
+{
+  Field *pk_field;
+  longlong new_val;
+  pk_field= table->key_info[table->s->primary_key].key_part[0].field;
+
+  my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
+  new_val= pk_field->val_int() + 1;
+  dbug_tmp_restore_column_map(table->read_set, old_map);
+
+  /* TODO: switch to compare-and-swap? */
+  mysql_mutex_lock(&tbl_def->mutex);
+  if (tbl_def->auto_incr_val < new_val)
+    tbl_def->auto_incr_val= new_val;
+  mysql_mutex_unlock(&tbl_def->mutex);
+}
+
+
+/**
+  @brief
+  Free lock controls. We call this whenever we close a table. If the table had
+  the last reference to the share, then we free memory associated with it.
+*/
+
+static int free_share(LEVELDB_SHARE *share)
+{
+  mysql_mutex_lock(&leveldb_mutex);
+  if (!--share->use_count)
+  {
+    my_hash_delete(&leveldb_open_tables, (uchar*) share);
+    thr_lock_delete(&share->lock);
+    //mysql_mutex_destroy(&share->mutex);
+    my_free(share);
+  }
+  mysql_mutex_unlock(&leveldb_mutex);
+
+  return 0;
+}
+
+
+static handler* leveldb_create_handler(handlerton *hton,
+                                       TABLE_SHARE *table, 
+                                       MEM_ROOT *mem_root)
+{
+  return new (mem_root) ha_leveldb(hton, table);
+}
+
+
+ha_leveldb::ha_leveldb(handlerton *hton, TABLE_SHARE *table_arg)
+  : handler(hton, table_arg), scan_it(NULL), pk_descr(NULL), 
+    key_descr(NULL), 
+    pk_can_be_decoded(false),
+    pk_tuple(NULL), pk_packed_tuple(NULL), 
+    sec_key_packed_tuple(NULL), sec_key_tails(NULL),
+    lock_rows(FALSE),
+    keyread_only(FALSE)
+{}
+
+
+static const char *ha_leveldb_exts[] = {
+  NullS
+};
+
+
+const char **ha_leveldb::bas_ext() const
+{
+  return ha_leveldb_exts;
+}
+
+
+/*
+  Convert record from table->record[0] form into a form that can be written
+  into leveldb.
+
+  @param packed_rec OUT Data slice with record data.
+*/
+
+void ha_leveldb::convert_record_to_storage_format(leveldb::Slice *packed_rec)
+{
+  Field **field;
+
+  for (field= table->field; *field; field++)
+  {
+    if ((*field)->real_type() == MYSQL_TYPE_VARCHAR)
+    {
+      Field_varstring* field_var= (Field_varstring*)*field;
+      /* Fill unused bytes with zeros */
+      uint used_size= field_var->length_bytes + (*field)->data_length();
+      uint total_size= (*field)->pack_length();
+      memset((*field)->ptr + used_size, 0, total_size - used_size);
+    }
+  }
+
+  if (!table->s->blob_fields)
+  {
+    *packed_rec = leveldb::Slice((char*)table->record[0], table->s->reclength);
+    return;
+  }
+
+  /* Ok have blob fields */
+  storage_record.length(0);
+  storage_record.append((const char*)table->record[0], table->s->reclength);
+
+  // for each blob column
+  for (field= table->field; *field; field++)
+  {
+    if ((*field)->type() == MYSQL_TYPE_BLOB)
+    {
+      Field_blob *blob= (Field_blob*)(*field);
+      uint32 value_len= blob->get_length();
+      uint length_bytes= blob->pack_length() - 8;
+      char *data_ptr;
+      memcpy(&data_ptr, blob->ptr + length_bytes, sizeof(uchar*));
+
+      storage_record.append(data_ptr, value_len);
+      uint32 size_to_write= htons(value_len);
+      size_t pointer_offset= (blob->ptr - table->record[0]) + length_bytes;
+      memcpy((char*)storage_record.ptr() + pointer_offset, &size_to_write,
+             sizeof(uint32));
+    }
+  }
+  *packed_rec= leveldb::Slice(storage_record.ptr(), storage_record.length());
+}
+
+
+void ha_leveldb::convert_record_from_storage_format(leveldb::Slice *slice, 
+                                                    uchar *buf)
+{
+  if (!table->s->blob_fields)
+  {
+    DBUG_ASSERT(slice->size() == table->s->reclength);
+    memcpy(buf, slice->data(), slice->size());
+  }
+  else
+  {
+    retrieved_record.assign(slice->data(), slice->size());
+    convert_record_from_storage_format(buf);
+  }
+}
+
+
+/*
+  Unpack the record in this->retrieved_record from storage format into 
+  buf (which can be table->record[0] or table->record[1])
+
+  If the table has blobs, the unpacked data in buf may keep pointers to the
+  data in this->retrieved_record.
+*/
+
+void ha_leveldb::convert_record_from_storage_format(uchar * buf)
+{
+  if (!table->s->blob_fields)
+  {
+    DBUG_ASSERT(retrieved_record.length() == table->s->reclength);
+    memcpy(buf, retrieved_record.c_str(), retrieved_record.length());
+    return;
+  }
+  else
+    unpack_blobs_from_retrieved_record(buf);
+}
+
+
+void ha_leveldb::unpack_blobs_from_retrieved_record(uchar *buf)
+{
+  /* 
+    Unpack the blobs
+     Blobs in the record are stored as 
+      [record-0 format] [blob data#1] [blob data#2]
+  */
+  memcpy(buf, retrieved_record.c_str(), table->s->reclength);
+
+  const char *blob_ptr= retrieved_record.c_str() + table->s->reclength;
+ 
+  // for each blob column
+  for (Field **field= table->field; *field; field++)
+  {
+    if ((*field)->type() == MYSQL_TYPE_BLOB)
+    {
+      Field_blob *blob= (Field_blob*)(*field);
+      my_ptrdiff_t ptr_diff= buf - table->record[0];
+      blob->move_field_offset(ptr_diff);
+      /* 
+        We've got the blob length when we've memcpy'ed table->record[0]. 
+        But there's still offset instead of blob pointer.
+      */
+      uint32 value_len= blob->get_length();
+      uint length_bytes= blob->pack_length() - 8;
+
+      // set 8-byte pointer to 0, like innodb does.
+      memset(blob->ptr + length_bytes, 0, 8); 
+
+      memcpy(blob->ptr + length_bytes, &blob_ptr, sizeof(uchar*));
+
+      blob_ptr += value_len;
+      blob->move_field_offset(-ptr_diff);
+    }
+  }
+}
+
+
+static void make_dbname_tablename(StringBuffer<64> *str, TABLE *table_arg)
+{
+  str->append(table_arg->s->db.str, table_arg->s->db.length);
+  str->append('.');
+  str->append(table_arg->s->table_name.str, table_arg->s->table_name.length);
+  str->c_ptr_safe();
+}
+
+
+int ha_leveldb::open(const char *name, int mode, uint test_if_locked)
+{
+  DBUG_ENTER("ha_leveldb::open");
+
+  if (!(share = get_share(name, table)))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+  thr_lock_data_init(&share->lock,&lock,NULL);
+  
+  /* 
+    note: pk_descr may be non-NULL here, when using partitions. It seems, 
+    it's ok to discard it
+  */
+  StringBuffer<64> fullname;
+  make_dbname_tablename(&fullname, table);
+  if (!(tbl_def= ddl_manager.find((uchar*)fullname.c_ptr(), fullname.length())))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+
+  key_descr= tbl_def->key_descr;
+  pk_descr= key_descr[table->s->primary_key];
+
+  pk_key_parts= table->key_info[table->s->primary_key].user_defined_key_parts;
+
+  uint key_len= table->key_info[table->s->primary_key].key_length; 
+  pk_descr->setup(table);  // move this into get_share() ??
+  uint packed_key_len= pk_descr->max_storage_fmt_length();
+
+  if (!(pk_tuple= (uchar*)my_malloc(key_len, MYF(0))) ||
+      !(pk_packed_tuple= (uchar*)my_malloc(packed_key_len, MYF(0))))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+  
+  /* Sometimes, we may use sec_key_packed_tuple for storing packed PK */
+  uint max_packed_sec_key_len= packed_key_len;
+  for (uint i= 0; i < table->s->keys; i++)
+  {
+    if (i == table->s->primary_key) /* Primary key was processed above */
+      continue;
+
+    key_descr[i]->setup(table);  // move this into get_share() ??
+
+    uint packed_len= key_descr[i]->max_storage_fmt_length();
+    if (packed_len > max_packed_sec_key_len)
+      max_packed_sec_key_len= packed_len;
+  }
+
+  if (!(sec_key_packed_tuple= (uchar*)my_malloc(max_packed_sec_key_len,
+                                                MYF(0))) ||
+      !((sec_key_tails= (uchar*)my_malloc(max_packed_sec_key_len, MYF(0)))))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+
+  info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+  
+  /* TODO: move the following to where TABLE_SHARE is opened: */
+  if (table->next_number_field)
+    load_auto_incr_value();
+
+  DBUG_RETURN(0);
+}
+
+
+int ha_leveldb::close(void)
+{
+  DBUG_ENTER("ha_leveldb::close");
+  
+  pk_descr= NULL;
+  key_descr= NULL;
+
+  if (pk_tuple)
+    my_free(pk_tuple);
+  pk_tuple= NULL;
+
+  if (pk_packed_tuple)
+    my_free(pk_packed_tuple);
+  pk_packed_tuple= NULL;
+  
+  if (sec_key_packed_tuple)
+    my_free(sec_key_packed_tuple);
+  sec_key_packed_tuple= NULL;
+  
+  if (sec_key_tails)
+    my_free(sec_key_tails);
+  sec_key_tails= NULL;
+
+  DBUG_RETURN(free_share(share));
+}
+
+
+const int HA_ERR_LEVELDB_UNIQUE_NOT_SUPPORTED= HA_ERR_LAST+1;
+const int HA_ERR_LEVELDB_PK_REQUIRED= HA_ERR_LAST+2;
+const int HA_ERR_LEVELDB_TOO_MANY_LOCKS= HA_ERR_LAST+3;
+
+bool ha_leveldb::get_error_message(int error, String *buf)
+{
+  if (error == HA_ERR_LEVELDB_PK_REQUIRED)
+    buf->append("Table must have a PRIMARY KEY");
+  else if (error == HA_ERR_LEVELDB_UNIQUE_NOT_SUPPORTED)
+    buf->append("Unique indexes are not supported");
+  else if (error == HA_ERR_LEVELDB_TOO_MANY_LOCKS)
+    buf->append("Number of locks held reached @@leveldb_max_row_locks");
+  return FALSE; /* not a temporary error */
+}
+
+
+/*
+  Create structures needed for storing data in leveldb. This is called when the
+  table is created. The structures will be shared by all TABLE* objects.
+
+  @param
+    table_arg  Table with definition
+    db_table   "dbname.tablename" 
+    len        strlen of the above
+
+  @return
+    0      - Ok 
+    other  - error, either given table ddl is not supported by leveldb or OOM.
+*/
+
+int ha_leveldb::create_key_defs(TABLE *table_arg, const char *db_table, uint len)
+{
+  uint i;
+  DBUG_ENTER("ha_leveldb::create_key_defs");
+  uint n_keys= table_arg->s->keys;
+   
+  /* Don't allow to create unique indexes */
+  for (i= 0; i < table_arg->s->keys; i++)
+  {
+    if (table_arg->key_info[i].flags & HA_NOSAME && 
+        i != table_arg->s->primary_key)
+    {
+      DBUG_RETURN(HA_ERR_LEVELDB_UNIQUE_NOT_SUPPORTED); 
+    }
+  }
+
+  /* Create table/key descriptions and put them into the data dictionary */
+  if (!(key_descr= (LDBSE_KEYDEF**)my_malloc(sizeof(LDBSE_KEYDEF*) * n_keys,
+                                             MYF(MY_ZEROFILL))))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+  
+  memset(key_descr, 0, sizeof(LDBSE_KEYDEF*) * n_keys);
+  tbl_def= NULL;
+
+  for (i= 0; i < table_arg->s->keys; i++)
+  {
+    if (!(key_descr[i]= new LDBSE_KEYDEF(ddl_manager.get_next_number(), i)))
+      goto error;
+  }
+  pk_descr= key_descr[table_arg->s->primary_key];
+
+  if (!(tbl_def= new LDBSE_TABLE_DEF))
+    goto error;
+  
+  tbl_def->n_keys= n_keys;
+  tbl_def->key_descr= key_descr;
+  tbl_def->dbname_tablename.append(db_table, len);
+  if (ddl_manager.put_and_write(tbl_def, ldb))
+    goto error;
+
+  DBUG_RETURN(0);
+
+error:
+  /* Delete what we have allocated so far */
+  for (i= 0; i < table_arg->s->keys;i++)
+    delete key_descr[i];
+  delete tbl_def;
+
+  DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+}
+
+
+static int leveldb_normalize_tablename(const char *tablename,
+                                       StringBuffer<256> *strbuf)
+{
+  DBUG_ASSERT(tablename[0] == '.' && tablename[1] == '/');
+  tablename += 2;
+
+  const char *p= tablename;
+  for (; *p != '/'; p++)
+  {
+    if (*p =='\0')
+    {
+      DBUG_ASSERT(0); // We were not passed table name?
+      return HA_ERR_INTERNAL_ERROR ;
+    }
+  }
+  strbuf->append(tablename, p - tablename);
+  strbuf->append('.');
+  strbuf->append(p + 1);
+  return 0;
+}
+
+
+/**
+  @brief
+  create() is called to create a database. The variable name will have the name
+  of the table.
+
+  @details
+  When create() is called you do not need to worry about
+  opening the table. Also, the .frm file will have already been
+  created so adjusting create_info is not necessary. You can overwrite
+  the .frm file at this point if you wish to change the table
+  definition, but there are no methods currently provided for doing
+  so.
+
+  Called from handle.cc by ha_create_table().
+
+  @see
+  ha_create_table() in handle.cc
+*/
+
+int ha_leveldb::create(const char *name, TABLE *table_arg,
+                       HA_CREATE_INFO *create_info)
+{
+  int res;
+  StringBuffer<256> strbuf;
+  DBUG_ENTER("ha_leveldb::create");
+  
+  /* 
+    Construct dbname.tablename ourselves, because parititioning 
+    passes strings like "./test/t14#P#p0" for individual partitions,
+    while table_arg->s->table_name has none of that.
+  */
+  if (leveldb_normalize_tablename(name, &strbuf))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+
+  /* 
+    We have HA_REQUIRE_PRIMARY_KEY flag, which guarantees there will be a
+    primary key. 
+    But there is an exception: the query
+
+      ALTER TABLE ... DROP COLUMN primary_key_column
+
+    will attempt to create a table without primary key.
+  */
+  if (table_arg->s->primary_key == MAX_INDEXES)
+  {
+    DBUG_RETURN(HA_ERR_LEVELDB_PK_REQUIRED);
+  }
+
+  if ((res= create_key_defs(table_arg, strbuf.ptr(), strbuf.length())))
+    DBUG_RETURN(res);
+  
+  if (create_info->auto_increment_value)
+     tbl_def->auto_incr_val= create_info->auto_increment_value;
+
+  /*
+    We only support auto_increment at start of the PRIMARY KEY.
+  */ 
+  Field *field;
+  //if ((field= table_arg->next_number_field))
+  if ((field= table_arg->found_next_number_field))
+  {
+    int pk= table_arg->s->primary_key;
+    Field *pk_field= table_arg->key_info[pk].key_part[0].field;
+    if (field->field_index !=  pk_field->field_index)
+      DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+  }
+  DBUG_RETURN(0);
+}
+
+
+/*
+  This function is used only when the table has not yet been opened, and 
+  keyread_allowed bitmap doesn't have the correct values yet.
+  
+  See comment it ha_leveldb::index_flags() for details.
+*/
+
+bool ha_leveldb::check_keyread_allowed(uint inx, uint part, bool all_parts) const
+{
+  bool res= true;
+  KEY *key_info= &table_share->key_info[inx];
+  
+  Field_pack_info dummy1;
+  res= dummy1.setup(key_info->key_part[part].field);
+
+  if (res && all_parts)
+  {
+    for (uint i= 0; i < part; i++)
+    {
+      Field *field;
+      if ((field= key_info->key_part[i].field))
+      {
+        Field_pack_info dummy;
+        if (!dummy.setup(field))
+        {
+          /* Cannot do index-only reads for this column */
+          res= false;
+          break;
+        }
+      }
+    }
+  }
+  
+  uint pk= table_share->primary_key;
+  if (inx == pk && all_parts && 
+      part == table_share->key_info[pk].user_defined_key_parts)
+  {
+    pk_can_be_decoded= res;
+  }
+
+  return res;
+}
+
+
+/*
+  @note
+    The problem with this function is that SQL layer calls it, when
+     - the table has not been yet opened (no ::open() call done)
+     - this->table_share already exists, but it is in the process of being
+       filled, so some of fields are still NULL.
+     - In particular, table_share->key_info[inx].key_part[] is filled only up
+       to part #part. Subsequent key parts are not yet filled.
+
+    To complicate things further, SQL layer will call index_flags() with 
+    all_parts=TRUE. Essentially, we're asked to provide flags for reading
+    keyparts whose datatype is not yet known.
+
+    We walk around this problem by using check_keyread_allowed(), which uses
+    table_share object and is careful not to step on unitialized data.
+
+    When we get a call with all_parts=TRUE, we try to analyze all parts but
+    ignore those that have key_part->field==NULL (these are not initialized
+    yet).
+*/
+
+ulong ha_leveldb::index_flags(uint inx, uint part, bool all_parts) const
+{
+  ulong base_flags= HA_READ_NEXT  |   // doesn't seem to be used
+                    HA_READ_ORDER | 
+                    HA_READ_RANGE |
+                    HA_READ_PREV;
+
+  if (check_keyread_allowed(inx, part, all_parts))
+    base_flags |= HA_KEYREAD_ONLY;
+
+  /* 
+    Index-only reads on primary key are the same as table scan for us. Still,
+    we need to explicitly "allow" them, otherwise SQL layer will miss some
+    plans.
+  */
+  if (inx == table_share->primary_key)
+    base_flags |= HA_KEYREAD_ONLY;
+
+  return base_flags;
+}
+
+
+/*
+  Read next index tuple through the secondary index.
+*/
+
+int ha_leveldb::secondary_index_read(int keyno, uchar *buf)
+{
+  if (scan_it->Valid())
+  {
+    leveldb::Slice key= scan_it->key();
+
+    /* Check if we've ran out of records of this index */
+    if (key_descr[keyno]->covers_key(key.data(), key.size()))
+    {
+      int rc;
+      //TODO: We could here check if we have ran out of range we're scanning
+      uint size= key_descr[keyno]->get_primary_key_tuple(pk_descr, key.data(), 
+                                                         (char*) pk_packed_tuple);
+      last_rowkey.copy((const char*)pk_packed_tuple, size, &my_charset_bin);
+
+      if (keyread_only && !lock_rows)
+      {
+        leveldb::Slice value= scan_it->value();
+        if (key_descr[keyno]->unpack_record(table, buf, &key, &value))
+          return HA_ERR_INTERNAL_ERROR;
+        rc= 0;
+      }
+      else
+        rc= get_row_by_rowid(buf, (const char*)pk_packed_tuple, size);
+
+      if (!rc)
+      {
+        table->status= 0;
+        return rc;
+      }
+    }
+  }
+  table->status= STATUS_NOT_FOUND;
+  return HA_ERR_END_OF_FILE;
+}
+
+
+//void store_key_image_to_rec(Field *field, uchar *ptr, uint len);
+
+int ha_leveldb::index_read_map(uchar *buf, const uchar *key,
+                               key_part_map keypart_map,
+                               enum ha_rkey_function find_flag)
+{
+  int rc= 0;
+  DBUG_ENTER("ha_leveldb::index_read_map");
+
+  uint key_parts= table->key_info[active_index].user_defined_key_parts;
+  LDBSE_KEYDEF *kd= key_descr[active_index];
+
+  if (active_index == table->s->primary_key && 
+      find_flag == HA_READ_KEY_EXACT &&
+      ((keypart_map == ((key_part_map(1) << key_parts) - 1) ||
+        keypart_map == HA_WHOLE_KEY)))
+  {
+    /* 
+      Equality lookup over primary key, using full tuple. 
+      This is a special case, use DB::Get.
+    */
+    uint size= kd->pack_index_tuple(table, pk_packed_tuple, key, keypart_map);
+    rc= get_row_by_rowid(buf, (const char*)pk_packed_tuple, size);
+    DBUG_RETURN(rc);
+  }
+
+  uint n_used_parts= my_count_bits(keypart_map);
+
+  uint packed_size; 
+
+  packed_size= kd->pack_index_tuple(table, sec_key_packed_tuple, key, 
+                                    keypart_map);
+
+  if (find_flag == HA_READ_PREFIX_LAST_OR_PREV || 
+      find_flag == HA_READ_PREFIX_LAST)
+  {
+    /* See below */
+    kd->successor(sec_key_packed_tuple, packed_size);
+  }
+
+  leveldb::Slice slice((char*)sec_key_packed_tuple, packed_size);
+  
+
+  leveldb::Slice rkey;
+  /*
+    This will open the iterator and position it at a record that's equal or
+    greater than the lookup tuple.
+  */
+  setup_index_scan(&slice);
+  bool move_forward= true;
+
+
+  switch (find_flag) {
+  case HA_READ_KEY_EXACT:
+  {
+    if (!scan_it->Valid())
+      rc= HA_ERR_KEY_NOT_FOUND;
+    else
+    {
+      rkey= scan_it->key();
+      if (!kd->covers_key(rkey.data(), rkey.size()) ||
+           kd->cmp_full_keys(rkey.data(), rkey.size(), 
+                             slice.data(), slice.size(), n_used_parts))
+      {
+        /* 
+          The record we've got is not from this index, or is not equal to the
+          lookup table
+        */
+        rc= HA_ERR_KEY_NOT_FOUND;
+      }
+    }
+    break;
+  }
+  case HA_READ_KEY_OR_NEXT:
+  {
+    if (!scan_it->Valid())
+      rc= HA_ERR_KEY_NOT_FOUND;
+    else
+    {
+      rkey= scan_it->key();
+      if (!kd->covers_key(rkey.data(), rkey.size()))
+      {
+        /* The record we've got is not from this index */
+        rc= HA_ERR_KEY_NOT_FOUND;
+      }
+    }
+    break;
+  }
+  case HA_READ_BEFORE_KEY:
+  {
+    move_forward= false;
+    /* We want to read the record that's right *before* the given key.  */
+    if (!scan_it->Valid())
+    {
+      /*
+        All the values in the database are smaller than our key. Two cases
+         - our index is the last in db. Its last value is a match 
+         - our index has no records (in that case we will get a record from 
+           our index and detect it below)
+      */
+      scan_it->SeekToLast();
+    }
+    else
+    {
+      /*
+        LevelDB iterator is positioned at "the first key in the source that 
+        at or past target".
+        We need to step one key back, so that we're at the last key that is
+        before the target.
+        If the passed key is greater than the max. value that is found in the
+        table, then iterator is pointing at the *first* record in subsequent
+        table/index.
+      */
+      scan_it->Prev();
+    }
+    /* fall through */
+  }
+  case HA_READ_AFTER_KEY:
+  {
+    bool in_key;
+    bool have_row;
+    /* 
+      Walk forward until we've found a record that is not equal to the lookup
+      tuple, but still belongs to this index.
+    */
+    while ((have_row= scan_it->Valid()))
+    {
+      rkey= scan_it->key();
+      if (!(in_key= kd->covers_key(rkey.data(), rkey.size())) ||
+          kd->cmp_full_keys(rkey.data(), rkey.size(), 
+                            slice.data(), slice.size(),
+                            n_used_parts))
+        break;
+
+      if (move_forward) 
+        scan_it->Next();
+      else
+        scan_it->Prev();
+    }
+    if (!have_row || !in_key)
+      rc= HA_ERR_END_OF_FILE;
+    break;
+  }
+  case HA_READ_KEY_OR_PREV:
+  {
+    if (!scan_it->Valid())
+    {
+      /*
+        We're after the last value in the database. It could be we needed the
+        last one.
+      */
+      scan_it->SeekToLast();
+    }
+    /* We should see a key that is less-or-equal than specified */
+    bool in_key;
+    bool have_row;
+    while ((have_row= scan_it->Valid()))
+    {
+      rkey= scan_it->key();
+      if (!(in_key= kd->covers_key(rkey.data(), rkey.size())) ||
+           kd->cmp_full_keys(rkey.data(), rkey.size(), 
+                             slice.data(), slice.size(),
+                             n_used_parts) <= 0)
+        break;
+      scan_it->Prev();
+    }
+    if (!have_row || !in_key)
+      rc= HA_ERR_END_OF_FILE;
+    break;
+  }
+  case HA_READ_PREFIX_LAST:
+  case HA_READ_PREFIX_LAST_OR_PREV:
+  {
+    /* 
+      Given a prefix of (VAL1,VAL2), get the last record that has
+      (kp1,kp2)=(VAL1,VAL2).  This cannot be translated directly to LevelDB
+      Iterator command.
+
+      We navigate to (VAL1,VAL2+1) and then step one record back. 
+    */
+    if (!scan_it->Valid())
+    {
+      /*
+        We're after the last value in the database. It could be we needed the
+        last one.
+      */
+      scan_it->SeekToLast();
+    }
+    else
+      scan_it->Prev();
+
+    if (scan_it->Valid())
+    {
+      rc= 0;
+      rkey= scan_it->key();
+      if (!kd->covers_key(rkey.data(), rkey.size()))
+      {
+        /* The record we've got is not from this index */
+        rc= HA_ERR_KEY_NOT_FOUND;
+      }
+      else
+      if (find_flag == HA_READ_PREFIX_LAST) 
+      {
+        packed_size= kd->pack_index_tuple(table, sec_key_packed_tuple, key, 
+                                          n_used_parts);
+        /*
+          Check if the record has the same search prefix.
+        */
+        if (kd->cmp_full_keys(rkey.data(), rkey.size(), 
+                              (const char*)sec_key_packed_tuple, packed_size,
+                              n_used_parts))
+          rc= HA_ERR_END_OF_FILE;
+      }
+    }
+    else
+      rc= HA_ERR_KEY_NOT_FOUND;
+
+    break;
+  }
+  default:
+    DBUG_ASSERT(0);
+    break;
+  }
+
+  if (rc)
+  {
+    table->status= STATUS_NOT_FOUND; /* Only not found error is possible */
+    DBUG_RETURN(rc);
+  }
+
+  skip_scan_it_next_call= FALSE;
+  uint pk_size;
+  
+  if (active_index == table->s->primary_key)
+  {
+    pk_size= rkey.size();
+    memcpy(pk_packed_tuple, rkey.data(), pk_size);
+    last_rowkey.copy(rkey.data(), pk_size, &my_charset_bin);
+    if (lock_rows)
+    {
+      /* We need to put a lock and re-read */
+      // TODO: what if we find that the row is gone? Need a re-read?
+      rc= get_row_by_rowid(buf, (const char*)pk_packed_tuple, pk_size);
+    }
+    else
+    {
+      /* Unpack from the row we've read */
+      leveldb::Slice value= scan_it->value();
+      convert_record_from_storage_format(&value, buf);
+    }
+  }
+  else
+  {
+    pk_size= kd->get_primary_key_tuple(pk_descr, rkey.data(), 
+                                       (char*) pk_packed_tuple);
+    last_rowkey.copy((const char*)pk_packed_tuple, pk_size, &my_charset_bin);
+
+    if (keyread_only && !lock_rows)
+    {
+      /* Get the key columns and primary key value */
+      leveldb::Slice value= scan_it->value();
+      if (kd->unpack_record(table, buf, &rkey, &value))
+        rc= HA_ERR_INTERNAL_ERROR;
+      else
+        rc= 0;
+    }
+    else
+      rc= get_row_by_rowid(buf, (const char*)pk_packed_tuple, pk_size);
+  }
+
+  if (rc)
+  {
+    /* the only possible error condition is record-not-found */
+    table->status= STATUS_NOT_FOUND;
+  }
+  else
+    table->status= 0;
+  DBUG_RETURN(rc);
+}
+
+
+int ha_leveldb::index_read_last_map(uchar * buf, const uchar * key, 
+                                    key_part_map keypart_map)
+{
+  return index_read_map(buf, key, keypart_map, HA_READ_PREFIX_LAST);
+}
+
+
+static void dbug_dump_str(FILE *out, const char *str, int len)
+{
+  fprintf(out, "\"");
+  for (int i= 0; i < len; i++)
+  {
+    if (str[i] > 32)
+      fprintf(out, "%c", str[i]);
+    else
+      fprintf(out, "\\%d", str[i]);
+  }
+  fprintf(out, "\"");
+}
+
+
+/*
+  Debugging help: dump the whole database into a human-readable file.
+  Usage: 
+    dbug_dump_database(ldb);
+*/
+
+void dbug_dump_database(leveldb::DB *db)
+{
+  FILE *out= fopen("/tmp/leveldb.dump", "wt");
+  if (!out)
+    return;
+
+  leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
+  for (it->SeekToFirst(); it->Valid(); it->Next()) {
+    leveldb::Slice key= it->key();
+    leveldb::Slice val= it->value();
+    dbug_dump_str(out, key.data(), key.size());
+    fprintf(out, " -> ");
+    dbug_dump_str(out, val.data(), val.size());
+    fprintf(out, "\n");
+  }
+  //assert(it->status().ok());  // Check for any errors found during the scan
+  delete it;
+  fclose(out);
+}
+
+
+int ha_leveldb::get_row_by_rowid(uchar *buf, const char *rowid, uint rowid_size)
+{
+  int rc;
+  DBUG_ENTER("ha_leveldb::get_row_by_rowid");
+
+  leveldb::Slice key_slice(rowid, rowid_size);
+
+  Ldb_transaction *trx= get_or_create_trx(table->in_use);
+  Row_lock *lock;
+  bool timed_out;
+  if (lock_rows)
+  {
+    if (!(lock= trx->get_lock((const uchar*)rowid, rowid_size, &timed_out)))
+      DBUG_RETURN(return_lock_failure(timed_out));
+  }
+
+  leveldb::ReadOptions options;
+  if (!lock_rows)
+    options.snapshot= trx->snapshot;
+  
+  bool found;
+  if (!trx->changes.Get(key_slice, &retrieved_record, &found))
+  {
+    leveldb::Status s= ldb->Get(options, key_slice, &retrieved_record);
+    found= !s.IsNotFound();
+  }
+
+  if (found)
+  {
+    if (lock_rows)
+      trx->add_lock(lock);
+    last_rowkey.copy((const char*)rowid, rowid_size, &my_charset_bin);
+    convert_record_from_storage_format(buf);
+    table->status= 0;
+    rc= 0;
+  }
+  else
+  {
+    if (lock_rows)
+      row_locks.release_lock(trx->pins, lock);
+    table->status= STATUS_NOT_FOUND;
+    rc= HA_ERR_KEY_NOT_FOUND;
+  }
+
+  DBUG_RETURN(rc);
+}
+
+
+int ha_leveldb::index_next(uchar *buf)
+{
+  return index_next_with_direction(buf, true);
+}
+
+
+int ha_leveldb::index_prev(uchar *buf)
+{
+  return index_next_with_direction(buf, false);
+}
+
+
+int ha_leveldb::index_next_with_direction(uchar *buf, bool move_forward)
+{
+  int rc;
+  DBUG_ENTER("ha_leveldb::index_next");
+
+  if (active_index == table->s->primary_key)
+    rc= rnd_next_with_direction(buf, move_forward);
+  else
+  {
+    if (skip_scan_it_next_call)
+      skip_scan_it_next_call= FALSE;
+    else
+    {
+      if (move_forward)
+        scan_it->Next();  /* this call cannot fail */
+      else
+        scan_it->Prev();
+    }
+
+    rc= secondary_index_read(active_index, buf);
+  }
+
+  DBUG_RETURN(rc);
+}
+
+
+int ha_leveldb::index_first(uchar *buf)
+{
+  uchar *key;
+  uint key_size;
+  int rc;
+  DBUG_ENTER("ha_leveldb::index_first");
+  
+  key= (active_index == table->s->primary_key)? pk_packed_tuple : 
+                                                sec_key_packed_tuple;
+  key_descr[active_index]->get_infimum_key(key, &key_size);
+  leveldb::Slice index_key((const char*)key, key_size);
+
+  setup_index_scan(&index_key);
+  skip_scan_it_next_call= TRUE;
+
+  rc= index_next(buf);
+  DBUG_RETURN(rc);
+}
+
+
+int ha_leveldb::index_last(uchar *buf)
+{
+  uchar *key;
+  uint key_size;
+  int rc;
+  DBUG_ENTER("ha_leveldb::index_last");
+  
+  key= (active_index == table->s->primary_key)? pk_packed_tuple : 
+                                                sec_key_packed_tuple;
+  key_descr[active_index]->get_supremum_key(key, &key_size);
+  leveldb::Slice index_key((const char*)key, key_size);
+
+  setup_index_scan(&index_key);
+
+  if (!scan_it->Valid())
+  {
+    /*
+      Leveldb keyspace has no records that follow our index. It could be, our
+      index is the last in the keyspace. Navigate to last record in the
+      keyspace. 
+    */
+    scan_it->SeekToLast();
+  }
+  else
+  {
+    /*
+      Iterator is pointing at some record right after the end of the index.
+      Move one record back.
+    */
+    scan_it->Prev();
+  }
+  skip_scan_it_next_call= FALSE;
+  
+  if (active_index == table->s->primary_key)
+  {
+    skip_scan_it_next_call= true;
+    rc= rnd_next_with_direction(buf, false);
+  }
+  else
+    rc= secondary_index_read(active_index, buf);
+
+  DBUG_RETURN(rc);
+}
+
+
+void ha_leveldb::unlock_row()
+{
+  if (lock_rows)
+  {
+    Ldb_transaction *trx= get_or_create_trx(table->in_use);
+    trx->release_last_lock();
+  }
+}
+
+
+//static const char* empty_str="";
+
+int ha_leveldb::write_row(uchar *buf)
+{
+  DBUG_ENTER("ha_leveldb::write_row");
+  DBUG_ASSERT(buf == table->record[0]);
+  DBUG_ASSERT(lock_rows);
+  
+  /* Update AUTO_INCREMENT column */
+  bool using_auto_incr_value= false;
+
+  /*
+    Note: "buf == table->record[0]" is copied from innodb. I am not aware of 
+    any use cases where this condition is not true.
+  */
+  if (table->next_number_field && buf == table->record[0])
+  {
+    int err;
+    if ((err= update_auto_increment()))
+    {
+      DBUG_RETURN(err);
+    }
+    using_auto_incr_value= true;
+  }
+
+  /* Get a packed primary key value */
+  uint packed_size= pk_descr->pack_record(table, buf, pk_packed_tuple, NULL, NULL);
+  leveldb::Slice key_slice((const char*)pk_packed_tuple, packed_size);
+
+  Ldb_transaction *trx= get_or_create_trx(table->in_use);
+  bool do_locking= !THDVAR(table->in_use, bulk_load);
+  Row_lock *lock= NULL; // init to shut up the compiler
+
+  if (do_locking)
+  {
+    /* 
+      Get a record lock to make sure we do not overwrite somebody's changes 
+    */
+    bool timed_out;
+    if (!(lock= trx->get_lock(pk_packed_tuple, packed_size, &timed_out)))
+    {
+      DBUG_RETURN(return_lock_failure(timed_out));
+    }
+
+    /* 
+      note: we intentionally don't set options.snapshot here. We want to read 
+      the latest committed data.
+    */ 
+    leveldb::ReadOptions options; 
+
+    bool found;
+    if (!trx->changes.Get(key_slice, &retrieved_record, &found))
+    {
+      leveldb::Status s= ldb->Get(options, key_slice, &retrieved_record);
+      found= !s.IsNotFound();
+    }
+
+    if (found) 
+    {
+      /* There is a row with this rowid already */
+      row_locks.release_lock(trx->pins, lock);
+      DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
+    }
+  }
+
+  /* Ok, we keep a lock. This will prevent concurrent writes with this rowid */
+  trx->prepare_for_write();
+  
+  if (do_locking)
+    trx->add_lock(lock); /* the lock will be released when trx commits */
+
+  /* Write every secondary index */
+  for (uint i= 0; i < table->s->keys; i++)
+  {
+    if (i != table->s->primary_key)
+    {
+      int packed_size;
+      int tail_size;
+
+      packed_size= key_descr[i]->pack_record(table, buf, sec_key_packed_tuple,
+                                             sec_key_tails, &tail_size);
+
+      leveldb::Slice secondary_key_slice((char*)sec_key_packed_tuple, 
+                                         packed_size);
+      leveldb::Slice value_slice((const char*)sec_key_tails, tail_size);
+      trx->changes.Put(secondary_key_slice, value_slice);
+      trx->n_writes++;
+    }
+  }
+ 
+  /* Write primary_key -> record */
+  if (!using_auto_incr_value && table->next_number_field)
+    update_auto_incr_val();
+
+  leveldb::Slice value_slice;
+  convert_record_to_storage_format(&value_slice);
+  
+  trx->changes.Put(key_slice, value_slice);
+  trx->n_writes++;
+
+  if (do_locking && trx->n_writes > THDVAR(table->in_use, bulk_load_size))
+  {
+    /* Bulk insert mode: flush the write batch if it became too big */
+    if (trx->flush_batch())
+      DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+  }
+
+  DBUG_RETURN(0);
+}
+
+
+/*
+  Open a cursor and position it at the passed record
+*/
+
+void ha_leveldb::setup_index_scan(leveldb::Slice *slice)
+{
+  Ldb_transaction *trx= get_or_create_trx(table->in_use);
+
+  /*
+    SQL layer can call rnd_init() multiple times in a row.
+    In that case, re-use the iterator, but re-position it at the table start.
+  */
+  if (!scan_it)
+  {
+    leveldb::ReadOptions options;
+    if (!lock_rows)
+      options.snapshot= trx->snapshot;
+    leveldb::Iterator* leveldb_it= ldb->NewIterator(options);
+    scan_it= new Apply_changes_iter;
+    scan_it->init(&trx->changes, leveldb_it);
+  }
+  
+  /* 
+    Seek() will "Position at the first key in the source that at or past target".
+    The operation cannot fail.
+  */
+  scan_it->Seek(*slice);
+}
+
+
+int ha_leveldb::rnd_init(bool scan)
+{
+  DBUG_ENTER("ha_leveldb::rnd_init");
+  
+  if (scan)
+  {
+    uint key_size;
+    pk_descr->get_infimum_key(pk_packed_tuple, &key_size);
+    leveldb::Slice table_key((const char*)pk_packed_tuple, key_size);
+
+    setup_index_scan(&table_key);
+    skip_scan_it_next_call= true;
+  }
+  else
+  {
+    /* We don't need any preparations for rnd_pos() calls. */
+  }
+
+  DBUG_RETURN(0);
+}
+
+
+int ha_leveldb::rnd_next(uchar *buf)
+{
+  return rnd_next_with_direction(buf, true);
+}
+
+
+/*
+  See also secondary_index_read(). 
+*/
+int ha_leveldb::rnd_next_with_direction(uchar *buf, bool move_forward)
+{
+  int rc;
+  DBUG_ENTER("ha_leveldb::rnd_next");
+  
+  if (!scan_it)
+  {
+    /*
+      We can get here when SQL layer has called
+
+        h->index_init(PRIMARY);
+        h->index_read_map(full index tuple, HA_READ_KEY_EXACT);
+
+      In this case, we should return EOF.
+    */
+    table->status= STATUS_NOT_FOUND;
+    DBUG_RETURN(HA_ERR_END_OF_FILE);
+  }
+
+retry:
+  if (skip_scan_it_next_call)
+    skip_scan_it_next_call= false;
+  else
+  {
+    if (move_forward)
+      scan_it->Next();  /* this call cannot fail */
+    else
+      scan_it->Prev();  /* this call cannot fail */
+  }
+
+  if (scan_it->Valid())
+  {
+    /* check if we're out of this table */
+    leveldb::Slice key= scan_it->key();
+    if (!pk_descr->covers_key(key.data(), key.size()))
+    {
+      rc= HA_ERR_END_OF_FILE;
+      table->status= STATUS_NOT_FOUND;
+    }
+    else
+    {
+      if (lock_rows)
+      {
+        Ldb_transaction *trx= get_or_create_trx(table->in_use);
+        /*
+          Here is a problem. We've read a row without locking it.
+          We could not lock the row before reading it, because we didn't know
+          its rowkey.
+          
+          Current solution is: lock the row and re-read it.
+        */
+        Row_lock *lock;
+        bool timed_out;
+        if (!(lock= trx->get_lock((const uchar*)key.data(), key.size(), &timed_out)))
+          DBUG_RETURN(return_lock_failure(timed_out));
+        
+        leveldb::ReadOptions options;
+        /* lock_rows==TRUE, so not setting options.snapshot */
+        bool found;
+        if (!trx->changes.Get(key, &retrieved_record, &found))
+        {
+          leveldb::Status s= ldb->Get(options, key, &retrieved_record);
+          found= !s.IsNotFound();
+        }
+
+        if (!found) 
+        {
+          /* The row is not there already. Try another one */
+          row_locks.release_lock(trx->pins, lock);
+          goto retry;
+        }
+        trx->add_lock(lock);
+
+        last_rowkey.copy(key.data(), key.size(), &my_charset_bin);
+        convert_record_from_storage_format(buf);
+        table->status= 0;
+        rc= 0;
+      }
+      else
+      {
+        last_rowkey.copy(key.data(), key.size(), &my_charset_bin);
+        leveldb::Slice value= scan_it->value();
+        convert_record_from_storage_format(&value, buf);
+        rc= 0;
+        table->status= 0;
+      }
+    }
+  }
+  else
+    rc= HA_ERR_END_OF_FILE;
+
+  DBUG_RETURN(rc);
+}
+
+
+int ha_leveldb::rnd_end()
+{
+  DBUG_ENTER("ha_leveldb::rnd_end");
+
+  if (scan_it)
+  {
+    delete scan_it;
+    scan_it= NULL;
+  }
+  DBUG_RETURN(0);
+}
+
+
+int ha_leveldb::index_end() 
+{
+
+  if (scan_it)
+  {
+    delete scan_it;
+    scan_it= NULL;
+  }
+
+  active_index= MAX_KEY; 
+  return 0;
+}
+
+
+int ha_leveldb::delete_all_rows()
+{
+  DBUG_ENTER("ha_leveldb::delete_all_rows");
+  /*
+    We will have to delete records one-by-one anyway. Let the SQL layer do
+    it.
+  */
+  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
+}
+
+int ha_leveldb::truncate()
+{
+  mysql_mutex_lock(&tbl_def->mutex);
+  tbl_def->auto_incr_val= 1;
+  mysql_mutex_unlock(&tbl_def->mutex);
+  remove_rows(tbl_def);
+  return 0;
+}
+
+/*
+  Delete the row we've last read. Ignore the parameter.
+  (Check out InnoDB: row_update_for_mysql() has "UT_NOT_USED(mysql_rec)")
+*/
+int ha_leveldb::delete_row(const uchar *buf)
+{
+  DBUG_ENTER("ha_leveldb::delete_row");
+  
+  leveldb::Slice key_slice(last_rowkey.ptr(), last_rowkey.length());
+  Ldb_transaction *trx= get_or_create_trx(table->in_use);
+  trx->prepare_for_write();
+  trx->changes.Delete(key_slice);
+  DBUG_ASSERT(buf == table->record[0]);
+
+  // Delete the record for every secondary index
+  for (uint i= 0; i < table->s->keys; i++)
+  {
+    if (i != table->s->primary_key)
+    {
+      int packed_size;
+      packed_size= key_descr[i]->pack_record(table, buf, sec_key_packed_tuple,
+                                             NULL, NULL);
+      leveldb::Slice secondary_key_slice((char*)sec_key_packed_tuple, 
+                                         packed_size);
+      trx->changes.Delete(secondary_key_slice);
+    }
+  }
+
+  DBUG_RETURN(0);
+}
+
+
+int ha_leveldb::info(uint flag)
+{
+  DBUG_ENTER("ha_leveldb::info");
+  
+  if (!table)
+    return 1;
+
+  if (flag & HA_STATUS_VARIABLE)
+  {
+    stats.records= 1000;
+  }
+  if (flag & HA_STATUS_CONST)
+  {
+    DBUG_ASSERT(table->s->primary_key != MAX_KEY);
+
+    ref_length= pk_descr->max_storage_fmt_length();
+  }
+
+  if (flag & HA_STATUS_ERRKEY)
+  {
+    /* 
+      Currently we support only primary keys so we know which key had a
+      uniqueness violation.
+    */
+    errkey= 0;
+    dup_ref= pk_tuple; //TODO: this should store packed PK.
+  }
+
+  DBUG_RETURN(0);
+}
+
+
+void ha_leveldb::position(const uchar *record)
+{
+  DBUG_ENTER("ha_leveldb::position");
+
+  memcpy(ref, last_rowkey.ptr(), ref_length);
+  DBUG_VOID_RETURN;
+}
+
+
+int ha_leveldb::rnd_pos(uchar *buf, uchar *pos)
+{
+  int rc;
+  DBUG_ENTER("ha_leveldb::rnd_pos");
+
+  rc= get_row_by_rowid(buf, (const char*)pos, ref_length);
+
+  DBUG_RETURN(rc);
+}
+
+
+int ha_leveldb::return_lock_failure(bool timed_out)
+{
+  THD *thd;
+  if ((thd= table->in_use)) 
+  {
+    thd_mark_transaction_to_rollback(thd, false);
+  }
+  return timed_out? HA_ERR_LOCK_WAIT_TIMEOUT : HA_ERR_LEVELDB_TOO_MANY_LOCKS;
+}
+
+
+int ha_leveldb::update_row(const uchar *old_data, uchar *new_data)
+{
+  DBUG_ENTER("ha_leveldb::update_row");
+  DBUG_ASSERT(lock_rows);
+
+  /*
+    old_data points to record we're updating. It is the same as the record
+    we've just read (for multi-table UPDATE, too, because SQL layer will make
+    an rnd_pos() call to re-read the record before calling update_row())
+  */
+  DBUG_ASSERT(new_data == table->record[0]);
+ 
+  /* Get a rowkey fo the new record */
+  uint packed_size= pk_descr->pack_record(table, new_data, pk_packed_tuple,
+                                          NULL, NULL);
+
+  leveldb::Slice key_slice((const char*)pk_packed_tuple, packed_size);
+  Ldb_transaction *trx= get_or_create_trx(table->in_use);
+
+  /* Compare rowkey for the new record with rowkey for the old one */
+  leveldb::Slice old_key_slice(last_rowkey.ptr(), last_rowkey.length());
+  if (primary_key_comparator.Compare(key_slice, old_key_slice))
+  {
+    /* Ok, they are different. We're doing DELETE+PUT */
+
+    /* 
+      We need to make sure that PUT will not overwrite some existing record.
+      Get a lock. on what we're going to write.
+    */
+    Row_lock *lock;
+    bool timed_out;
+    if (!(lock= trx->get_lock(pk_packed_tuple, packed_size, &timed_out)))
+      DBUG_RETURN(return_lock_failure(timed_out));
+
+    bool found;
+    if (!trx->changes.Get(key_slice, &retrieved_record, &found))
+    {
+      leveldb::ReadOptions options; 
+      /* Not setting options.snapshot, we need to check the real contents */
+      leveldb::Status s= ldb->Get(options, key_slice, &retrieved_record);
+      found= !s.IsNotFound();
+    }
+
+    if (found) 
+    {
+      row_locks.release_lock(trx->pins, lock);
+      DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
+    }
+
+    trx->prepare_for_write();
+    trx->add_lock(lock);
+    trx->changes.Delete(old_key_slice);
+  }
+
+  trx->prepare_for_write();
+
+  /* Update every index */
+  for (uint i= 0; i < table->s->keys; i++)
+  {
+    if (i != table->s->primary_key)
+    {
+      int packed_size;
+      int tail_size;
+      // TODO: compare old/new fields, and update only when actually necessary.
+
+      // First, a Delete()
+      {
+        packed_size= key_descr[i]->pack_record(table, old_data, 
+                                               sec_key_packed_tuple, 
+                                               NULL, NULL);
+        leveldb::Slice secondary_key_slice((char*)sec_key_packed_tuple, 
+                                           packed_size);
+        trx->changes.Delete(secondary_key_slice);
+      }
+
+      // Then, Put().
+      {
+        packed_size= key_descr[i]->pack_record(table, new_data, 
+                                               sec_key_packed_tuple,
+                                               sec_key_tails, &tail_size);
+        leveldb::Slice secondary_key_slice((char*)sec_key_packed_tuple, 
+                                           packed_size);
+        leveldb::Slice value_slice((const char*)sec_key_tails, tail_size);
+        trx->changes.Put(secondary_key_slice, value_slice);
+      }
+    }
+  }
+  
+  if (table->next_number_field)
+    update_auto_incr_val();
+  /* Write the table record */
+  leveldb::Slice value_slice;
+  convert_record_to_storage_format(&value_slice);
+  trx->changes.Put(key_slice, value_slice);
+
+  DBUG_RETURN(0);
+}
+
+
+/* The following function was copied from ha_blackhole::store_lock: */
+THR_LOCK_DATA **ha_leveldb::store_lock(THD *thd,
+                                         THR_LOCK_DATA **to,
+                                         enum thr_lock_type lock_type)
+{
+  DBUG_ENTER("ha_leveldb::store_lock");
+  if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
+  {
+    /*
+      Here is where we get into the guts of a row level lock.
+      If TL_UNLOCK is set
+      If we are not doing a LOCK TABLE or DISCARD/IMPORT
+      TABLESPACE, then allow multiple writers
+    */
+
+    if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
+         lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
+        && !thd_tablespace_op(thd))
+      lock_type = TL_WRITE_ALLOW_WRITE;
+
+    /*
+      In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
+      MySQL would use the lock TL_READ_NO_INSERT on t2, and that
+      would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
+      to t2. Convert the lock to a normal read lock to allow
+      concurrent inserts to t2.
+    */
+
+    if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd))
+      lock_type = TL_READ;
+
+    lock.type= lock_type;
+  }
+  *to++= &lock;
+  DBUG_RETURN(to);
+}
+
+
+int ha_leveldb::external_lock(THD *thd, int lock_type)
+{
+  int res= 0;
+  DBUG_ENTER("ha_leveldb::external_lock");
+  if (lock_type == F_UNLCK)
+  {
+    if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) 
+    {
+      /*
+        Do like InnoDB: when we get here, it's time to commit a
+        single-statement transaction.
+        
+        If the statement involved multiple tables, this code will be executed
+        for each of them, but that's ok because non-first trx->commit() calls
+        will be no-ops.
+      */
+      Ldb_transaction* trx= get_or_create_trx(thd);
+      res= trx->commit();
+      delete scan_it;
+      scan_it= NULL;
+    }
+    lock_rows= FALSE;
+  } 
+  else
+  {
+    /*
+      It's nice to do the following on start of every statement. The problem
+      is, handler->start_stmt() is not called for INSERTs. 
+      So, we put this code here.
+    */
+    Ldb_transaction* trx= get_or_create_trx(thd);
+    trx->set_params(THDVAR(table->in_use, lock_wait_timeout), 
+                    THDVAR(table->in_use, max_row_locks));
+
+    if (lock_type == F_WRLCK)
+    {
+      /* 
+        SQL layer signals us to take a write lock. It does so when starting DML
+        statement. We should put locks on the rows we're reading.
+      */
+      lock_rows= TRUE;
+    }
+
+    trans_register_ha(thd, FALSE, leveldb_hton);
+    if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+    {
+      trx->start_stmt();
+      trans_register_ha(thd, TRUE, leveldb_hton);
+    }
+  }
+
+  DBUG_RETURN(res);
+}
+
+
+int ha_leveldb::start_stmt(THD *thd, thr_lock_type lock_type)
+{
+  if (thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+  {
+    Ldb_transaction* trx= get_or_create_trx(thd);
+    trx->set_params(THDVAR(table->in_use, lock_wait_timeout), 
+                    THDVAR(table->in_use, max_row_locks));
+    trx->start_stmt();
+  }
+  return 0;
+}
+
+/*
+  Note: the following function is called when the table is not open. That is, 
+  this->table==NULL, pk_key_descr==NULL, etc. 
+
+  tablename points to line in form "./dbname/tablename".
+*/
+
+int ha_leveldb::delete_table(const char *tablename)
+{
+  StringBuffer<256> strbuf;
+  DBUG_ENTER("ha_leveldb::delete_table");
+
+  if (leveldb_normalize_tablename(tablename, &strbuf))
+  {
+    DBUG_ASSERT(0); // We were not passed table name?
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+  }
+
+
+  /* Find the table in the hash */
+  LDBSE_TABLE_DEF *tbl;
+  if (!(tbl= ddl_manager.find((uchar*)strbuf.c_ptr(), strbuf.length())))
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+
+  remove_rows(tbl);
+
+  /* 
+    Remove the table entry in data dictionary (this will also remove it from
+    the persistent data dictionary).
+  */
+  ddl_manager.remove(tbl, ldb, true);
+
+  DBUG_RETURN(0);
+}
+
+
+void ha_leveldb::remove_rows(LDBSE_TABLE_DEF *tbl)
+{
+  leveldb::Iterator* it= ldb->NewIterator(leveldb::ReadOptions());
+  
+  char key_buf[MAX_KEY_LENGTH];
+  uint key_len;
+  /* 
+    Remove all records in each index.
+    (This is is not crash-safe, but it doesn't matter, because bulk row
+    deletion will be handled on leveldb side)
+  */
+  for (uint i= 0; i < tbl->n_keys ; i++)
+  {
+    tbl->key_descr[i]->get_infimum_key((uchar*)key_buf, &key_len);
+
+    leveldb::Slice table_key(key_buf, key_len);
+    it->Seek(table_key);
+    while (it->Valid())
+    {
+      leveldb::Slice key= it->key();
+      if (!tbl->key_descr[i]->covers_key(key.data(), key.size()))
+        break;
+      ldb->Delete(leveldb::WriteOptions(), key);
+      it->Next();
+    }
+  }
+  delete it;
+}
+
+
+int ha_leveldb::rename_table(const char *from, const char *to)
+{
+  StringBuffer<256> from_str;
+  StringBuffer<256> to_str;
+  
+  if (leveldb_normalize_tablename(from, &from_str))
+    return HA_ERR_INTERNAL_ERROR;
+
+  if (leveldb_normalize_tablename(to, &to_str))
+    return HA_ERR_INTERNAL_ERROR;
+
+  if (ddl_manager.rename((uchar*)from_str.ptr(), from_str.length(),
+                         (uchar*)to_str.ptr(), to_str.length(), ldb))
+    return HA_ERR_INTERNAL_ERROR;
+
+  return 0;
+}
+
+/**
+  check_if_incompatible_data() called if ALTER TABLE can't detect otherwise
+  if new and old definition are compatible
+
+  @details If there are no other explicit signs like changed number of
+  fields this function will be called by compare_tables()
+  (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm
+  file.
+
+*/
+
+bool ha_leveldb::check_if_incompatible_data(HA_CREATE_INFO *info,
+                                            uint table_changes)
+{
+  DBUG_ENTER("ha_leveldb::check_if_incompatible_data");
+  // this function is needed only for online alter-table
+  DBUG_RETURN(COMPATIBLE_DATA_NO);
+}
+
+
+int ha_leveldb::extra(enum ha_extra_function operation)
+{
+  DBUG_ENTER("ha_leveldb::extra");
+
+  switch (operation) {
+  case HA_EXTRA_KEYREAD:
+    keyread_only= TRUE;
+    break;
+  case HA_EXTRA_NO_KEYREAD:
+    keyread_only= FALSE;
+    break;
+  default:
+    break;
+  }
+  DBUG_RETURN(0);
+}
+
+
+ha_rows ha_leveldb::records_in_range(uint inx, key_range *min_key,
+                                     key_range *max_key)
+{
+  DBUG_ENTER("ha_leveldb::records_in_range");
+  DBUG_RETURN(10);                         // low number to force index usage
+}
+
+
+void ha_leveldb::update_create_info(HA_CREATE_INFO *create_info)
+{
+  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
+  {
+    table->file->info(HA_STATUS_AUTO);
+    // TODO: the following is basic, we need to actually
+    //  store the specified value somewhere..
+    create_info->auto_increment_value= tbl_def->auto_incr_val;
+  }
+}
+
+
+void ha_leveldb::get_auto_increment(ulonglong offset, ulonglong increment,
+                                    ulonglong nb_desired_values,
+                                    ulonglong *first_value,
+                                    ulonglong *nb_reserved_values)
+{
+  if (!nb_desired_values)
+    nb_desired_values= 1;
+
+  mysql_mutex_lock(&tbl_def->mutex);
+  *first_value= tbl_def->auto_incr_val;
+  *nb_reserved_values= nb_desired_values;
+  tbl_def->auto_incr_val += nb_desired_values;
+  mysql_mutex_unlock(&tbl_def->mutex);
+}
+
+
+#if 0
+//TODO: do we have any status vars?
+static int show_leveldb_vars(THD *thd, SHOW_VAR *var, char *buff)
+{
+  //innodb_export_status();
+  //leveldb_counters_copy= leveldb_counters; 
+
+  var->type= SHOW_ARRAY;
+  //var->value= (char *) &leveldb_status_variables;
+  return 0;
+}
+#endif
+
+struct st_mysql_storage_engine leveldb_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+static struct st_mysql_show_var func_status[]=
+{
+ // {"Cassandra",  (char *)show_leveldb_vars, SHOW_FUNC},
+  {0,0,SHOW_UNDEF}
+};
+
+mysql_declare_plugin(leveldb_se)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &leveldb_storage_engine,
+  "LEVELDB",
+  "Monty Program Ab",
+  "LevelDB storage engine",
+  PLUGIN_LICENSE_GPL,
+  leveldb_init_func,                            /* Plugin Init */
+  leveldb_done_func,                            /* Plugin Deinit */
+  0x0001,                                       /* version number (0.1) */
+  func_status,                                  /* status variables */
+  leveldb_system_variables,                     /* system variables */
+  NULL,                                         /* config options */
+  0,                                            /* flags */
+}
+mysql_declare_plugin_end;
+
+
+/*
+  Compute a hash number for a PK value in RowKeyFormat.
+
+  @note 
+    RowKeyFormat is comparable with memcmp. This means, any hash function will
+    work correctly. We use my_charset_bin's hash function. 
+
+    Note from Bar: could also use crc32 function.
+*/
+
+ulong Primary_key_comparator::get_hashnr(const char *key, size_t key_len)
+{
+  ulong nr=1, nr2=4;
+  my_charset_bin.coll->hash_sort(&my_charset_bin, (const uchar*)key, key_len,
+                                 &nr, &nr2);
+  return((ulong) nr);
+}
+
diff --git a/storage/leveldb/ha_leveldb.h b/storage/leveldb/ha_leveldb.h
new file mode 100644
index 0000000..fef6fcf
--- /dev/null
+++ b/storage/leveldb/ha_leveldb.h
@@ -0,0 +1,307 @@
+/* 
+   Copyright (c) 2012,2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface			/* gcc class implementation */
+#endif
+
+
+#include "my_global.h"                   /* ulonglong */
+#include "thr_lock.h"                    /* THR_LOCK, THR_LOCK_DATA */
+#include "handler.h"                     /* handler */
+#include "my_base.h"                     /* ha_rows */
+
+#include "leveldb/db.h"
+#include "leveldb/comparator.h"
+#include "leveldb/write_batch.h"
+
+#include "sql_string.h"
+
+#include "ldb_applyiter.h"
+
+//#ifdef HAVE_PSI_INTERFACE
+extern PSI_stage_info stage_waiting_on_row_lock;
+
+extern "C"
+void thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond, mysql_mutex_t *mutex,
+                    const PSI_stage_info *stage, PSI_stage_info *old_stage);
+extern "C"
+void thd_exit_cond(MYSQL_THD thd, const PSI_stage_info *stage);
+
+/**
+  Mark transaction to rollback and mark error as fatal to a sub-statement.
+  @param  thd   Thread handle
+  @param  all   TRUE <=> rollback main transaction.
+*/
+extern "C"
+void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+
+//#endif
+
+/** @brief
+  LEVELDB_SHARE is a structure that will be shared among all open handlers.
+  This example implements the minimum of what you will probably need.
+
+  //TODO: join this with LDBSE_TABLE_DEF ? 
+*/
+typedef struct st_leveldb_share {
+  char *table_name;
+  uint table_name_length,use_count;
+  //mysql_mutex_t mutex;
+
+  THR_LOCK lock;
+} LEVELDB_SHARE;
+
+class LDBSE_KEYDEF;
+class LDBSE_TABLE_DEF;
+class Row_lock;
+class Ldb_transaction;
+
+/** @brief
+  Class definition for the storage engine
+*/
+
+class ha_leveldb: public handler
+{
+  THR_LOCK_DATA lock;      ///< MySQL lock
+  LEVELDB_SHARE *share;    ///< Shared lock info
+  
+  /* Iterator used for range scans and for full table/index scans */
+  Apply_changes_iter *scan_it;
+
+  LDBSE_TABLE_DEF *tbl_def;
+
+  /* Primary Key encoder from KeyTupleFormat to StorageFormat */
+  LDBSE_KEYDEF *pk_descr;
+
+  /* Array of index descriptors */
+  LDBSE_KEYDEF **key_descr;
+
+  bool check_keyread_allowed(uint inx, uint part, bool all_parts) const;
+  /* 
+    Number of key parts in PK. This is the same as 
+      table->key_info[table->s->primary_key].keyparts
+  */
+  uint pk_key_parts;
+  
+  //Ldb_transaction *cur_trx;
+
+  /*
+    TRUE <=> Primary Key columns can be decoded from the index
+  */
+  mutable bool pk_can_be_decoded;
+
+  uchar *pk_tuple; /* Buffer for storing PK in KeyTupleFormat */
+  uchar *pk_packed_tuple; /* Buffer for storing PK in StorageFormat */
+  // ^^ todo: change it to 'char*'? TODO: ^ can we join this with last_rowkey?
+
+  uchar *sec_key_packed_tuple;
+  uchar *sec_key_tails;
+ 
+  /* rowkey of the last record we've read, in StorageFormat. */
+  String last_rowkey; 
+  
+  /* Buffer used by convert_record_to_storage_format() */
+  String storage_record;
+
+  /* Last retrieved record, in table->record[0] data format */
+  std::string retrieved_record;
+  
+  /* If TRUE, reads should place locks on rows */
+  bool lock_rows;
+
+  /* Lock that we've placed on the row we've just read. */
+  Row_lock *last_row_lock;
+ 
+  /* TRUE means we're doing an index-only read. FALSE means otherwise. */
+  bool keyread_only;
+  
+  bool skip_scan_it_next_call;
+
+  int create_key_defs(TABLE *table_arg, const char *db_table, uint len);
+  int secondary_index_read(int keyno, uchar *buf);
+  void setup_index_scan(leveldb::Slice *slice);
+  int get_row_by_rowid(uchar *buf, const char *pk_tuple, uint pk_tuple_size);
+
+  void update_auto_incr_val();
+  void load_auto_incr_value();
+  
+  /* Idea copied from InnoDB's convert_error_code_to_mysql */
+  int return_lock_failure(bool timed_out);
+
+public:
+  ha_leveldb(handlerton *hton, TABLE_SHARE *table_arg);
+  ~ha_leveldb() {}
+  
+  /** @brief
+    The name that will be used for display purposes.
+   */
+  const char *table_type() const { return "LEVELDB"; }
+
+  /* The following is only used by SHOW KEYS: */
+  const char *index_type(uint inx) { return "BTREE"; }
+
+  /** @brief
+    The file extensions.
+   */
+  const char **bas_ext() const;
+
+  /** @brief
+    This is a list of flags that indicate what functionality the storage engine
+    implements. The current table flags are documented in handler.h
+  */
+  ulonglong table_flags() const
+  {
+    /*
+      HA_BINLOG_STMT_CAPABLE
+        We are saying that this engine is just statement capable to have
+        an engine that can only handle statement-based logging. This is
+        used in testing.
+      HA_REC_NOT_IN_SEQ 
+        If we don't set it, filesort crashes, because it assumes rowids are 
+        1..8 byte numbers 
+    */
+    return HA_BINLOG_STMT_CAPABLE | 
+           HA_REC_NOT_IN_SEQ |
+           HA_REQUIRE_PRIMARY_KEY |
+           (pk_can_be_decoded? HA_PRIMARY_KEY_IN_READ_INDEX:0) |
+           HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
+           HA_NULL_IN_KEY;
+  }
+
+  /** @brief
+    This is a bitmap of flags that indicates how the storage engine
+    implements indexes. The current index flags are documented in
+    handler.h. If you do not implement indexes, just return zero here.
+
+      @details
+    part is the key part to check. First key part is 0.
+    If all_parts is set, MySQL wants to know the flags for the combined
+    index, up to and including 'part'.
+  */
+  ulong index_flags(uint inx, uint part, bool all_parts) const;
+
+  int rename_table(const char *from, const char *to);
+
+  void unpack_blobs_from_retrieved_record(uchar *buf);
+  void convert_record_from_storage_format(leveldb::Slice *slice, uchar *buf);
+  void convert_record_from_storage_format(uchar *buf);
+
+  void convert_record_to_storage_format(leveldb::Slice *packed_rec);
+
+  /** @brief
+    unireg.cc will call max_supported_record_length(), max_supported_keys(),
+    max_supported_key_parts(), uint max_supported_key_length()
+    to make sure that the storage engine can handle the data it is about to
+    send. Return *real* limits of your storage engine here; MySQL will do
+    min(your_limits, MySQL_limits) automatically.
+   */
+  uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+  uint max_supported_keys()          const { return MAX_INDEXES; }
+  uint max_supported_key_parts()     const { return MAX_REF_PARTS; }
+
+  /** @brief
+    unireg.cc will call this to make sure that the storage engine can handle
+    the data it is about to send. Return *real* limits of your storage engine
+    here; MySQL will do min(your_limits, MySQL_limits) automatically.
+
+      @details
+    There is no need to implement ..._key_... methods if your engine doesn't
+    support indexes.
+   */
+  uint max_supported_key_length()    const { return 16*1024; /* just to return something*/ }
+  
+  /* At the moment, we're ok with default handler::index_init() implementation. */
+  int index_read_map(uchar * buf, const uchar * key,
+                     key_part_map keypart_map,
+                     enum ha_rkey_function find_flag);
+  
+  int index_read_last_map(uchar * buf, const uchar * key, 
+                          key_part_map keypart_map);
+
+  virtual double scan_time() { return (double) (stats.records+stats.deleted) / 20.0+10; }
+  virtual double read_time(uint, uint, ha_rows rows)
+  { return (double) rows /  20.0+1; }
+
+  int open(const char *name, int mode, uint test_if_locked);
+  int close(void);
+
+  int write_row(uchar *buf);
+  int update_row(const uchar *old_data, uchar *new_data);
+  int delete_row(const uchar *buf);
+
+  int index_next(uchar *buf);
+  int index_next_with_direction(uchar *buf, bool move_forward);
+  int index_prev(uchar *buf);
+
+  int index_first(uchar *buf);
+  int index_last(uchar *buf);
+  int index_end();
+
+  void unlock_row();
+
+  /** @brief
+    Unlike index_init(), rnd_init() can be called two consecutive times
+    without rnd_end() in between (it only makes sense if scan=1). In this
+    case, the second call should prepare for the new table scan (e.g if
+    rnd_init() allocates the cursor, the second call should position the
+    cursor to the start of the table; no need to deallocate and allocate
+    it again. This is a required method.
+  */
+  int rnd_init(bool scan);
+  int rnd_end();
+
+  int rnd_next(uchar *buf);
+  int rnd_next_with_direction(uchar *buf, bool move_forward);
+
+  int rnd_pos(uchar *buf, uchar *pos);
+  void position(const uchar *record);
+  int info(uint);
+  int extra(enum ha_extra_function operation);
+  int start_stmt(THD *thd, thr_lock_type lock_type);
+  int external_lock(THD *thd, int lock_type);
+  int delete_all_rows(void);
+  int truncate();
+
+  void remove_rows(LDBSE_TABLE_DEF *tbl);
+  ha_rows records_in_range(uint inx, key_range *min_key,
+                           key_range *max_key);
+  int delete_table(const char *from);
+  int create(const char *name, TABLE *form,
+             HA_CREATE_INFO *create_info);
+  bool check_if_incompatible_data(HA_CREATE_INFO *info,
+                                  uint table_changes);
+
+  THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
+                             enum thr_lock_type lock_type);
+
+  my_bool register_query_cache_table(THD *thd, char *table_key,
+                                     uint key_length,
+                                     qc_engine_callback
+                                     *engine_callback,
+                                     ulonglong *engine_data)
+  {
+    /* Currently, we don't support query cache */
+    return FALSE;
+  }
+  bool get_error_message(int error, String *buf);
+
+  void get_auto_increment(ulonglong offset, ulonglong increment,
+                          ulonglong nb_desired_values,
+                          ulonglong *first_value,
+                          ulonglong *nb_reserved_values);
+  void update_create_info(HA_CREATE_INFO *create_info);
+};
diff --git a/storage/leveldb/ldb_applyiter.cc b/storage/leveldb/ldb_applyiter.cc
new file mode 100644
index 0000000..03dde92
--- /dev/null
+++ b/storage/leveldb/ldb_applyiter.cc
@@ -0,0 +1,207 @@
+/* 
+   Copyright (c) 2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "my_global.h"                   /* ulonglong */
+#include "my_base.h"                     /* ha_rows */
+#include "my_sys.h"
+#include "my_tree.h"
+
+#include "leveldb/db.h"
+#include "leveldb/comparator.h"
+#include "leveldb/write_batch.h"
+
+#include "ldb_rowmods.h"
+#include "ldb_applyiter.h"
+
+int compare_mem_comparable_keys(const uchar *a, size_t a_len, const uchar *b, size_t b_len);
+
+
+Apply_changes_iter::Apply_changes_iter() :
+  trx(NULL), ldb(NULL) 
+{}
+
+
+Apply_changes_iter::~Apply_changes_iter() 
+{ 
+  delete trx;
+  delete ldb;
+}
+
+
+void Apply_changes_iter::init(Row_table *trx_arg, leveldb::Iterator *ldb_arg)
+{
+  delete trx;
+  delete ldb;
+  trx= new Row_table_iter(trx_arg);
+  ldb= ldb_arg; 
+  valid= false;
+}
+
+
+void Apply_changes_iter::Next()
+{
+  DBUG_ASSERT(valid);
+  if (cur_is_trx)
+    trx->Next();
+  else
+    ldb->Next();
+
+  advance(1);
+}
+
+
+void Apply_changes_iter::Prev()
+{
+  DBUG_ASSERT(valid);
+  if (cur_is_trx)
+    trx->Prev();
+  else
+    ldb->Prev();
+
+  advance(-1);
+}
+
+
+void Apply_changes_iter::Seek(leveldb::Slice &key)
+{
+  ldb->Seek(key);
+  trx->Seek(key);
+  advance(1);
+}
+
+
+void Apply_changes_iter::SeekToLast()
+{
+  ldb->SeekToLast();
+  trx->SeekToLast();
+  advance(-1);
+}
+
+
+/*
+  @param direction  1 means forward, -1 means backward.
+*/
+
+void Apply_changes_iter::advance(int direction)
+{
+  valid= true;
+  while (1)
+  {
+    if (!trx->Valid() && !ldb->Valid())
+    {
+      // ok we got here if neither scan nor trx have any records.
+      cur_is_trx= false;  //just set it to something
+      valid= false;
+      return;
+    }
+
+    if (!trx->Valid())
+    {
+      /* Got record from leveldb but not from trx */
+      cur_is_trx= false;
+      break;
+    }
+
+    if (!ldb->Valid())
+    {
+      cur_is_trx= true;
+      if (trx->is_tombstone())
+      {
+        if (direction == 1)
+          trx->Next();
+        else
+          trx->Prev();
+        continue;  /* A tombstone.. (but no matching record? odd..) */
+      }
+      break;
+    }
+
+    if (ldb->Valid() && trx->Valid())
+    {
+      leveldb::Slice ldb_key= ldb->key();
+      leveldb::Slice trx_key= trx->key();
+      int cmp= direction * 
+               compare_mem_comparable_keys((const uchar*)trx_key.data(), trx_key.size(),
+                                           (const uchar*)ldb_key.data(), ldb_key.size());
+      if (!cmp) // keys are equal
+      {
+        if (trx->is_tombstone())
+        {
+          /* leveldb has a record, but trx says we have deleted it */
+          if (direction == 1)
+          {
+            ldb->Next();
+            trx->Next();
+          }
+          else
+          {
+            ldb->Prev();
+            trx->Prev();
+          }
+          continue;  // restart the logic
+        }
+
+        /* trx has a newer version of the record */
+        if (direction == 1) 
+          ldb->Next();
+        else
+          ldb->Prev();
+        cur_is_trx= true;
+        break;
+      }
+      else if (cmp > 0)
+      {
+        /* record from leveldb comes first */
+        cur_is_trx= false;
+        break;
+      }
+      else // cmp < 0
+      {
+        /* record from transaction comes first */
+        if (trx->is_tombstone())
+        {
+          if (direction == 1)
+            trx->Next();
+          else
+            trx->Prev();
+          continue;  /* A tombstone.. (but no matching record? odd..) */
+        }
+        /* A record from transaction but not in the db */
+        cur_is_trx= true;
+        break;
+      }
+    }
+  }
+}
+
+
+leveldb::Slice Apply_changes_iter::value()
+{
+  if (cur_is_trx)
+    return trx->value();
+  else
+    return ldb->value();
+}
+
+
+leveldb::Slice Apply_changes_iter::key()
+{
+  if (cur_is_trx)
+    return trx->key();
+  else
+    return ldb->key();
+}
+
diff --git a/storage/leveldb/ldb_applyiter.h b/storage/leveldb/ldb_applyiter.h
new file mode 100644
index 0000000..342d5d3
--- /dev/null
+++ b/storage/leveldb/ldb_applyiter.h
@@ -0,0 +1,53 @@
+/* 
+   Copyright (c) 2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+class Row_table;
+class Row_table_iter;
+
+/*
+  A class that looks like LevelDB's iterator, but internally it takes into 
+  account the changes made by the transaction.
+
+  In other words, the iterator gives a view of the data insidde leveldb, but
+  also applies the changes made by the transaction.
+*/
+
+class Apply_changes_iter
+{
+  bool valid;
+  bool cur_is_trx;
+  
+  /* These are the iterators we're merging. We own them, so should free them */
+  Row_table_iter *trx; 
+  leveldb::Iterator* ldb;
+public:
+  Apply_changes_iter();
+  ~Apply_changes_iter();
+  void init(Row_table *trx_arg, leveldb::Iterator *ldb_arg);
+
+  void Next();
+  void Prev();
+  
+  void Seek(leveldb::Slice &key);
+  void SeekToLast();
+
+  bool Valid() { return valid; }
+  leveldb::Slice key();
+  leveldb::Slice value();
+private:
+  void advance(int direction);
+};
+
diff --git a/storage/leveldb/ldb_datadic.cc b/storage/leveldb/ldb_datadic.cc
new file mode 100644
index 0000000..d80bf42
--- /dev/null
+++ b/storage/leveldb/ldb_datadic.cc
@@ -0,0 +1,795 @@
+/* 
+   Copyright (c) 2012,2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation        // gcc: Class implementation
+#endif
+
+#include <mysql/plugin.h>
+#include "ha_leveldb.h"
+#include "sql_class.h"
+#include "my_bit.h"
+
+#include "ldb_datadic.h"
+
+
+void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
+                 uint key_length);
+
+
+void write_int(String *out, uint32 val)
+{
+  uint buf= htonl(val);
+  out->append((char*)&buf, 4);
+}
+
+
+uint32 read_int(char **data)
+{
+  uint buf;
+  memcpy(&buf, *data, sizeof(uint32));
+  *data += sizeof(uint32);
+  return ntohl(buf);
+}
+
+
+LDBSE_KEYDEF::~LDBSE_KEYDEF()
+{
+  if (pk_key_parts)
+    my_free(pk_key_parts);
+  if (pack_info)
+    my_free(pack_info);
+}
+
+
+void LDBSE_KEYDEF::setup(TABLE *tbl)
+{
+  /* 
+    set max_length based on the table. If we're unlucky, setup() may be
+    called concurrently from multiple threads but that is ok because result of
+    compuation is assignment of maxlength to the same value.
+    ^^ TODO: is this still true? concurrent setup() calls are not safe
+    anymore...
+  */
+  if (!maxlength)
+  {
+    KEY *key_info= &tbl->key_info[keyno];
+    KEY *pk_info=  &tbl->key_info[tbl->s->primary_key];
+
+    if (keyno != tbl->s->primary_key)
+    {
+      n_pk_key_parts= pk_info->actual_key_parts;
+      pk_key_parts= (PK_KEY_PART*)my_malloc(sizeof(PK_KEY_PART) * n_pk_key_parts, MYF(0));
+    }
+    else
+    {
+      pk_info= NULL;
+      pk_key_parts= 0;
+    }
+
+    size_t size= sizeof(Field_pack_info) * key_info->actual_key_parts;
+    pack_info= (Field_pack_info*)my_malloc(size, MYF(0));
+ 
+    uint len= INDEX_NUMBER_SIZE;
+    int unpack_len= 0;
+    /* this loop also loops over the 'extended key' tail */
+    for (uint i= 0; i < key_info->actual_key_parts; i++)
+    {
+      Field *field= key_info->key_part[i].field;
+
+      if (field->real_maybe_null())
+        len +=1; // NULL-byte
+
+      pack_info[i].setup(key_info->key_part[i].field);
+      pack_info[i].image_offset= len;
+      pack_info[i].unpack_data_offset= unpack_len;
+
+      if (pk_info)
+      {
+        for (uint j= 0; j < n_pk_key_parts; j++)
+        {
+          if (field->field_index == pk_info->key_part[j].field->field_index)
+          {
+            pk_key_parts[j].offset= len;
+            pk_key_parts[j].size=   pack_info[i].image_len;
+          }
+        }
+      }
+
+      len        += pack_info[i].image_len;
+      unpack_len += pack_info[i].unpack_data_len;
+    }
+    maxlength= len;
+    unpack_data_len= unpack_len;
+  }
+}
+
+
+/*
+  Get a mem-comparable form of Primary Key from mem-comparable form of this key
+
+  @param
+    pk_descr        Primary Key descriptor
+    key             Index tuple from this key in mem-comparable form
+    pk_buffer  OUT  Put here mem-comparable form of the Primary Key.
+
+  @note
+    It may or may not be possible to restore primary key columns to their
+    mem-comparable form.  To handle all cases, this function copies mem-
+    comparable forms directly.
+
+    LevelDB SE supports "Extended keys". This means that PK columns are present
+    at the end of every key.  If the key already includes PK columns, then
+    these columns are not present at the end of the key.
+
+    Because of the above, we copy each primary key column.
+*/
+
+uint LDBSE_KEYDEF::get_primary_key_tuple(LDBSE_KEYDEF *pk_descr, 
+                                         const char *key, char *pk_buffer)
+{
+  uint size= 0;
+  char *buf= pk_buffer;
+  DBUG_ASSERT(n_pk_key_parts);
+  
+  // copy the PK number
+  store_index_number((uchar*)buf, pk_descr->index_number);
+  buf += INDEX_NUMBER_SIZE;
+  size += INDEX_NUMBER_SIZE;
+
+  for (uint j= 0; j < n_pk_key_parts; j++)
+  {
+    uint len= pk_key_parts[j].size;
+    memcpy(buf, key + pk_key_parts[j].offset, len);
+    buf += len;
+    size += len;
+  }
+  return size;
+}
+
+
+uint LDBSE_KEYDEF::pack_index_tuple(TABLE *tbl, uchar *packed_tuple, 
+                                    const uchar *key_tuple, 
+                                    key_part_map keypart_map)
+{
+  /* We were given a record in KeyTupleFormat. First, save it to record */
+  uint key_len= calculate_key_len(tbl, keyno, key_tuple, keypart_map);
+  key_restore(tbl->record[0], (uchar*)key_tuple, &tbl->key_info[keyno], 
+              key_len);
+
+  uint n_used_parts= my_count_bits(keypart_map);
+  if (keypart_map == HA_WHOLE_KEY)
+    n_used_parts= 0; // Full key is used
+
+  /* Then, convert the record into a mem-comparable form */
+  return pack_record(tbl, tbl->record[0], packed_tuple, NULL, NULL, 
+                     n_used_parts);
+}
+
+
+void LDBSE_KEYDEF::successor(uchar *packed_tuple, uint len)
+{
+  uchar *p= packed_tuple + len - 1;
+  for (; p > packed_tuple; p--)
+  {
+    if (*p != uchar(0xFF))
+    {
+      *p= *p + 1;
+      break;
+    }
+    *p='\0';
+  }
+}
+
+
+/*
+  Get index columns from the record and pack them into mem-comparable form.
+
+  @param
+    tbl                   Table we're working on
+    record           IN   Record buffer with fields in table->record format
+    packed_tuple     OUT  Key in the mem-comparable form
+    unpack_info      OUT  Unpack data
+    unpack_info_len  OUT  Unpack data length
+    n_key_parts           Number of keyparts to process. 0 means all of them.
+
+  @detail
+    Some callers do not need the unpack information, they can pass
+    unpack_info=NULL, unpack_info_len=NULL.
+*/
+
+uint LDBSE_KEYDEF::pack_record(TABLE *tbl, const uchar *record, 
+                               uchar *packed_tuple, 
+                               uchar *unpack_info, int *unpack_info_len,
+                               uint n_key_parts)
+{
+  uchar *tuple= packed_tuple;
+  uchar *unpack_end= unpack_info;
+  KEY *key_info= &tbl->key_info[keyno];
+  
+  store_index_number(tuple, index_number);
+  tuple += INDEX_NUMBER_SIZE;
+  
+  // The following includes the 'extended key' tail:
+  if (n_key_parts == 0 || n_key_parts == MAX_REF_PARTS)
+    n_key_parts= key_info->actual_key_parts;
+
+  for (uint i=0; i < n_key_parts; i++)
+  {
+    Field *field= key_info->key_part[i].field;
+    my_ptrdiff_t ptr_diff= record - tbl->record[0];
+    field->move_field_offset(ptr_diff);
+    
+    const int length= pack_info[i].image_len;
+    if (field->real_maybe_null())
+    {
+      if (field->is_real_null())
+      {
+        /* NULL value. store '\0' so that it sorts before non-NULL values */
+        *tuple++ = 0;
+        memset(tuple, 0, length);
+      }
+      else
+      {
+        // store '1'
+        *tuple++ = 1;
+        field->make_sort_key(tuple, length);
+      }
+    }
+    else
+      field->make_sort_key(tuple, length);
+
+    tuple += length;
+
+    if (unpack_end && pack_info && pack_info[i].make_unpack_info_func)
+    {
+      pack_info[i].make_unpack_info_func(&pack_info[i], field, unpack_end);
+      unpack_end += pack_info[i].unpack_data_len;
+    }
+
+    field->move_field_offset(-ptr_diff);
+  }
+ 
+  if (unpack_info_len)
+    *unpack_info_len= unpack_end - unpack_info;
+
+  return tuple - packed_tuple;
+}
+
+
+/*
+  Take mem-comparable form and unpack_info and unpack it to Table->record
+
+  @detail
+    not all indexes support this
+*/
+
+int LDBSE_KEYDEF::unpack_record(TABLE *table, uchar *buf, 
+                                 const leveldb::Slice *packed_key, 
+                                 const leveldb::Slice *unpack_info)
+{
+  int res= 0;
+  KEY * const key_info= &table->key_info[keyno];
+
+  const uchar * const key_ptr= (const uchar*)packed_key->data();
+  const uchar * const unpack_ptr= (const uchar*)unpack_info->data();
+
+  if (packed_key->size() != max_storage_fmt_length())
+    return 1;
+  
+  if (unpack_info->size() != unpack_data_len)
+    return 1;
+
+  for (uint i= 0; i < key_info->actual_key_parts ; i++)
+  {
+    Field *field= key_info->key_part[i].field;
+    Field_pack_info *fpi= &pack_info[i];
+    
+    if (fpi->unpack_func)
+    {
+      my_ptrdiff_t ptr_diff= buf - table->record[0];
+      field->move_field_offset(ptr_diff);
+
+      if (fpi->maybe_null)
+      {
+        if (*(key_ptr + (fpi->image_offset - 1)) == 0)
+          field->set_null();
+        else
+          field->set_notnull();
+      }
+
+      res= fpi->unpack_func(fpi, field, key_ptr + fpi->image_offset,
+                            unpack_ptr + fpi->unpack_data_offset);
+      field->move_field_offset(-ptr_diff);
+
+      if (res) 
+        break; /* Error */
+    }
+  }
+  return res;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// Field_pack_info
+///////////////////////////////////////////////////////////////////////////////////////////
+
+int unpack_integer(Field_pack_info *fpi, Field *field, 
+                   const uchar *from, const uchar *unpack_info)
+{
+  const int length= field->pack_length();
+  uchar *to= field->ptr;
+
+#ifdef WORDS_BIGENDIAN
+  {
+    if (((Field_num*)field)->unsigned_flag)
+      to[0]= from[0];
+    else
+      to[0]= (char)(from[0] ^ 128); // Reverse the sign bit.
+    memcpy(to + 1, from + 1, length - 1);
+  }
+#else  
+  {
+    const int sign_byte= from[0];
+    if (((Field_num*)field)->unsigned_flag)
+      to[length - 1]= sign_byte;
+    else
+      to[length - 1]= static_cast<char>(sign_byte ^ 128); // Reverse the sign bit.
+    for (int i= 0, j= length - 1; i < length-1; ++i, --j)
+      to[i]= from[j];
+  }
+#endif
+  return 0;
+}
+
+
+/* Unpack the string by copying it over */
+int unpack_binary_str(Field_pack_info *fpi, Field *field, 
+                      const uchar *tuple,
+                      const uchar *unpack_info)
+{
+  memcpy(field->ptr + fpi->field_data_offset, tuple, fpi->image_len);
+  return 0;
+}
+
+
+/*
+  For UTF-8, we need to convert 2-byte wide-character entities back into
+  UTF8 sequences.
+*/
+
+int unpack_utf8_str(Field_pack_info *fpi, Field *field,
+                    const uchar *tuple,
+                    const uchar *unpack_info)
+{
+  CHARSET_INFO *cset= (CHARSET_INFO*)field->charset();
+  const uchar *src= tuple;
+  const uchar *src_end= tuple + fpi->image_len;
+  uchar *dst= field->ptr + fpi->field_data_offset;
+  uchar *dst_end= dst + fpi->image_len;
+
+  while (src < src_end)
+  {
+    my_wc_t wc= (src[0] <<8) | src[1]; 
+    src += 2;
+    int res= cset->cset->wc_mb(cset, wc, dst, dst_end);
+    DBUG_ASSERT(res > 0 && res <=3);
+    if (res < 0)
+      return 1;
+    dst += res;
+  }
+  return 0;
+}
+
+
+int unpack_binary_varchar(Field_pack_info *fpi, Field *field, 
+                          const uchar *tuple,
+                          const uchar *unpack_info)
+{
+  uint32 length_bytes= ((Field_varstring*)field)->length_bytes;
+  //copy the length bytes
+  memcpy(field->ptr, unpack_info, length_bytes);
+
+  return unpack_binary_str(fpi, field, tuple, unpack_info);
+}
+
+
+int unpack_utf8_varchar(Field_pack_info *fpi, Field *field, 
+                        const uchar *tuple,
+                        const uchar *unpack_info)
+{
+  uint32 length_bytes= ((Field_varstring*)field)->length_bytes;
+  //copy the length bytes
+  memcpy(field->ptr, unpack_info, length_bytes);
+
+  return unpack_utf8_str(fpi, field, tuple, unpack_info);
+}
+
+
+/*
+  For varchar, save the length.
+*/
+void make_varchar_unpack_info(Field_pack_info *fsi, Field *field, uchar *unpack_data)
+{
+  // TODO: use length from fsi.
+  Field_varstring *fv= (Field_varstring*)field;
+  memcpy(unpack_data, fv->ptr, fv->length_bytes);
+}
+
+
+/*
+  Setup index-only read of a field
+
+  @param
+    field  IN  field to be packed/un-packed
+
+  @return 
+    TRUE  -  Field can be read with index-only reads
+    FALSE -  Otherwise
+*/
+
+bool Field_pack_info::setup(Field *field)
+{
+  int res= false;
+  enum_field_types type= field->real_type();
+
+  maybe_null= field->real_maybe_null();
+  make_unpack_info_func= NULL;
+  unpack_func= NULL;
+  unpack_data_len= 0;
+  field_data_offset= 0;
+
+  /* Calculate image length. By default, is is pack_length() */
+  image_len= field->pack_length();
+  if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING)
+  {
+    /* 
+      For CHAR-based columns, check how strxfrm image will take.
+      field->field_length = field->char_length() * cs->mbmaxlen.
+    */
+    const CHARSET_INFO *cs= field->charset();
+    image_len= cs->coll->strnxfrmlen(cs, field->field_length);
+  }
+
+  if (type == MYSQL_TYPE_LONGLONG ||
+      type == MYSQL_TYPE_LONG ||
+      type == MYSQL_TYPE_INT24 ||
+      type == MYSQL_TYPE_SHORT ||
+      type == MYSQL_TYPE_TINY)
+  {
+    unpack_func= unpack_integer;
+    make_unpack_info_func= NULL;
+    return true;
+  }
+ 
+  const bool is_varchar= (type == MYSQL_TYPE_VARCHAR);
+  if (is_varchar)
+  {
+    make_unpack_info_func= make_varchar_unpack_info;
+    unpack_data_len= ((Field_varstring*)field)->length_bytes;
+    field_data_offset= ((Field_varstring*)field)->length_bytes;
+  }
+
+  if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_STRING)
+  {
+    const CHARSET_INFO *cs= field->charset();
+
+    if (cs == &my_charset_bin ||
+        cs == &my_charset_latin1_bin)
+    {
+      unpack_func= is_varchar? unpack_binary_varchar : unpack_binary_str;
+      res= true; 
+    }
+    else if(cs == &my_charset_utf8_bin)
+    {
+      unpack_func= is_varchar? unpack_utf8_varchar : unpack_utf8_str;
+      res= true;
+    }
+  }
+  return res;
+}
+
+
+#if 0
+void _ldbse_store_blob_length(uchar *pos,uint pack_length,uint length)
+{
+  switch (pack_length) {
+  case 1:
+    *pos= (uchar) length;
+    break;
+  case 2:
+    int2store(pos,length);
+    break;
+  case 3:
+    int3store(pos,length);
+    break;
+  case 4:
+    int4store(pos,length);
+  default:
+    break;
+  }
+  return;
+}
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// Table_ddl_manager
+///////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+  Write table definition DDL entry.
+
+  We write
+    dbname.tablename -> {index_nr, index_nr, index_nr, ... }
+*/
+
+void LDBSE_TABLE_DEF::write_to(leveldb::DB *ldb_dict, uchar *key, size_t keylen)
+{
+  StringBuffer<32> indexes;
+
+  for (uint i=0; i < n_keys; i++)
+  {
+    write_int(&indexes, key_descr[i]->index_number);
+  }
+  leveldb::Slice skey((char*)key, keylen); 
+  leveldb::Slice svalue(indexes.c_ptr(), indexes.length());
+
+  leveldb::WriteOptions options;
+  options.sync= true;
+  ldb_dict->Put(options, skey, svalue); 
+}
+
+
+uchar* Table_ddl_manager::get_hash_key(LDBSE_TABLE_DEF *rec, size_t *length,
+                                       my_bool not_used __attribute__((unused)))
+{
+  *length= rec->dbname_tablename.length();
+  return (uchar*) rec->dbname_tablename.c_ptr();
+}
+
+
+void Table_ddl_manager::free_hash_elem(void* data)
+{
+  LDBSE_TABLE_DEF* elem= (LDBSE_TABLE_DEF*)data;
+  delete elem;
+}
+
+
+bool Table_ddl_manager::init(leveldb::DB *ldb_dict)
+{
+  mysql_rwlock_init(0, &rwlock);
+  (void) my_hash_init(&ddl_hash, /*system_charset_info*/&my_charset_bin, 32,0,0,
+                      (my_hash_get_key) Table_ddl_manager::get_hash_key,
+                      Table_ddl_manager::free_hash_elem, 0);
+  
+  /* Read the data dictionary and populate the hash */
+  uchar ddl_entry[LDBSE_KEYDEF::INDEX_NUMBER_SIZE];
+  store_index_number(ddl_entry, DDL_ENTRY_INDEX_NUMBER);
+  leveldb::Slice ddl_entry_slice((char*)ddl_entry, LDBSE_KEYDEF::INDEX_NUMBER_SIZE);
+  
+  leveldb::Iterator* it;
+  it= ldb_dict->NewIterator(leveldb::ReadOptions());
+  int i= 0;
+  int max_number= DDL_ENTRY_INDEX_NUMBER + 1;
+  for (it->Seek(ddl_entry_slice); it->Valid(); it->Next()) 
+  {
+    char *ptr;
+    char *ptr_end;
+    LDBSE_TABLE_DEF *tdef= new LDBSE_TABLE_DEF;
+    leveldb::Slice key= it->key();
+    leveldb::Slice val= it->value();
+
+    if (key.size() <= LDBSE_KEYDEF::INDEX_NUMBER_SIZE)
+    {
+      sql_print_error("LevelDB: Table_store: key has length %d (corruption?)",
+                      (int)key.size());
+      return true;
+    }
+
+    if (memcmp(key.data(), ddl_entry, LDBSE_KEYDEF::INDEX_NUMBER_SIZE))
+      break;
+
+    tdef->dbname_tablename.append(key.data() + LDBSE_KEYDEF::INDEX_NUMBER_SIZE, 
+                                  key.size() - LDBSE_KEYDEF::INDEX_NUMBER_SIZE);
+    
+    // Now, read the DDLs.
+
+    if (val.size() < LDBSE_KEYDEF::INDEX_NUMBER_SIZE)
+    {
+      sql_print_error("LevelDB: Table_store: no keys defined in %*s",
+                      (int)key.size(), key.data());
+      return true;
+    }
+    if (val.size() % LDBSE_KEYDEF::INDEX_NUMBER_SIZE)
+    {
+      sql_print_error("LevelDB: Table_store: invalid keylist for table %s", 
+                      tdef->dbname_tablename.c_ptr_safe());
+      return true;
+    }
+    tdef->n_keys= val.size() / LDBSE_KEYDEF::INDEX_NUMBER_SIZE;
+    if (!(tdef->key_descr= (LDBSE_KEYDEF**)my_malloc(sizeof(LDBSE_KEYDEF*) * 
+                                                     tdef->n_keys, 
+                                                     MYF(MY_ZEROFILL))))
+      return true;
+
+    ptr= (char*)val.data();
+    ptr_end= ptr + val.size();
+    for (uint keyno=0; ptr < ptr_end; keyno++)
+    {
+      int index_number= read_int(&ptr);
+
+      /* 
+        We can't fully initialize LDBSE_KEYDEF object here, because full
+        initialization requires that there is an open TABLE* where we could
+        look at Field* objects and set max_length and other attributes.
+      */
+      tdef->key_descr[keyno]= new LDBSE_KEYDEF(index_number, keyno); 
+      
+      /* Keep track of what was the last index number we saw */
+      if (max_number < index_number)
+        max_number= index_number;
+    }
+    put(tdef);
+    i++;
+  }
+
+  sequence.init(max_number+1);
+
+  if (!it->status().ok())
+  {
+    std::string s= it->status().ToString();
+    sql_print_error("LevelDB: Table_store: load error: %s", s.c_str());
+    return true;
+  }
+  delete it;
+  sql_print_information("LevelDB: Table_store: loaded DDL data for %d tables", i);
+  return false;
+}
+
+
+LDBSE_TABLE_DEF* Table_ddl_manager::find(uchar *table_name, 
+                                         uint table_name_len, 
+                                         bool lock)
+{
+  LDBSE_TABLE_DEF *rec;
+  if (lock)
+    mysql_rwlock_rdlock(&rwlock);
+  rec= (LDBSE_TABLE_DEF*)my_hash_search(&ddl_hash, (uchar*)table_name,
+                                        table_name_len);
+  if (lock)
+    mysql_rwlock_unlock(&rwlock);
+  return rec;
+}
+
+
+int Table_ddl_manager::put_and_write(LDBSE_TABLE_DEF *tbl, leveldb::DB *ldb_dict)
+{
+  uchar buf[NAME_LEN * 2 + LDBSE_KEYDEF::INDEX_NUMBER_SIZE];
+  uint pos= 0;
+
+  store_index_number(buf, DDL_ENTRY_INDEX_NUMBER);
+  pos+= LDBSE_KEYDEF::INDEX_NUMBER_SIZE; 
+  
+  memcpy(buf + pos, tbl->dbname_tablename.ptr(), tbl->dbname_tablename.length());
+  pos += tbl->dbname_tablename.length();
+
+  int res;
+  if ((res= put(tbl)))
+    return res;
+
+  tbl->write_to(ldb_dict, buf, pos);
+  return 0;
+}
+
+
+/* Return 0 - ok, other value - error */
+
+int Table_ddl_manager::put(LDBSE_TABLE_DEF *tbl, bool lock)
+{
+  LDBSE_TABLE_DEF *rec;
+  my_bool result;
+
+  if (lock)
+    mysql_rwlock_wrlock(&rwlock);
+  rec= (LDBSE_TABLE_DEF*)find((uchar*)tbl->dbname_tablename.c_ptr(),
+                               tbl->dbname_tablename.length(), false);
+  if (rec)
+  {
+    // this will free the old record.
+    my_hash_delete(&ddl_hash, (uchar*) rec);
+  }
+  result= my_hash_insert(&ddl_hash, (uchar*)tbl);
+
+  if (lock)
+    mysql_rwlock_unlock(&rwlock);
+  return result;
+}
+
+
+void Table_ddl_manager::remove(LDBSE_TABLE_DEF *tbl, leveldb::DB *ldb_dict, bool lock)
+{
+  if (lock)
+    mysql_rwlock_wrlock(&rwlock);
+
+  uchar buf[NAME_LEN * 2 + LDBSE_KEYDEF::INDEX_NUMBER_SIZE];
+  uint pos= 0;
+
+  store_index_number(buf, DDL_ENTRY_INDEX_NUMBER);
+  pos+= LDBSE_KEYDEF::INDEX_NUMBER_SIZE; 
+  
+  memcpy(buf + pos, tbl->dbname_tablename.ptr(), tbl->dbname_tablename.length());
+  pos += tbl->dbname_tablename.length();
+
+  leveldb::Slice tkey((char*)buf, pos);
+  ldb_dict->Delete(leveldb::WriteOptions(), tkey); 
+
+  /* The following will also delete the object: */
+  my_hash_delete(&ddl_hash, (uchar*) tbl);
+
+  if (lock)
+    mysql_rwlock_unlock(&rwlock);
+}
+
+
+bool Table_ddl_manager::rename(uchar *from, uint from_len, 
+                               uchar *to, uint to_len, 
+                               leveldb::DB *ldb_dict)
+{
+  LDBSE_TABLE_DEF *rec;
+  LDBSE_TABLE_DEF *new_rec;
+  bool res= true;
+  uchar new_buf[NAME_LEN * 2 + LDBSE_KEYDEF::INDEX_NUMBER_SIZE];
+  uint new_pos= 0;
+
+  mysql_rwlock_wrlock(&rwlock);
+  if (!(rec= (LDBSE_TABLE_DEF*)find(from, from_len, false)))
+    goto err;
+
+  if (!(new_rec= new LDBSE_TABLE_DEF))
+    goto err;
+
+  new_rec->dbname_tablename.append((char*)to, to_len);
+  new_rec->n_keys= rec->n_keys;
+  new_rec->auto_incr_val= rec->auto_incr_val;
+  new_rec->key_descr= rec->key_descr;
+  rec->key_descr= NULL; /* so that it's not free'd when deleting the old rec */
+  
+  // Create a new key 
+  store_index_number(new_buf, DDL_ENTRY_INDEX_NUMBER);
+  new_pos+= LDBSE_KEYDEF::INDEX_NUMBER_SIZE; 
+  
+  memcpy(new_buf + new_pos, new_rec->dbname_tablename.ptr(), 
+         new_rec->dbname_tablename.length());
+  new_pos += new_rec->dbname_tablename.length();
+  
+  // Create a key to add 
+  new_rec->write_to(ldb_dict, new_buf, new_pos);
+  remove(rec, ldb_dict, false);
+  put(new_rec, false);
+  res= false; // ok
+err:
+  mysql_rwlock_unlock(&rwlock);
+  return res;
+}
+
+
+void Table_ddl_manager::cleanup()
+{
+  my_hash_free(&ddl_hash);
+  mysql_rwlock_destroy(&rwlock);
+  sequence.cleanup();
+}
+
diff --git a/storage/leveldb/ldb_datadic.h b/storage/leveldb/ldb_datadic.h
new file mode 100644
index 0000000..708ff6c
--- /dev/null
+++ b/storage/leveldb/ldb_datadic.h
@@ -0,0 +1,359 @@
+/* 
+   Copyright (c) 2012,2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+class LDBSE_KEYDEF;
+class Field_pack_info;
+
+inline void store_index_number(uchar *dst, uint32 number)
+{
+#ifdef WORDS_BIGENDIAN
+    memcpy(dst, &number, LDBSE_KEYDEF::INDEX_NUMBER_SIZE);
+#else
+    const uchar *src= (uchar*)&number;
+    dst[0]= src[3];
+    dst[1]= src[2];
+    dst[2]= src[1];
+    dst[3]= src[0];
+#endif
+}
+
+/*
+  An object of this class represents information about an index in an SQL 
+  table. It provides services to encode and decode index tuples.
+
+  There are several data encodings. 
+  
+  === SQL LAYER ===
+  SQL layer uses two encodings:
+
+  - "Table->record format". This is the format that is used for the data in
+     the record buffers, table->record[i]
+
+  - KeyTupleFormat (see opt_range.cc) - this is used in parameters to index
+    lookup functions, like handler::index_read_map().
+
+  === Inside LevelDB === 
+  Primary Key is stored as a mapping:
+
+    index_tuple -> StoredRecord
+  
+  StoredRecord is in Table->record format, except for blobs, which are stored
+  in-place. See ha_leveldb::convert_record_to_storage_format for details.
+
+  Secondary indexes are stored as one of two variants:
+   
+    index_tuple -> unpack_info
+    index_tuple -> empty_string
+  
+  index_tuple here is the form of key that can be compared with memcmp(), aka
+  "mem-comparable form".
+
+  unpack_info is extra data that allows to restore the original value from its
+  mem-comparable form. It is present only if the index supports index-only 
+  reads.
+*/
+
+class LDBSE_KEYDEF
+{
+public:
+  /* Convert a key from KeyTupleFormat to mem-comparable form */
+  uint pack_index_tuple(TABLE *tbl, uchar *packed_tuple, 
+                        const uchar *key_tuple, key_part_map keypart_map);
+  
+  /* Convert a key from Table->record format to mem-comparable form */
+  uint pack_record(TABLE *tbl, const uchar *record, uchar *packed_tuple, 
+                   uchar *unpack_info, int *unpack_info_len,
+                   uint n_key_parts=0);
+  int unpack_record(TABLE *table, uchar *buf, const leveldb::Slice *packed_key,
+                    const leveldb::Slice *unpack_info);
+
+  /* Get the key that is the "infimum" for this index */
+  inline void get_infimum_key(uchar *key, uint *size)
+  {
+    store_index_number(key, index_number);
+    *size= INDEX_NUMBER_SIZE;
+  }
+  
+  /* Get the key that is a "supremum" for this index */
+  inline void get_supremum_key(uchar *key, uint *size)
+  {
+    store_index_number(key, index_number+1);
+    *size= INDEX_NUMBER_SIZE;
+  }
+  
+  /* Make a key that is right after the given key. */
+  void successor(uchar *packed_tuple, uint len);
+
+  /*
+    This can be used to compare prefixes.
+    if  X is a prefix of Y, then we consider that X = Y.
+  */
+  int cmp_full_keys(const char *pa, uint a_len, const char *pb, uint b_len,
+                    uint n_parts)
+  {
+    DBUG_ASSERT(covers_key(pa, a_len));
+    DBUG_ASSERT(covers_key(pb, b_len));
+
+    uint min_len= a_len < b_len? a_len : b_len;
+    int res= memcmp(pa, pb, min_len);
+    return res;
+  }
+  
+  /* Check if given mem-comparable key belongs to this index */
+  bool covers_key(const char *key, uint keylen)
+  {
+    if (keylen < INDEX_NUMBER_SIZE)
+      return false;
+    if (memcmp(key, index_number_storage_form, INDEX_NUMBER_SIZE))
+      return false;
+    else
+      return true;
+  }
+  
+  /* Must only be called for secondary keys: */
+  uint get_primary_key_tuple(LDBSE_KEYDEF *pk_descr, const char *key, 
+                             char *pk_buffer);
+   
+  /* Return max length of mem-comparable form */
+  uint max_storage_fmt_length() 
+  {
+    return maxlength;
+  }
+
+  LDBSE_KEYDEF(uint indexnr_arg, uint keyno_arg) : 
+    index_number(indexnr_arg), 
+    pk_key_parts(NULL),
+    pack_info(NULL),
+    keyno(keyno_arg), 
+    maxlength(0) // means 'not intialized'
+  {
+    store_index_number(index_number_storage_form, indexnr_arg);
+  }
+  ~LDBSE_KEYDEF();
+  
+  enum {
+    INDEX_NUMBER_SIZE= 4
+  };
+
+  void setup(TABLE *table);
+  
+private:
+  
+  /* Global number of this index (used as prefix in StorageFormat) */
+  const uint32 index_number;
+
+  uchar index_number_storage_form[INDEX_NUMBER_SIZE]; 
+  
+  friend class LDBSE_TABLE_DEF; // for index_number above
+
+  class PK_KEY_PART
+  {
+  public:
+    uint offset;
+    uint size;
+  };
+
+  /*
+    Array of descriptions of primary key columns. 
+     - element #0 describes the first PK column, 
+     - element #1 describes the second PK column, and so forth.
+    the offsets are offsets of column representation in StorageFormat
+    representation of this index.
+  */
+  PK_KEY_PART *pk_key_parts;
+  uint n_pk_key_parts;
+  
+  /* Array of index-part descriptors. */
+  Field_pack_info *pack_info;
+  
+  uint keyno; /* number of this index in the table */
+  
+  /*
+    Length of the mem-comparable form. In the encoding we're using, it is
+    constant (any value will have this length).
+  */
+  uint maxlength;
+  
+  /* Length of the unpack_data */
+  uint unpack_data_len;
+};
+
+
+typedef void (*make_unpack_info_t) (Field_pack_info *fpi, Field *field, uchar *dst);
+typedef int (*index_field_unpack_t)(Field_pack_info *fpi, Field *field,
+                                    const uchar *tuple,
+                                    const uchar *unpack_info);
+
+/*
+  This stores information about how a field can be packed to mem-comparable
+  form and unpacked back.
+*/
+
+class Field_pack_info
+{
+public:
+  /* 
+    Offset of the image of this field in the mem-comparable image. This field
+    must be set from outside of the class
+  */
+  int image_offset;
+
+  /* Length of mem-comparable image of the field, in bytes */
+  int image_len;
+  
+  /* Length of image in the unpack data */
+  int unpack_data_len;
+  int unpack_data_offset;
+
+  /* Offset of field data in table->record[i] from field->ptr. */
+  int field_data_offset;
+  
+  bool maybe_null; /* TRUE <=> NULL-byte is stored */
+
+  /*
+    Pack function is assumed to be:
+     - store NULL-byte, if needed
+     - call field->make_sort_key();
+    If you neeed to unpack, you should also call
+  */
+  make_unpack_info_t make_unpack_info_func;
+
+  /*
+    This function takes
+    - mem-comparable form 
+    - unpack_info data 
+    and restores the original value.
+  */
+  index_field_unpack_t unpack_func;
+
+  bool setup(Field *field);
+};
+
+
+/* 
+  A table definition. This is an entry in the mapping
+    
+    dbname.tablename -> {index_nr, index_nr, ... }
+
+  There is only one LDBSE_TABLE_DEF object for a given table.
+  That's why we keep auto_increment value here, too.
+*/
+
+class LDBSE_TABLE_DEF
+{
+public:
+  LDBSE_TABLE_DEF() : key_descr(NULL), auto_incr_val(1)
+  {
+    mysql_mutex_init(0, &mutex, MY_MUTEX_INIT_FAST);
+  }
+  ~LDBSE_TABLE_DEF()
+  {
+    mysql_mutex_destroy(&mutex);
+    /* Don't free key definitions */
+    if (key_descr)
+    {
+      for (uint i= 0; i < n_keys; i++)
+        delete key_descr[i];
+      my_free(key_descr);
+    }
+  }
+  /* Stores 'dbname.tablename' */
+  StringBuffer<64> dbname_tablename;
+  
+  /* Number of indexes */
+  uint n_keys;
+  
+  /* Array of index descriptors */
+  LDBSE_KEYDEF **key_descr;
+  
+  mysql_mutex_t mutex; // guards the following:
+  longlong auto_incr_val;
+
+  void write_to(leveldb::DB *ldb_dict, uchar *key, size_t keylen);
+};
+
+
+/* 
+  A thread-safe sequential number generator. Its performance is not a concern
+*/
+
+class Sequence_generator
+{
+  int next_number;
+
+  mysql_mutex_t mutex;
+public:
+  void init(int initial_number)
+  {
+    mysql_mutex_init(0 , &mutex, MY_MUTEX_INIT_FAST);
+    next_number= initial_number;
+  }
+
+  int get_next_number() 
+  {
+    int res;
+    mysql_mutex_lock(&mutex);
+    res= next_number++;
+    mysql_mutex_unlock(&mutex);
+    return res;
+  }
+
+  void cleanup()
+  {
+    mysql_mutex_destroy(&mutex);
+  }
+};
+
+
+/*
+  This contains a mapping of 
+
+     dbname.table_name -> array{LDBSE_KEYDEF}.
+
+  objects are shared among all threads.
+*/
+
+class Table_ddl_manager
+{
+  HASH ddl_hash; // Contains LDBSE_TABLE_DEF elements
+  mysql_rwlock_t rwlock;
+
+  Sequence_generator sequence;
+
+  enum {
+    DDL_ENTRY_INDEX_NUMBER=1
+  };
+
+public:
+  bool init(leveldb::DB *ldb_dict);
+  void cleanup();
+
+  int put_and_write(LDBSE_TABLE_DEF *key_descr, leveldb::DB *ldb_dict);
+  int put(LDBSE_TABLE_DEF *key_descr, bool lock= true);
+  void remove(LDBSE_TABLE_DEF *rec, leveldb::DB *ldb_dict, bool lock=true);
+
+  LDBSE_TABLE_DEF *find(uchar *table_name, uint len, bool lock=true);
+  
+  bool rename(uchar *from, uint from_len, uchar *to, uint to_len, 
+              leveldb::DB *ldb_dict);
+
+  int get_next_number() { return sequence.get_next_number(); }
+private:
+  static uchar* get_hash_key(LDBSE_TABLE_DEF *rec, size_t *length,
+                             my_bool not_used __attribute__((unused)));
+  static void free_hash_elem(void* data);
+};
+
diff --git a/storage/leveldb/ldb_locks.cc b/storage/leveldb/ldb_locks.cc
new file mode 100644
index 0000000..5362a01
--- /dev/null
+++ b/storage/leveldb/ldb_locks.cc
@@ -0,0 +1,311 @@
+/* 
+   Copyright (c) 2012,2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation        // gcc: Class implementation
+#endif
+
+#include <mysql/plugin.h>
+
+#include "ha_leveldb.h"  // TODO: this is too much
+
+#include "ldb_locks.h"
+
+static uchar* get_row_lock_hash_key(const uchar *entry, size_t* key_len, my_bool)
+{
+  Row_lock *rlock= (Row_lock*)entry;
+  *key_len= rlock->len;
+  return (uchar*) rlock->rowkey;
+}
+
+/**
+  Row_lock constructor
+
+  It is called from lf_hash and takes a pointer to an LF_SLIST instance.
+  Row_lock is located at arg+sizeof(LF_SLIST)
+*/
+static void rowlock_init(uchar *arg)
+{
+  Row_lock *rc= (Row_lock*)(arg+LF_HASH_OVERHEAD);
+  DBUG_ENTER("rowlock_init");
+
+  memset(rc, 0, sizeof(*rc));
+ 
+  mysql_mutex_init(0 /* TODO: register in P_S. */, &rc->mutex, MY_MUTEX_INIT_FAST);
+  mysql_cond_init(0, &rc->cond, 0);
+  
+  rc->waiters= 0;
+  DBUG_VOID_RETURN;
+}
+
+
+/**
+  Row_lock destructor
+
+  It is called from lf_hash and takes a pointer to an LF_SLIST instance.
+  Row_lock is located at arg+sizeof(LF_SLIST)
+*/
+static void rowlock_destroy(uchar *arg)
+{
+  Row_lock *rc= (Row_lock*)(arg+LF_HASH_OVERHEAD);
+  DBUG_ENTER("rowlock_destroy");
+
+  mysql_mutex_destroy(&rc->mutex);
+  mysql_cond_destroy(&rc->cond);
+
+  DBUG_ASSERT(rc->waiters == 0);
+  DBUG_VOID_RETURN;
+}
+
+
+/*
+  Global initialization. Should be called before any other operation.
+*/
+
+void LockTable::init(lf_key_comparison_func_t key_cmp_func, 
+                     lf_hashfunc_t hashfunc)
+{
+  lf_hash_init(&lf_hash, sizeof(Row_lock), LF_HASH_UNIQUE, 0 /* key offset */,
+               0 /*key_len*/, get_row_lock_hash_key /*get_hash_key*/,
+               NULL /*charset*/);
+
+  lf_hash.alloc.constructor= rowlock_init;
+  lf_hash.alloc.destructor=  rowlock_destroy;
+
+  lf_hash.key_comparator= key_cmp_func;
+  lf_hash.hashfunc=       hashfunc;
+
+  lf_hash.element_size= offsetof(Row_lock, mutex);
+}
+
+
+/* This should be called when shutting down */
+
+void LockTable::cleanup()
+{
+  /* We should not have any locks at this point */ 
+  DBUG_ASSERT(lf_hash.count == 0);
+  lf_hash_destroy(&lf_hash);
+}
+
+
+/*
+  Get a lock for given row
+
+  @param pins          Pins for this thread as returned by LockTable::get_pins().
+  @param key           Row key
+  @param keylen        Length of the row key, in bytes.
+  @param timeout_sec   Wait at most this many seconds.
+
+  @return
+    pointer  Pointer to the obtained lock
+    NULL     Failed to acquire the lock (timeout or out-of-memory error).
+
+
+  @note 
+    The code is based on wt_thd_will_wait_for() in mysys/waiting_threads.c
+*/
+
+Row_lock* LockTable::get_lock(LF_PINS *pins, const uchar* key, size_t keylen,
+                              int timeout_sec)
+{
+  Row_lock *found_lock;
+  void *ptr;
+  bool inserted= false;
+
+  uchar *key_copy= NULL;
+
+retry:
+  while (!(ptr= lf_hash_search(&lf_hash, pins, key, keylen)))
+  {
+    Row_lock new_lock;
+    new_lock.deleted= FALSE;
+    new_lock.waiters= 0;
+    new_lock.busy= 0;
+
+    if (!key_copy && !(key_copy= (uchar*)my_malloc(keylen, MYF(0))))
+      return NULL;
+    memcpy(key_copy, key, keylen);
+    new_lock.rowkey= (char*)key_copy;
+    new_lock.len= keylen;
+    
+    int res= lf_hash_insert(&lf_hash, pins, &new_lock);
+    
+    if (res == -1)
+       goto return_null; /* out of memory */
+    
+    inserted= !res;
+    if (inserted)
+    {
+      /* 
+        key_copy is now used in the entry in hash table.
+        We should not free it.
+      */
+      key_copy= NULL;
+    }
+
+    /*
+      Two cases: either lf_hash_insert() failed - because another thread
+      has just inserted a resource with the same id - and we need to retry.
+
+      Or lf_hash_insert() succeeded, and then we need to repeat
+      lf_hash_search() to find a real address of the newly inserted element.
+
+      That is, we don't care what lf_hash_insert() has returned.
+      And we need to repeat the loop anyway.
+    */
+  }
+    
+  if (ptr == MY_ERRPTR)
+    goto return_null; /* Out of memory */
+
+  found_lock= (Row_lock*)ptr;
+  mysql_mutex_lock(&found_lock->mutex);
+
+  if (found_lock->deleted)
+  {
+    /* We have found the lock, but it was deleted after that */
+    mysql_mutex_unlock(&found_lock->mutex);
+    lf_hash_search_unpin(pins);
+    goto retry;
+  }
+
+  /* We're holding Row_lock's mutex, which prevents anybody from deleting it */
+  lf_hash_search_unpin(pins);
+
+  if (!found_lock->busy)
+  {
+    /* We got the Row_lock. Do nothing. */
+    found_lock->busy= 1;
+    found_lock->owner_data= pins;
+    mysql_mutex_unlock(&found_lock->mutex);
+  }
+  else
+  {
+    if (found_lock->owner_data == pins)
+    {
+      /* We already own this lock */
+      found_lock->busy++;
+      mysql_mutex_unlock(&found_lock->mutex);
+    }
+    else
+    {
+      /* The found row_lock is not ours. Wait for it. */
+      found_lock->waiters++;
+      int res= 0;
+
+      struct timespec wait_timeout;
+      set_timespec(wait_timeout, timeout_sec);
+#ifndef STANDALONE_UNITTEST
+      THD *thd= current_thd;
+      PSI_stage_info old_stage;
+      thd_enter_cond(thd, &found_lock->cond, &found_lock->mutex,
+                     &stage_waiting_on_row_lock, &old_stage);
+#endif
+      while (found_lock->busy)
+      {
+        res= mysql_cond_timedwait(&found_lock->cond, &found_lock->mutex, 
+                                  &wait_timeout);
+        bool killed= false;
+#ifndef STANDALONE_UNITTEST
+        killed= thd_killed(thd);
+#endif
+        if (res == ETIMEDOUT || killed)
+        {
+          if (found_lock->busy)
+          {
+            // We own the mutex still
+            found_lock->waiters--; // we're not waiting anymore
+            mysql_mutex_unlock(&found_lock->mutex);
+            goto return_null;
+          }
+          else
+            break;
+        }
+        if (res!=0)
+          fprintf(stderr, "wait failed: %d\n", res);
+      }
+      
+      /*
+        Ok, now we own the mutex again, and the lock is released. Take it.
+      */
+      DBUG_ASSERT(!found_lock->busy);
+      found_lock->busy= 1;
+      found_lock->owner_data= pins;
+      found_lock->waiters--; // we're not waiting anymore
+#ifndef STANDALONE_UNITTEST
+      thd_exit_cond(thd, &old_stage);
+#else
+      mysql_mutex_unlock(&found_lock->mutex);
+#endif
+    }
+  }
+
+  if (key_copy)
+    my_free(key_copy);
+  return found_lock;
+
+return_null:
+  if (key_copy)
+    my_free(key_copy);
+  return NULL;
+}
+
+
+/*
+  Release the previously obtained lock
+    @param pins      This thread pins
+    @param own_lock  Previously obtained lock
+*/
+
+void LockTable::release_lock(LF_PINS *pins, Row_lock *own_lock)
+{
+  /* Acquire the mutex to prevent anybody from getting into the queue */
+  mysql_mutex_lock(&own_lock->mutex);
+
+  DBUG_ASSERT(own_lock->owner_data == pins);
+ 
+  if (--own_lock->busy)
+  {
+    /* 
+      We've released the lock once. We've acquired it more than once though,
+      so we still keep it.
+    */
+    mysql_mutex_unlock(&own_lock->mutex);
+    return; 
+  }
+
+  if (own_lock->waiters)
+  {
+    /* 
+      Somebody is waiting for this lock (they can't stop as we're holding the
+      mutex). They are now responsible for disposing of the lock.
+    */
+    mysql_cond_signal(&own_lock->cond);
+    mysql_mutex_unlock(&own_lock->mutex);
+  }
+  else
+  {
+    /* Nobody's waiting. Release the lock */
+    char *rowkey= own_lock->rowkey;
+    own_lock->deleted= true;
+    mysql_mutex_unlock(&own_lock->mutex);
+    int res= lf_hash_delete(&lf_hash, pins, own_lock->rowkey, own_lock->len);
+    DBUG_ASSERT(res == 0);
+    my_free(rowkey);
+  }
+}
+
diff --git a/storage/leveldb/ldb_locks.h b/storage/leveldb/ldb_locks.h
new file mode 100644
index 0000000..e83ccc2
--- /dev/null
+++ b/storage/leveldb/ldb_locks.h
@@ -0,0 +1,96 @@
+/* 
+   Copyright (c) 2012,2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface			/* gcc class implementation */
+#endif
+
+#include "my_sys.h"
+#include "lf.h"
+
+/*
+  A row lock that one gets from LockTable.
+
+  note: the structure is stored in LF_HASH, which will copy a part of
+  structure with memcpy(). See LockTable::init().
+*/
+class Row_lock
+{
+public:
+  char *rowkey; /* The key this lock is for */
+  int len; /* length of the rowkey */
+  
+  /* TRUE - this row_lock is being deleted */
+  bool deleted;
+  
+  /* How many are waiting for the lock */
+  int waiters;
+  
+  /* 
+    busy==0 - means free
+    busy>=1 - means the lock is occupied, the number tells how many rows the
+              lock was acquired
+  */
+  int busy;
+  
+  /* 
+    Some opaque data that identifies the lock owner.  This is needed so we can
+    tell if this is the lock owner requesting the lock the second time, or
+    somebody else.
+  */
+  void *owner_data;
+  
+  /*
+    One must hold this mutex 
+     - when marking lock as busy or free
+     - when adding/removing himself from waiters
+    the mutex is also associated with the condition when waiting for the lock.
+  */
+  mysql_mutex_t mutex;
+  mysql_cond_t cond;
+};
+
+
+/*
+  A table of locks. It is backed by a lock-free hash.
+
+  INTERNALS
+  - Locks are exclusive.
+  - If a thread has an element in the hashtable, it has a lock.
+*/
+
+class LockTable
+{
+public:
+  LF_HASH lf_hash;
+
+public:
+  void init(lf_key_comparison_func_t key_cmp_func,
+            lf_hashfunc_t hashfunc);
+
+  void cleanup();
+  /*
+    Before using the LockTable, each thread should get its own "pins". 
+  */
+  LF_PINS* get_pins() { return lf_hash_get_pins(&lf_hash); }
+  void put_pins(LF_PINS *pins) { return lf_hash_put_pins(pins); }
+
+  Row_lock* get_lock(LF_PINS *pins, const uchar* key, size_t keylen,
+                     int timeout_sec);
+  void release_lock(LF_PINS *pins, Row_lock *own_lock);
+};
+
+
diff --git a/storage/leveldb/ldb_rowmods.cc b/storage/leveldb/ldb_rowmods.cc
new file mode 100644
index 0000000..9a8aafe
--- /dev/null
+++ b/storage/leveldb/ldb_rowmods.cc
@@ -0,0 +1,364 @@
+/* 
+   Copyright (c) 2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "my_global.h"                   /* ulonglong */
+#include "my_base.h"                     /* ha_rows */
+#include "my_sys.h"
+#include "my_tree.h"
+
+#include "leveldb/db.h"
+#include "leveldb/comparator.h"
+#include "leveldb/write_batch.h"
+#include "ldb_rowmods.h"
+
+void Row_table::init()
+{
+  init_tree(&tree, 512 /*default_alloc_size*/, 0 /*memory_limit*/,
+            sizeof(void*)/*size*/, Row_table::compare_rows, 1 /*with_delete*/,
+            NULL /*free_element*/, NULL/*custom_arg*/);
+  tree.flag |= TREE_NO_DUPS;
+  init_alloc_root(&mem_root, 512, 512);
+  stmt_id= 1;
+  change_id= 0;
+}
+
+
+void Row_table::reinit()
+{
+  if (tree.elements_in_tree > 0)
+  {
+    cleanup();
+    init();
+  }
+}
+
+
+void Row_table::cleanup()
+{
+  delete_tree(&tree);
+  free_root(&mem_root, MYF(0));
+}
+
+
+/*
+  This function may
+  - find no records with the key.
+  - find a record with the key
+  - find a tombstone with the key.
+
+  @param found  OUT  TRUE means we've found a record
+                     FALSE means we've found a tombstone
+
+  @return true - means we've found a record or a tombstone
+          false - means found nothing
+*/
+
+bool Row_table::Get(leveldb::Slice &key, std::string *record, bool *found)
+{
+  ROW_DATA **row_ptr;
+  if ((row_ptr= (ROW_DATA**)tree_search(&tree, &key, &key)))
+  {
+    ROW_DATA *row= *row_ptr;
+    if (row->value_len == DATA_IS_TOMBSTONE)
+      *found= false; 
+    else
+    {
+      *found= true;
+      record->assign(((char*)row) + ROW_DATA_SIZE + row->key_len, row->value_len);
+    }
+    return true; /* Found either a record or a tombstone */
+  }
+  else
+    return false; /* Not found */
+}
+
+
+int Row_table::compare_rows(const void* arg, const void *a, const void *b)
+{
+  uchar *pa, *pb;
+  size_t a_size, b_size;
+  
+  /* One of the parameters may be a leveldb slice */
+  if (a == arg)
+  {
+    leveldb::Slice *slice= (leveldb::Slice*)a;
+    pa= (uchar*)slice->data();
+    a_size= slice->size();
+  }
+  else
+  {
+    ROW_DATA *row = *((ROW_DATA**)a);
+    a_size= row->key_len;
+    pa= ((uchar*)row) + ROW_DATA_SIZE;
+  }
+  
+  /* Same as above for b */
+  if (b == arg)
+  {
+    leveldb::Slice *slice= (leveldb::Slice*)b;
+    pb= (uchar*)slice->data();
+    b_size= slice->size();
+  }
+  else
+  {
+    ROW_DATA *row = *((ROW_DATA**)b);
+    b_size= row->key_len;
+    pb= ((uchar*)row) + ROW_DATA_SIZE;
+  }
+
+  size_t len= (a_size < b_size) ? a_size : b_size;
+  int res= memcmp(pa, pb, len);
+
+  if (!res)
+  {
+    if (a_size < b_size)
+      res= -1;
+    if (a_size > b_size)
+      res= 1;
+  }
+
+  return res;
+}
+
+
+bool Row_table::Put(leveldb::Slice& key, leveldb::Slice& val)
+{
+  uchar *data = (uchar*)alloc_root(&mem_root, ROW_DATA_SIZE + key.size() + 
+                                              val.size());
+
+  ROW_DATA *rdata= (ROW_DATA*)data;
+  rdata->key_len= key.size();
+  rdata->value_len= val.size();
+  rdata->stmt_id= stmt_id;
+  rdata->prev_version= NULL;
+  memcpy(data + ROW_DATA_SIZE, key.data(), key.size());
+  memcpy(data + ROW_DATA_SIZE + key.size(), val.data(), val.size());
+ 
+  change_id++;
+  if (!tree_insert(&tree, &data, /*key_size*/0, NULL/*custom_arg*/))
+  {
+    /* There is already a record with this key (or Out-Of-Memory) */
+    ROW_DATA **row_ptr;
+    row_ptr= (ROW_DATA**)tree_search(&tree, &key, &key);
+    if (!row_ptr)
+      return true;
+
+    /*
+      The record is from a previous statement. We may need to get back to
+      that record. Save a pointer to it
+    */
+    if ((*row_ptr)->stmt_id != stmt_id)
+    {
+      rdata->prev_version= *row_ptr;
+    }
+    *row_ptr= rdata;
+  }
+  return false;
+}
+
+
+/*
+  Put a tombstone into the table
+*/
+
+bool Row_table::Delete(leveldb::Slice& key)
+{
+  uchar *data = (uchar*)alloc_root(&mem_root, ROW_DATA_SIZE + key.size());
+  ROW_DATA *rdata= (ROW_DATA*)data;
+  rdata->key_len= key.size();
+  rdata->value_len= DATA_IS_TOMBSTONE;
+  rdata->stmt_id= stmt_id;
+  rdata->prev_version= NULL;
+  memcpy(data + ROW_DATA_SIZE, key.data(), key.size());
+
+  change_id++;
+
+  if (!tree_insert(&tree, &data, /*key_size*/0, NULL/*custom_arg*/))
+  {
+    /* There is already a record with this key (or Out-Of-Memory) */
+    ROW_DATA **row_ptr;
+    row_ptr= (ROW_DATA**)tree_search(&tree, &key, &key);
+    if (!row_ptr)
+      return true; /* OOM */
+    
+    if ((*row_ptr)->stmt_id != stmt_id)
+    {
+      /*
+        The record is from a previous statement. We may need to get back to
+        that record. Save a pointer to it
+      */
+      rdata->prev_version= *row_ptr;
+    }
+
+    /* Put the new record instead of the old one */
+    *row_ptr= rdata;
+  }
+  return false;
+}
+
+
+void Row_table::start_stmt()
+{
+  stmt_id++;
+}
+
+
+/*
+  Undo all changes made with the current stmt_id.
+*/
+void Row_table::rollback_stmt()
+{
+  ROW_DATA *delete_list= NULL;
+  Row_table_iter iter(this);
+
+  /*
+    To avoid invalidating the iterator, first collect all items that need to be
+    deleted in a linked list, and then actually do the deletes.
+  */
+  for (iter.SeekToFirst(); iter.Valid(); iter.Next())
+  {
+    if ((*iter.row_ptr)->stmt_id == stmt_id)
+    {
+      if ((*iter.row_ptr)->prev_version)
+      {
+        /*
+          This element has a previous version (the previous version is what the
+          element was before the current statement).
+          Replace the element with the its previous version. They have the same
+          key value, so there is no need to re-balance the tree.
+        */
+        *iter.row_ptr= (*iter.row_ptr)->prev_version;
+      }
+      else
+      {
+        /* No previous version. Record for removal */
+        (*iter.row_ptr)->prev_version= delete_list;
+        delete_list= (*iter.row_ptr);
+      }
+    }
+  }
+  
+  /* Do all of the recorded deletes */
+  while (delete_list) 
+  {
+    ROW_DATA *next= delete_list->prev_version;
+    
+    tree_delete(&tree, &delete_list, /*key_size*/ 0, NULL);
+
+    delete_list= next;
+  }
+
+  change_id++;
+}
+
+
+/****************************************************************************
+ * Row_table_iter
+ ***************************************************************************/
+
+Row_table_iter::Row_table_iter(Row_table *rtable_arg) : 
+  rtable(rtable_arg), row_ptr(NULL), change_id(rtable_arg->change_id)
+{}
+
+
+void Row_table_iter::Seek(const leveldb::Slice &slice)
+{
+  row_ptr= (ROW_DATA**)tree_search_key(&rtable->tree, &slice, parents, &last_pos,
+                                       HA_READ_KEY_OR_NEXT, &slice/*custom_arg*/);
+  change_id= rtable->change_id;
+}
+
+
+void Row_table_iter::SeekToFirst()
+{
+  row_ptr= (ROW_DATA**)tree_search_edge(&rtable->tree, parents, &last_pos, 
+                                        offsetof(TREE_ELEMENT, left));
+  change_id= rtable->change_id;
+}
+
+
+void Row_table_iter::SeekToLast()
+{
+  row_ptr= (ROW_DATA**)tree_search_edge(&rtable->tree, parents, &last_pos, 
+                                        offsetof(TREE_ELEMENT, right));
+  change_id= rtable->change_id;
+}
+
+
+void Row_table_iter::Next()
+{
+  if (rtable->change_id != change_id)
+  {
+    change_id= rtable->change_id;
+    row_ptr= (ROW_DATA**)tree_search_key(&rtable->tree, row_ptr, parents, 
+                                         &last_pos, HA_READ_AFTER_KEY,
+                                         NULL/*custom_arg*/);
+  }
+  else
+  {
+    row_ptr= (ROW_DATA**)tree_search_next(&rtable->tree, &last_pos, 
+                                          offsetof(TREE_ELEMENT, left),
+                                          offsetof(TREE_ELEMENT, right));
+  }
+}
+
+
+void Row_table_iter::Prev()
+{
+  if (rtable->change_id != change_id)
+  {
+    change_id= rtable->change_id;
+    row_ptr= (ROW_DATA**)tree_search_key(&rtable->tree, row_ptr, parents, 
+                                         &last_pos, HA_READ_BEFORE_KEY,
+                                         NULL/*custom_arg*/);
+  }
+  else
+  {
+    row_ptr= (ROW_DATA**)tree_search_next(&rtable->tree, &last_pos,
+                                          offsetof(TREE_ELEMENT, right),
+                                          offsetof(TREE_ELEMENT, left));
+  }
+}
+
+
+bool Row_table_iter::Valid()
+{
+  return (row_ptr != NULL);
+}
+
+
+bool Row_table_iter::is_tombstone()
+{
+  DBUG_ASSERT(Valid());
+  return ((*row_ptr)->value_len == DATA_IS_TOMBSTONE);
+}
+
+
+leveldb::Slice Row_table_iter::key()
+{
+  DBUG_ASSERT(Valid());
+  return leveldb::Slice(((char*)*row_ptr) + ROW_DATA_SIZE, (*row_ptr)->key_len);
+}
+
+
+leveldb::Slice Row_table_iter::value()
+{
+  DBUG_ASSERT(Valid() && !is_tombstone());
+  ROW_DATA *row= *row_ptr;
+  return leveldb::Slice(((char*)row) + ROW_DATA_SIZE + row->key_len, 
+                        row->value_len);
+}
+
diff --git a/storage/leveldb/ldb_rowmods.h b/storage/leveldb/ldb_rowmods.h
new file mode 100644
index 0000000..a626254
--- /dev/null
+++ b/storage/leveldb/ldb_rowmods.h
@@ -0,0 +1,140 @@
+/* 
+   Copyright (c) 2013 Monty Program Ab
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "my_tree.h"
+
+
+typedef struct st_row_data
+{
+  size_t key_len;
+
+  /* Can have a special value: DATA_IS_TOMBSTONE */
+  size_t value_len;
+  
+  /* Previous version */
+  struct st_row_data *prev_version;
+ 
+  /* Number of the statement that inserted this row/tombstone */
+  int stmt_id;
+
+  /* 
+    This structure is always followed by the key, which is followed by the
+    value
+  */
+} ROW_DATA;
+
+const size_t ROW_DATA_SIZE= ALIGN_SIZE(sizeof(ROW_DATA));
+
+const size_t DATA_IS_TOMBSTONE= size_t(-1);
+
+class Row_table;
+
+
+/*
+  A leveldb-like iterator for traversing contents of Row_table. 
+  
+  Changes (insertion/removal of records) to the underlying Row_table will not
+  invalidate this iterator (internally, the iterator will detect the change
+  and re-position itself).
+
+  The iterator uses ideas from B-TREE index scans on ha_heap tables.
+*/
+
+class Row_table_iter
+{
+  Row_table *rtable; /* Table this iterator is for*/
+
+  /* The following are for tree iteration: */
+  TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1];
+  TREE_ELEMENT **last_pos;
+  ROW_DATA **row_ptr;
+
+  /* 
+    If rtable->change_id is greater than ours, the iterator is invalidated and
+    we need to re-position in the tree 
+  */
+  int change_id;
+  friend class Row_table;
+public:
+  Row_table_iter(Row_table *rtable_arg);
+
+  /* Scanning functions */
+  void Seek(const leveldb::Slice &slice);
+  void SeekToFirst();
+  void SeekToLast();
+
+  void Next();
+  void Prev();
+  
+  /* Functions to get information about the current element */
+  bool Valid();
+  bool is_tombstone();
+  leveldb::Slice key();
+  leveldb::Slice value();
+};
+
+
+/*
+  A storage for rows, or their tombstones. One can use leveldb-like iterators
+  to traverse the rows.
+*/
+
+class Row_table
+{
+  TREE tree;
+  MEM_ROOT mem_root;
+
+  /* Current statement id */
+  int stmt_id;
+  
+  /* 
+    This is incremented on every change, so iterators can know 
+    if they were invalidated and should re-position themselves.
+  */
+  int change_id;
+
+  friend class Row_table_iter;
+public:
+  /* This is like a constructor */
+  void init(); 
+
+  void cleanup();
+  void reinit();
+
+  /* Operations to put a row, or a tombstone */
+  bool Put(leveldb::Slice& key, leveldb::Slice& val);
+  bool Delete(leveldb::Slice& key);
+  
+  /* Lookup may find nothing, find row, of find a tombstone */
+  bool Get(leveldb::Slice &key, std::string *record, bool *found);
+  
+  /*
+    Statement support. It is possible to rollback all changes made by the
+    current statement.
+  */
+  void start_stmt();
+  void rollback_stmt();
+
+  /* This may return false when there are really no changes (TODO: still true?) */
+  bool is_empty()
+  {
+    return test(tree.elements_in_tree == 0);
+  };
+private:
+  static int compare_rows(const void* arg, const void *a,const void *b);
+};
+
+
diff --git a/storage/leveldb/unittest/CMakeLists.txt b/storage/leveldb/unittest/CMakeLists.txt
new file mode 100644
index 0000000..468cc8c
--- /dev/null
+++ b/storage/leveldb/unittest/CMakeLists.txt
@@ -0,0 +1,11 @@
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
+                    ${CMAKE_SOURCE_DIR}/unittest/mytap)
+LINK_LIBRARIES(mytap mysys dbug strings)
+
+ADD_DEFINITIONS(-DSTANDALONE_UNITTEST)
+
+ADD_EXECUTABLE(test_rowlocks
+        test_rowlocks.cc ../ldb_locks.cc ../ldb_locks.h)
+#MY_ADD_TEST(test_rowlocks)
+
diff --git a/storage/leveldb/unittest/test_rowlocks.cc b/storage/leveldb/unittest/test_rowlocks.cc
new file mode 100644
index 0000000..d1251c5
--- /dev/null
+++ b/storage/leveldb/unittest/test_rowlocks.cc
@@ -0,0 +1,165 @@
+/*
+  TODO: MP AB Copyrights
+*/
+#include <my_sys.h>
+#include <string.h>
+#include "../ldb_locks.h"
+
+#include "thr_template.cc"
+
+
+/* This will hold one lock table that we're testing */
+LockTable *lock_table;
+
+const int N_ACCTS= 100;
+int bank_accounts[N_ACCTS];
+int total_money;
+
+bool prevent_deadlocks= true;
+
+int n_deadlocks= 0;
+
+int timeout_sec;
+
+int compare_int_keys(const uchar *s, size_t slen, 
+                     const uchar *t, size_t tlen)
+{
+  DBUG_ASSERT(slen==sizeof(int));
+  DBUG_ASSERT(tlen==sizeof(int));
+  int sval;
+  int tval;
+  memcpy(&sval, s, sizeof(int));
+  memcpy(&tval, t, sizeof(int));
+  if (sval < tval)
+    return -1;
+  else if (sval > tval)
+    return 1;
+  else
+    return 0;
+}
+
+/* Not really a hash function */
+ulong int_hashfunc(const char *key, size_t key_len)
+{
+  DBUG_ASSERT(key_len == sizeof(int));
+  int keyval;
+  memcpy(&keyval, key, sizeof(int));
+  return keyval;
+}
+
+
+/* This is one thread */
+pthread_handler_t locktable_test1(void *arg)
+{
+  LF_PINS *pins;
+  pins= lf_hash_get_pins(&lock_table->lf_hash);
+
+  /* In a loop, get a couple of locks */
+  int loop;
+  DBUG_ASSERT(RAND_MAX > N_ACCTS);
+
+  for (loop=0; loop < 200*1000; loop++)
+  {
+    int val1, val2;
+    val1= rand() % N_ACCTS;
+    do {
+      val2= rand() % N_ACCTS;
+    } while (val2 == val1);
+
+    if (prevent_deadlocks && val2 > val1)
+    {
+      int tmp=val2;
+      val2= val1;
+      val1= tmp;
+    }
+
+    int transfer=150;
+
+    Row_lock *lock1;
+    Row_lock *lock2;
+
+    lock1= lock_table->get_lock(pins, (uchar*)&val1, sizeof(int), timeout_sec);
+    DBUG_ASSERT(lock1);
+    lock2= lock_table->get_lock(pins, (uchar*)&val2, sizeof(int), timeout_sec);
+
+    if (!prevent_deadlocks && !lock2)
+    {
+      //Couldn't get lock2, must be a deadlock
+      lock_table->release_lock(pins, lock1);
+
+      mysql_mutex_lock(&mutex);
+      n_deadlocks++;
+      mysql_mutex_unlock(&mutex);
+      continue;
+    }
+
+    DBUG_ASSERT(lock2);
+    bank_accounts[val1] -= transfer;
+    bank_accounts[val2] += transfer;
+
+    lock_table->release_lock(pins, lock1);
+    lock_table->release_lock(pins, lock2);
+  }
+
+  lf_hash_put_pins(pins);
+ 
+  // Test harness needs us to signal that we're done:
+  mysql_mutex_lock(&mutex);
+  if (!--running_threads) mysql_cond_signal(&cond);
+  mysql_mutex_unlock(&mutex);
+
+  return 0;
+}
+
+
+void init_shared_data()
+{
+  total_money= 0;
+  for (int i=0; i < N_ACCTS;i++)
+  {
+    bank_accounts[i]= 1000;
+    total_money += bank_accounts[i]; 
+  }
+}
+
+void check_shared_data(const char *name)
+{
+  int money_after= 0;
+  for (int i=0; i < N_ACCTS; i++)
+    money_after += bank_accounts[i];
+  if (money_after == total_money)
+    fprintf(stderr, "# validation %s ok\n", name);
+  else
+    fprintf(stderr, "# validation %s failed: expected %d found %d\n", name,
+            total_money, money_after);
+}
+
+void do_tests()
+{
+  fprintf(stderr, "# lf_hash based lock table tests\n");
+
+  /* Global initialization */
+  lock_table= new LockTable;
+  lock_table->init(compare_int_keys, int_hashfunc);
+
+  init_shared_data();
+  prevent_deadlocks= true;
+  timeout_sec= 10*1000;
+
+  locktable_test1(NULL);
+
+  test_concurrently("locktable_test1", locktable_test1, 2 /*THREADS*/, 10 /*CYCLES*/);
+  check_shared_data("1");
+  
+
+  prevent_deadlocks= false;
+  timeout_sec= 2;
+  test_concurrently("locktable_test1", locktable_test1, 2 /*THREADS*/, 10 /*CYCLES*/);
+  check_shared_data("2");
+  fprintf(stderr, "# n_deadlocks=%d\n", n_deadlocks);
+  
+  lock_table->cleanup();
+
+  fprintf(stderr, "# tests end\n");
+}
+
diff --git a/storage/leveldb/unittest/thr_template.cc b/storage/leveldb/unittest/thr_template.cc
new file mode 100644
index 0000000..a0e1e5b
--- /dev/null
+++ b/storage/leveldb/unittest/thr_template.cc
@@ -0,0 +1,93 @@
+/* Copyright (c) 2006-2008 MySQL AB, 2009 Sun Microsystems, Inc.
+   Use is subject to license terms.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <my_atomic.h>
+#include <tap.h>
+
+volatile uint32 bad;
+pthread_attr_t thr_attr;
+mysql_mutex_t mutex;
+mysql_cond_t cond;
+uint running_threads;
+
+void do_tests();
+
+void test_concurrently(const char *test, pthread_handler handler, int n, int m)
+{
+  pthread_t t;
+  ulonglong now= my_getsystime();
+
+  bad= 0;
+
+  diag("Testing %s with %d threads, %d iterations... ", test, n, m);
+  for (running_threads= n ; n ; n--)
+  {
+    if (pthread_create(&t, &thr_attr, handler, &m) != 0)
+    {
+      diag("Could not create thread");
+      abort();
+    }
+  }
+  mysql_mutex_lock(&mutex);
+  while (running_threads)
+    mysql_cond_wait(&cond, &mutex);
+  mysql_mutex_unlock(&mutex);
+
+  now= my_getsystime()-now;
+  ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e7, bad);
+}
+
+int main(int argc __attribute__((unused)), char **argv)
+{
+  MY_INIT("thd_template");
+
+  if (argv[1] && *argv[1])
+    DBUG_SET_INITIAL(argv[1]);
+
+  mysql_mutex_init(0, &mutex, 0);
+  mysql_cond_init(0, &cond, 0);
+  pthread_attr_init(&thr_attr);
+  pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
+
+#ifdef MY_ATOMIC_MODE_RWLOCKS
+#if defined(HPUX11) || defined(__POWERPC__) /* showed to be very slow (scheduler-related) */
+#define CYCLES 300
+#else
+#define CYCLES 3000
+#endif
+#else
+#define CYCLES 3000
+#endif
+#define THREADS 30
+
+  diag("N CPUs: %d, atomic ops: %s", my_getncpus(), MY_ATOMIC_MODE);
+
+  do_tests();
+
+  /*
+    workaround until we know why it crashes randomly on some machine
+    (BUG#22320).
+  */
+  sleep(2);
+  mysql_mutex_destroy(&mutex);
+  mysql_cond_destroy(&cond);
+  pthread_attr_destroy(&thr_attr);
+  my_end(0);
+  return exit_status();
+}
+
diff --git a/support-files/build-tags b/support-files/build-tags
index e89cf40..accb526 100755
--- a/support-files/build-tags
+++ b/support-files/build-tags
@@ -6,7 +6,7 @@ filter='\.cpp$\|\.cc$\|\.c$\|\.h$\|sql_yacc\.yy$\|\.hpp$'
 list="find . -type f"
 bzr root >/dev/null 2>/dev/null && list="bzr ls --from-root -R --kind=file --versioned"
 
-$list |grep $filter |while read f; 
+$list | grep -v storage/ndb | grep $filter |while read f; 
 do
 	 etags -o TAGS --append $f
 done


More information about the commits mailing list