[Commits] Rev 4586: MDEV-4122: LevelDB: store key/index numbers, not names in file:///home/psergey/dev2/mysql-5.6-leveldb/

Sergey Petrunya psergey at askmonty.org
Fri Feb 1 16:44:53 EET 2013


At file:///home/psergey/dev2/mysql-5.6-leveldb/

------------------------------------------------------------
revno: 4586
revision-id: psergey at askmonty.org-20130201144452-3g0jmd4dkvlb9s3w
parent: psergey at askmonty.org-20130201133747-eqmzcu1ivj0msm6u
committer: Sergey Petrunya <psergey at askmonty.org>
branch nick: mysql-5.6-leveldb
timestamp: Fri 2013-02-01 18:44:52 +0400
message:
  MDEV-4122: LevelDB: store key/index numbers, not names
  - Initial ALTER TABLE support
=== modified file 'mysql-test/r/leveldb.result'
--- a/mysql-test/r/leveldb.result	2013-01-30 04:21:07 +0000
+++ b/mysql-test/r/leveldb.result	2013-02-01 14:44:52 +0000
@@ -283,7 +283,6 @@ drop table t9;
 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;
-ERROR HY000: Table storage engine for 't15' doesn't have this option
 DROP TABLE t15;
 #
 # MDEV-3968: UPDATE produces a wrong result while modifying a PK on a LevelDB table
@@ -798,3 +797,17 @@ pk	col1
 2	row2
 3	row3
 drop table t44;
+#
+# ALTER TABLE tests
+#
+create table t45 (pk int primary key, col1 varchar(12));
+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'

=== modified file 'mysql-test/t/leveldb.test'
--- a/mysql-test/t/leveldb.test	2013-01-29 18:06:11 +0000
+++ b/mysql-test/t/leveldb.test	2013-02-01 14:44:52 +0000
@@ -252,7 +252,7 @@ drop table t9;
 --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
+#--error ER_ILLEGAL_HA
 ALTER TABLE t15 DROP COLUMN a;
 DROP TABLE t15;
 
@@ -701,3 +701,15 @@ 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));
+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;
+

=== modified file 'storage/leveldb/ha_leveldb.cc'
--- a/storage/leveldb/ha_leveldb.cc	2013-02-01 13:30:37 +0000
+++ b/storage/leveldb/ha_leveldb.cc	2013-02-01 14:44:52 +0000
@@ -413,8 +413,8 @@ static int leveldb_init_func(void *p)
     TABLE to create an empty table from scratch. LevelDB cannot efficiently
     re-create a table.
   */
-  leveldb_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED |
-                       HTON_ALTER_NOT_SUPPORTED;
+  leveldb_hton->flags= HTON_TEMPORARY_NOT_SUPPORTED;// |
+                       //HTON_ALTER_NOT_SUPPORTED;
 
   /*
     As for the datadir, innobase_init() uses mysql_real_data_home for
@@ -897,6 +897,28 @@ bool ha_leveldb::get_error_message(int e
   return FALSE; /* not a temporary 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
@@ -920,7 +942,7 @@ int ha_leveldb::create(const char *name,
                        HA_CREATE_INFO *create_info)
 {
   int res;
-  const char *tablename= name;
+  StringBuffer<256> strbuf;
   DBUG_ENTER("ha_leveldb::create");
   
   /* 
@@ -928,23 +950,8 @@ int ha_leveldb::create(const char *name,
     passes strings like "./test/t14#P#p0" for individual partitions,
     while table_arg->s->table_name has none of that.
   */
-  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?
-      DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
-    }
-  }
-  /* Note: this will delete all indexes, primary and secondary */
-  StringBuffer<256> strbuf;
-  strbuf.append(tablename, p - tablename);
-  strbuf.append('.');
-  strbuf.append(p + 1);
+  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
@@ -955,7 +962,7 @@ int ha_leveldb::create(const char *name,
   
   /*
     We only support auto_increment at start of the PRIMARY KEY.
-  */
+  */ //TODO: this doesn't work (values are all zeros)
   TABLE_SHARE *share= table_arg->s;
   if (share->next_number_index != MAX_KEY)
   {
@@ -2088,25 +2095,15 @@ int ha_leveldb::external_lock(THD *thd, 
 
 int ha_leveldb::delete_table(const char *tablename)
 {
+  StringBuffer<256> strbuf;
   DBUG_ENTER("ha_leveldb::delete_table");
 
-  DBUG_ASSERT(tablename[0] == '.' && tablename[1] == '/');
-  tablename += 2;
-
-  const char *p= tablename;
-  for (; *p != '/'; p++)
+  if (leveldb_normalize_tablename(tablename, &strbuf))
   {
-    if (*p =='\0')
-    {
-      DBUG_ASSERT(0); // We were not passed table name?
-      DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
-    }
+    DBUG_ASSERT(0); // We were not passed table name?
+    DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
   }
-  /* Note: this will delete all indexes, primary and secondary */
-  StringBuffer<256> strbuf;
-  strbuf.append(tablename, p - tablename);
-  strbuf.append('.');
-  strbuf.append(p + 1);
+
 
   /* Find the table in the hash */
   LDBSE_TABLE_DEF *tbl;
@@ -2142,12 +2139,30 @@ int ha_leveldb::delete_table(const char 
     Remove the table entry in data dictionary (this will also remove it from
     the persistent data dictionary).
   */
-  ddl_manager.remove(tbl, ldb_dict);
+  ddl_manager.remove(tbl, ldb_dict, true);
 
   DBUG_RETURN(0);
 }
 
 
+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_dict))
+    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

=== modified file 'storage/leveldb/ha_leveldb.h'
--- a/storage/leveldb/ha_leveldb.h	2013-02-01 13:30:37 +0000
+++ b/storage/leveldb/ha_leveldb.h	2013-02-01 14:44:52 +0000
@@ -168,11 +168,7 @@ class ha_leveldb: public handler
   }
 
 
-  int rename_table(const char *from, const char *to)
-  {
-    //DBUG_ASSERT(0); /* Not supported yet */
-    return HA_ERR_INTERNAL_ERROR;
-  }
+  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);

=== modified file 'storage/leveldb/ldb_datadic.cc'
--- a/storage/leveldb/ldb_datadic.cc	2013-02-01 13:37:47 +0000
+++ b/storage/leveldb/ldb_datadic.cc	2013-02-01 14:44:52 +0000
@@ -810,7 +810,7 @@ void LDBSE_TABLE_DEF::write_to(leveldb::
 {
   StringBuffer<32> indexes;
 
-  for (uint i; i < n_keys; i++)
+  for (uint i=0; i < n_keys; i++)
   {
     write_int(&indexes, key_descr[i]->index_number);
   }
@@ -928,12 +928,13 @@ LDBSE_TABLE_DEF* Table_ddl_manager::find
 
 /* Return 0 - ok, other value - error */
 
-int Table_ddl_manager::put(LDBSE_TABLE_DEF *tbl)
+int Table_ddl_manager::put(LDBSE_TABLE_DEF *tbl, bool lock)
 {
   LDBSE_TABLE_DEF *rec;
   my_bool result;
 
-  mysql_rwlock_wrlock(&rwlock);
+  if (lock)
+    mysql_rwlock_wrlock(&rwlock);
   rec= (LDBSE_TABLE_DEF*)find((uchar*)tbl->dbname_tablename.c_ptr(),
                                tbl->dbname_tablename.length(), false);
   if (rec)
@@ -943,18 +944,53 @@ int Table_ddl_manager::put(LDBSE_TABLE_D
   }
   result= my_hash_insert(&ddl_hash, (uchar*)tbl);
 
-  mysql_rwlock_unlock(&rwlock);
+  if (lock)
+    mysql_rwlock_unlock(&rwlock);
   return result;
 }
 
 
-void Table_ddl_manager::remove(LDBSE_TABLE_DEF *tbl, leveldb::DB *ldb_dict)
+void Table_ddl_manager::remove(LDBSE_TABLE_DEF *tbl, leveldb::DB *ldb_dict, bool lock)
 {
+  if (lock)
+    mysql_rwlock_wrlock(&rwlock);
   leveldb::Slice tkey(tbl->dbname_tablename.ptr(), tbl->dbname_tablename.length());
   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;
+
+  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->key_descr= rec->key_descr;
+  rec->key_descr= NULL; /* so that it's not free'd when deleting the old rec */
+
+  new_rec->write_to(ldb_dict);
+  remove(rec, ldb_dict, false);
+  put(new_rec, false);
+  res= false; // ok
+err:
+  mysql_rwlock_unlock(&rwlock);
+  return res;
 }
 
 

=== modified file 'storage/leveldb/ldb_datadic.h'
--- a/storage/leveldb/ldb_datadic.h	2013-02-01 13:37:47 +0000
+++ b/storage/leveldb/ldb_datadic.h	2013-02-01 14:44:52 +0000
@@ -234,9 +234,13 @@ class Table_ddl_manager
 public:
   bool init(leveldb::DB *ldb_dict, Keydef_store *keydef_store);
   void cleanup();
-  int put(LDBSE_TABLE_DEF *key_descr);
-  void remove(LDBSE_TABLE_DEF *rec, 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);
 
 private:
   static uchar* get_hash_key(LDBSE_TABLE_DEF *rec, size_t *length,



More information about the commits mailing list