[Groonga-mysql-commit] mroonga/mroonga [master] cleanup MySQL type -> groonga type conversion.

Back to archive index

null+****@clear***** null+****@clear*****
2011年 12月 19日 (月) 16:32:21 JST


Kouhei Sutou	2011-12-19 07:32:21 +0000 (Mon, 19 Dec 2011)

  New Revision: 5f2e5a847f721ef3124ee9ea1f07eb1b5da732d6

  Log:
    cleanup MySQL type -> groonga type conversion.

  Modified files:
    ha_mroonga.cc
    ha_mroonga.h

  Modified: ha_mroonga.cc (+111 -44)
===================================================================
--- ha_mroonga.cc    2011-12-19 05:35:16 +0000 (a574093)
+++ ha_mroonga.cc    2011-12-19 07:32:21 +0000 (7f5c3ee)
@@ -45,6 +45,10 @@
 
 #define MRN_MESSAGE_BUFFER_SIZE 1024
 
+#define MRN_SHORT_TEXT_SIZE (1 << 12) //  4Kbytes
+#define MRN_TEXT_SIZE       (1 << 16) // 64Kbytes
+#define MRN_LONG_TEXT_SIZE  (1 << 31) //  2Gbytes
+
 #define MRN_DBUG_ENTER_FUNCTION() DBUG_ENTER(__FUNCTION__)
 #if !defined(DBUG_OFF) && !defined(_lint)
 #  define MRN_DBUG_ENTER_METHOD()                 \
@@ -502,47 +506,114 @@ static bool mrn_is_geo_key(KEY *key_info)
     key_info->key_part[0].field->type() == MYSQL_TYPE_GEOMETRY;
 }
 
-static grn_builtin_type mrn_get_type(grn_ctx *ctx,
-                                     enum_field_types mysql_field_type)
+static grn_builtin_type mrn_grn_type_from_field(grn_ctx *ctx, Field *field,
+                                                bool for_index_key)
 {
-  grn_builtin_type type;
+  grn_builtin_type type = GRN_DB_VOID;
+  enum_field_types mysql_field_type = field->type();
   switch (mysql_field_type) {
-  case MYSQL_TYPE_BIT:      // bit
-  case MYSQL_TYPE_ENUM:     // enum
-  case MYSQL_TYPE_SET:      // set
-  case MYSQL_TYPE_TINY:     // tinyint
-    type = GRN_DB_INT8;
+  case MYSQL_TYPE_DECIMAL:      // DECIMAL; <= 65bytes
+    type = GRN_DB_SHORT_TEXT;   // 4Kbytes
     break;
-  case MYSQL_TYPE_SHORT:    // smallint
-    type = GRN_DB_INT16; // 2bytes
+  case MYSQL_TYPE_TINY:         // TINYINT; 1byte
+    type = GRN_DB_INT8;         // 1byte
     break;
-  case MYSQL_TYPE_INT24:    // mediumint
-  case MYSQL_TYPE_LONG:     // int
-    type = GRN_DB_INT32; // 4bytes
+  case MYSQL_TYPE_SHORT:        // SMALLINT; 2bytes
+    type = GRN_DB_INT16;        // 2bytes
     break;
-  case MYSQL_TYPE_LONGLONG: // bigint
-    type = GRN_DB_INT64; // 8bytes
+  case MYSQL_TYPE_LONG:         // INT; 4bytes
+    type = GRN_DB_INT32;        // 4bytes
     break;
-  case MYSQL_TYPE_FLOAT:    // float
-  case MYSQL_TYPE_DOUBLE:   // double
-    type = GRN_DB_FLOAT; // 8bytes
+  case MYSQL_TYPE_FLOAT:        // FLOAT; 4bytes
+  case MYSQL_TYPE_DOUBLE:       // DOUBLE; 8bytes
+    type = GRN_DB_FLOAT;        // 8bytes
     break;
-  case MYSQL_TYPE_DATE:     // date
-  case MYSQL_TYPE_TIME:     // time
-  case MYSQL_TYPE_YEAR:     // year
-  case MYSQL_TYPE_DATETIME: // datetime
-    type = GRN_DB_TIME; // micro sec from epoc time by int64
+  case MYSQL_TYPE_NULL:         // NULL; ???
+    type = GRN_DB_INT8;         // XXX: Is it OK?
     break;
-  case MYSQL_TYPE_GEOMETRY: // geometry
-    type = GRN_DB_WGS84_GEO_POINT; // geo point in WGS84
+  case MYSQL_TYPE_TIMESTAMP:    // TIMESTAMP; 4bytes
+    type = GRN_DB_TIME;         // 8bytes
     break;
-  default:
-    // tinytext=256, text=64K, mediumtext=16M, longtext=4G
-    // tinyblob...
-    // GRN_DB_SHORTTEXT 4096bytes
-    // GRN_DB_TEXT      ???bytes
-    // GRN_DB_LONGTEXT  ???bytes
-    type = GRN_DB_TEXT;       // others
+  case MYSQL_TYPE_LONGLONG:     // BIGINT; 8bytes
+    type = GRN_DB_INT64;        // 8bytes
+    break;
+  case MYSQL_TYPE_INT24:        // MEDIUMINT; 3bytes
+    type = GRN_DB_INT32;        // 4bytes
+    break;
+  case MYSQL_TYPE_DATE:         // DATE; 3bytes
+  case MYSQL_TYPE_TIME:         // TIME; 3bytes
+  case MYSQL_TYPE_DATETIME:     // DATETIME; 8bytes
+  case MYSQL_TYPE_YEAR:         // YEAR; 1byte
+  case MYSQL_TYPE_NEWDATE:      // ???
+    type = GRN_DB_TIME;         // 8bytes
+    break;
+  case MYSQL_TYPE_VARCHAR:      // VARCHAR; <= 64KB + 1bytes
+    if (for_index_key) {
+      type = GRN_DB_SHORT_TEXT; // 4Kbytes
+    } else {
+      if (field->field_length <= MRN_SHORT_TEXT_SIZE) {
+        type = GRN_DB_SHORT_TEXT; //  4Kbytes
+      } else if (field->field_length <= MRN_TEXT_SIZE) {
+        type = GRN_DB_TEXT;       // 64Kbytes
+      } else {
+        type = GRN_DB_LONG_TEXT;  //  2Gbytes
+      }
+    }
+    break;
+  case MYSQL_TYPE_BIT:          // BIT; <= 8bytes
+    type = GRN_DB_INT64;        // 8bytes
+    break;
+  case MYSQL_TYPE_NEWDECIMAL:   // ???
+    type = GRN_DB_SHORT_TEXT;   // 4Kbytes
+  case MYSQL_TYPE_ENUM:         // ENUM; <= 2bytes
+    type = GRN_DB_INT16;        // 2bytes
+    break;
+  case MYSQL_TYPE_SET:          // SET; <= 8bytes
+    type = GRN_DB_INT64;        // 8bytes
+    break;
+  case MYSQL_TYPE_TINY_BLOB:    // TINYBLOB; <= 256bytes
+    type = GRN_DB_SHORT_TEXT;   // 4Kbytes
+    break;
+  case MYSQL_TYPE_MEDIUM_BLOB:  // MEDIUMBLOB; <= 16Mbytes + 2bytes
+    if (for_index_key) {
+      type = GRN_DB_SHORT_TEXT; // 4Kbytes
+    } else {
+      type = GRN_DB_LONG_TEXT;  // 2Gbytes
+    }
+    break;
+  case MYSQL_TYPE_LONG_BLOB:    // LONGBLOB; <= 4Gbytes + 3bytes
+    if (for_index_key) {
+      type = GRN_DB_SHORT_TEXT; // 4Kbytes
+    } else {
+      type = GRN_DB_LONG_TEXT;  // 2Gbytes
+    }
+    break;
+  case MYSQL_TYPE_BLOB:         // BLOB; <= 64Kbytes + 1bytes
+    if (for_index_key) {
+      type = GRN_DB_SHORT_TEXT; // 4Kbytes
+    } else {
+      type = GRN_DB_LONG_TEXT;  // 2Gbytes
+    }
+    break;
+  case MYSQL_TYPE_VAR_STRING:   // ??? VARCHAR???; <= 64KB + 1bytes
+    if (for_index_key) {
+      type = GRN_DB_SHORT_TEXT; // 4Kbytes
+    } else {
+      if (field->field_length <= MRN_SHORT_TEXT_SIZE) {
+        type = GRN_DB_SHORT_TEXT; //  4Kbytes
+      } else if (field->field_length <= MRN_TEXT_SIZE) {
+        type = GRN_DB_TEXT;       // 64Kbytes
+      } else {
+        type = GRN_DB_LONG_TEXT;  //  2Gbytes
+      }
+    }
+    break;
+  case MYSQL_TYPE_STRING:       // ??? CHAR???; < 1Kbytes =~ (255 * 4)bytes
+                                //              4 is the maximum size of a character
+    type = GRN_DB_SHORT_TEXT; // 4Kbytes
+    break;
+  case MYSQL_TYPE_GEOMETRY:     // ???bytes
+    type = GRN_DB_WGS84_GEO_POINT; // 8bytes
     break;
   }
   return type;
@@ -1542,7 +1613,7 @@ int ha_mroonga::wrapper_create(const char *name, TABLE *table,
   DBUG_RETURN(error);
 }
 
-int ha_mroonga::wrapper_validate_key_info(KEY *key_info)
+int ha_mroonga::wrapper_create_index_fulltext_validate(KEY *key_info)
 {
   MRN_DBUG_ENTER_METHOD();
 
@@ -1551,15 +1622,14 @@ int ha_mroonga::wrapper_validate_key_info(KEY *key_info)
   for (i = 0; i < key_info->key_parts; i++) {
     Field *field = key_info->key_part[i].field;
 
-    enum_field_types mysql_field_type = field->type();
-    grn_builtin_type gtype = mrn_get_type(ctx, mysql_field_type);
-    if (gtype != GRN_DB_TEXT)
+    grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, true);
+    if (gtype != GRN_DB_SHORT_TEXT)
     {
       error = ER_CANT_CREATE_TABLE;
       GRN_LOG(ctx, GRN_LOG_ERROR,
               "key type must be text: <%d> "
               "(TODO: We should show type name not type ID.)",
-              mysql_field_type);
+              field->type());
       my_message(ER_CANT_CREATE_TABLE,
                  "key type must be text. (TODO: We should show type name.)",
                  MYF(0));
@@ -1580,7 +1650,7 @@ int ha_mroonga::wrapper_create_index_fulltext(grn_obj *grn_table,
   MRN_DBUG_ENTER_METHOD();
   int error = 0;
 
-  error = wrapper_validate_key_info(key_info);
+  error = wrapper_create_index_fulltext_validate(key_info);
   if (error) {
     DBUG_RETURN(error);
   }
@@ -1779,8 +1849,7 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
       int column_name_size = strlen(column_name);
       is_id = (strncmp(MRN_COLUMN_NAME_ID, column_name, column_name_size) == 0);
 
-      enum_field_types mysql_field_type = pkey_field->type();
-      grn_builtin_type gtype = mrn_get_type(ctx, mysql_field_type);
+      grn_builtin_type gtype = mrn_grn_type_from_field(ctx, pkey_field, false);
       pkey_type = grn_ctx_at(ctx, gtype);
     } else {
       is_id = false;
@@ -1837,8 +1906,7 @@ int ha_mroonga::storage_create(const char *name, TABLE *table,
     }
 
     grn_obj_flags col_flags = GRN_OBJ_PERSISTENT | GRN_OBJ_COLUMN_SCALAR;
-    enum_field_types mysql_field_type = field->type();
-    grn_builtin_type gtype = mrn_get_type(ctx, mysql_field_type);
+    grn_builtin_type gtype = mrn_grn_type_from_field(ctx, field, false);
     col_type = grn_ctx_at(ctx, gtype);
     char *col_path = NULL; // we don't specify path
 
@@ -1968,8 +2036,7 @@ int ha_mroonga::storage_create_index(TABLE *table, const char *grn_table_name,
     }
 
     column = grn_obj_column(ctx, grn_table, column_name, column_name_size);
-    enum_field_types mysql_field_type = field->type();
-    grn_builtin_type groonga_type = mrn_get_type(ctx, mysql_field_type);
+    grn_builtin_type groonga_type = mrn_grn_type_from_field(ctx, field, true);
     index_type = grn_ctx_at(ctx, groonga_type);
   } else {
     index_type = grn_ctx_at(ctx, GRN_DB_SHORT_TEXT);

  Modified: ha_mroonga.h (+1 -1)
===================================================================
--- ha_mroonga.h    2011-12-19 05:35:16 +0000 (2ab0b1c)
+++ ha_mroonga.h    2011-12-19 07:32:21 +0000 (1de4921)
@@ -385,7 +385,7 @@ private:
                      HA_CREATE_INFO *info, MRN_SHARE *tmp_share);
   int storage_create(const char *name, TABLE *table,
                      HA_CREATE_INFO *info, MRN_SHARE *tmp_share);
-  int wrapper_validate_key_info(KEY *key_info);
+  int wrapper_create_index_fulltext_validate(KEY *key_info);
   int wrapper_create_index_fulltext(grn_obj *grn_table,
                                     const char *grn_table_name,
                                     int i,




Groonga-mysql-commit メーリングリストの案内
Back to archive index