[Commits] Rev 3522: Dynamic columns insert. in file:///home/bell/maria/bzr/work-maria-5.5-cassandra/
sanja at montyprogram.com
sanja at montyprogram.com
Wed Sep 26 22:09:26 EEST 2012
At file:///home/bell/maria/bzr/work-maria-5.5-cassandra/
------------------------------------------------------------
revno: 3522
revision-id: sanja at montyprogram.com-20120926190923-oxdeydkyu12bmx1m
parent: sanja at montyprogram.com-20120925151828-0b5m3mp0h4jeqhut
committer: sanja at montyprogram.com
branch nick: work-maria-5.5-cassandra
timestamp: Wed 2012-09-26 22:09:23 +0300
message:
Dynamic columns insert.
-------------- next part --------------
=== modified file 'include/ma_dyncol.h'
--- a/include/ma_dyncol.h 2012-09-25 15:18:28 +0000
+++ b/include/ma_dyncol.h 2012-09-26 19:09:23 +0000
@@ -175,13 +175,17 @@ dynamic_column_json(DYNAMIC_COLUMN *str,
/* conversion of values to 3 base types */
enum enum_dyncol_func_result
dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
- my_bool quote);
+ CHARSET_INFO *cs, my_bool quote);
enum enum_dyncol_func_result
dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
enum enum_dyncol_func_result
dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val);
+enum enum_dyncol_func_result
+dynamic_column_vals(DYNAMIC_COLUMN *str,
+ DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals,
+ char **free_names);
/***************************************************************************
Internal functions, don't use if you don't know what you are doing...
=== modified file 'mysql-test/r/cassandra.result'
--- a/mysql-test/r/cassandra.result 2012-09-25 15:18:28 +0000
+++ b/mysql-test/r/cassandra.result 2012-09-26 19:09:23 +0000
@@ -363,7 +363,7 @@ delete from t2;
insert into t2 values(1,'9b5658dc-f32f-11e1-94cd-f46d046e9f09');
insert into t2 values(2,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a');
drop table t2;
-CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
+CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
select rowkey, column_list(dyn), column_get(dyn, 'uuidcol' as char) from t2;
rowkey column_list(dyn) column_get(dyn, 'uuidcol' as char)
1 `uuidcol` 9b5658dc-f32f-11e1-94cd-f46d046e9f09
@@ -373,3 +373,13 @@ CREATE TABLE t2 (rowkey bigint PRIMARY K
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
delete from t2;
drop table t2;
+#
+# Dynamic column insert
+#
+CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
+insert into t2 values (1, column_create("dyn1", 1, "dyn2", "two"));
+select rowkey, column_json(dyn) from t2;
+rowkey column_json(dyn)
+1 [{"dyn1":"1"},{"dyn2":"two"}]
+delete from t2;
+drop table t2;
=== modified file 'mysql-test/t/cassandra.test'
--- a/mysql-test/t/cassandra.test 2012-09-25 15:18:28 +0000
+++ b/mysql-test/t/cassandra.test 2012-09-26 19:09:23 +0000
@@ -463,7 +463,7 @@ insert into t2 values(2,'9b5658dc-f32f-1
drop table t2;
#test dynamic column read
-CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
+CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
select rowkey, column_list(dyn), column_get(dyn, 'uuidcol' as char) from t2;
drop table t2;
@@ -473,6 +473,15 @@ CREATE TABLE t2 (rowkey bigint PRIMARY K
delete from t2;
drop table t2;
+--echo #
+--echo # Dynamic column insert
+--echo #
+CREATE TABLE t2 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
+insert into t2 values (1, column_create("dyn1", 1, "dyn2", "two"));
+select rowkey, column_json(dyn) from t2;
+delete from t2;
+drop table t2;
+
############################################################################
## Cassandra cleanup
############################################################################
=== modified file 'mysys/ma_dyncol.c'
--- a/mysys/ma_dyncol.c 2012-09-25 15:18:28 +0000
+++ b/mysys/ma_dyncol.c 2012-09-26 19:09:23 +0000
@@ -3443,7 +3443,7 @@ end:
enum enum_dyncol_func_result
dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
- my_bool quote)
+ CHARSET_INFO *cs, my_bool quote)
{
char buff[40];
int len;
@@ -3473,24 +3473,22 @@ dynamic_column_val_str(DYNAMIC_STRING *s
char *alloc= NULL;
char *from= val->x.string.value.str;
uint bufflen;
- my_bool conv= !my_charset_same(val->x.string.charset,
- &my_charset_utf8_general_ci);
+ my_bool conv= !my_charset_same(val->x.string.charset, cs);
my_bool rc;
len= val->x.string.value.length;
- bufflen= (len * (conv ? my_charset_utf8_general_ci.mbmaxlen : 1));
+ bufflen= (len * (conv ? cs->mbmaxlen : 1));
if (dynstr_realloc(str, bufflen))
return ER_DYNCOL_RESOURCE;
// guaranty UTF-8 string for value
- if (!my_charset_same(val->x.string.charset,
- &my_charset_utf8_general_ci))
+ if (!my_charset_same(val->x.string.charset, cs))
{
uint dummy_errors;
if (!quote)
{
/* convert to the destination */
str->length+= copy_and_convert_extended(str->str, bufflen,
- &my_charset_utf8_general_ci,
+ cs,
from, len,
val->x.string.charset,
&dummy_errors);
@@ -3499,8 +3497,7 @@ dynamic_column_val_str(DYNAMIC_STRING *s
if ((alloc= (char *)my_malloc(bufflen, MYF(0))))
{
len=
- copy_and_convert_extended(alloc, bufflen,
- &my_charset_utf8_general_ci,
+ copy_and_convert_extended(alloc, bufflen, cs,
from, len, val->x.string.charset,
&dummy_errors);
from= alloc;
@@ -3774,7 +3771,8 @@ dynamic_column_json(DYNAMIC_COLUMN *str,
}
json->str[json->length++]= '"';
json->str[json->length++]= ':';
- if ((rc= dynamic_column_val_str(json, &val, TRUE)) < 0 ||
+ if ((rc= dynamic_column_val_str(json, &val,
+ &my_charset_utf8_general_ci, TRUE)) < 0 ||
dynstr_append_mem(json, "}", 1))
goto err;
}
@@ -3809,6 +3807,7 @@ dynamic_column_vals(DYNAMIC_COLUMN *str,
uint i;
enum enum_dyncol_func_result rc;
+ *free_names= 0;
bzero(names, sizeof(DYNAMIC_ARRAY)); /* In case of errors */
bzero(vals, sizeof(DYNAMIC_ARRAY)); /* In case of errors */
if (str->length == 0)
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2012-06-14 18:05:31 +0000
+++ b/sql/sql_base.cc 2012-09-26 19:09:23 +0000
@@ -9773,6 +9773,7 @@ int dynamic_column_error_message(enum_dy
switch (rc) {
case ER_DYNCOL_YES:
case ER_DYNCOL_OK:
+ case ER_DYNCOL_TRUNCATED:
break; // it is not an error
case ER_DYNCOL_FORMAT:
my_error(ER_DYN_COL_WRONG_FORMAT, MYF(0));
=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h 2012-05-16 15:44:17 +0000
+++ b/sql/sql_base.h 2012-09-26 19:09:23 +0000
@@ -272,6 +272,7 @@ bool rename_temporary_table(THD* thd, TA
const char *table_name);
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
+class Open_tables_backup;
/* Functions to work with system tables. */
bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
Open_tables_backup *backup);
=== modified file 'storage/cassandra/ha_cassandra.cc'
--- a/storage/cassandra/ha_cassandra.cc 2012-09-25 15:18:28 +0000
+++ b/storage/cassandra/ha_cassandra.cc 2012-09-26 19:09:23 +0000
@@ -31,6 +31,7 @@ static handler *cassandra_create_handler
TABLE_SHARE *table,
MEM_ROOT *mem_root);
+extern int dynamic_column_error_message(enum_dyncol_func_result rc);
handlerton *cassandra_hton;
@@ -811,7 +812,7 @@ static int convert_hex_digit(const char
const char map2number[]="0123456789abcdef";
-static void convert_uuid2string (char *str, const char *cass_data)
+static void convert_uuid2string(char *str, const char *cass_data)
{
char *ptr= str;
/* UUID arrives as 16-byte number in network byte order */
@@ -825,6 +826,29 @@ static void convert_uuid2string (char *s
*ptr= 0;
}
+static bool convert_string2uuid(char *buf, const char *str)
+{
+ int lower, upper;
+ for (uint i= 0; i < 16; i++)
+ {
+ if ((upper= convert_hex_digit(str[0])) == -1 ||
+ (lower= convert_hex_digit(str[1])) == -1)
+ {
+ return true;
+ }
+ buf[i]= lower | (upper << 4);
+ str += 2;
+ if (i == 3 || i == 5 || i == 7 || i == 9)
+ {
+ if (str[0] != '-')
+ return true;
+ str++;
+ }
+ }
+ return false;
+}
+
+
class UuidDataConverter : public ColumnDataConverter
{
char buf[16]; /* Binary UUID representation */
@@ -842,29 +866,12 @@ public:
bool mariadb_to_cassandra(char **cass_data, int *cass_data_len)
{
String *uuid_str= field->val_str(&str_buf);
- char *pstr= (char*)uuid_str->c_ptr();
- if (uuid_str->length() != 36)
+ if (uuid_str->length() != 36)
+ return true;
+
+ if (convert_string2uuid(buf, (char*)uuid_str->c_ptr()))
return true;
-
- int lower, upper;
- for (uint i=0; i < 16; i++)
- {
- if ((upper= convert_hex_digit(pstr[0])) == -1 ||
- (lower= convert_hex_digit(pstr[1])) == -1)
- {
- return true;
- }
- buf[i]= lower | (upper << 4);
- pstr += 2;
- if (i == 3 || i == 5 || i == 7 || i == 9)
- {
- if (pstr[0] != '-')
- return true;
- pstr++;
- }
- }
-
*cass_data= buf;
*cass_data_len= 16;
return false;
@@ -887,6 +894,27 @@ bool cassandra_to_dyncol_intLong(const c
#endif
return 0;
}
+
+bool dyncol_to_cassandraLong(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ longlong *tmp= (longlong *) buff;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_long(tmp, value);
+ if (rc < 0)
+ return true;
+ *cass_data_len= sizeof(longlong);
+#ifdef WORDS_BIGENDIAN
+ *cass_data= (char *)buff;
+#else
+ flip64((char *)buff, (char *)buff + sizeof(longlong));
+ *cass_data= (char *)buff + sizeof(longlong);
+#endif
+ *freemem= NULL;
+ return false;
+}
+
bool cassandra_to_dyncol_intInt32(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
@@ -901,18 +929,57 @@ bool cassandra_to_dyncol_intInt32(const
value->x.long_value= tmp;
return 0;
}
+
+
+bool dyncol_to_cassandraInt32(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ longlong *tmp= (longlong *) ((char *)buff + sizeof(longlong));
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_long(tmp, value);
+ if (rc < 0)
+ return true;
+ *cass_data_len= sizeof(int32);
+ *cass_data= (char *)buff;
+#ifdef WORDS_BIGENDIAN
+ *((int32 *) buff) = (int32) *tmp;
+#else
+ {
+ int32 tmp2= (int32) *tmp;
+ flip32((char *)&tmp2, (char *)buff);
+ }
+#endif
+ *freemem= NULL;
+ return false;
+}
+
+
bool cassandra_to_dyncol_intCounter(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
{
value->type= DYN_COL_INT;
-#ifdef WORDS_BIGENDIAN
- flip64(cass_data, &value->x.long_value);
-#else
value->x.long_value= *((longlong *)cass_data);
-#endif
return 0;
}
+
+
+bool dyncol_to_cassandraCounter(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ longlong *tmp= (longlong *)buff;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_long(tmp, value);
+ if (rc < 0)
+ return true;
+ *cass_data_len= sizeof(longlong);
+ *cass_data= (char *)buff;
+ *freemem= NULL;
+ return false;
+}
+
bool cassandra_to_dyncol_doubleFloat(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
@@ -921,6 +988,23 @@ bool cassandra_to_dyncol_doubleFloat(con
value->x.double_value= *((float *)cass_data);
return 0;
}
+
+bool dyncol_to_cassandraFloat(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ double tmp;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_double(&tmp, value);
+ if (rc < 0)
+ return true;
+ *((float *)buff)= (float) tmp;
+ *cass_data_len= sizeof(float);
+ *cass_data= (char *)buff;
+ *freemem= NULL;
+ return false;
+}
+
bool cassandra_to_dyncol_doubleDouble(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
@@ -929,6 +1013,22 @@ bool cassandra_to_dyncol_doubleDouble(co
value->x.double_value= *((double *)cass_data);
return 0;
}
+
+bool dyncol_to_cassandraDouble(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ double *tmp= (double *)buff;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_double(tmp, value);
+ if (rc < 0)
+ return true;
+ *cass_data_len= sizeof(double);
+ *cass_data= (char *)buff;
+ *freemem= NULL;
+ return false;
+}
+
bool cassandra_to_dyncol_strStr(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value,
@@ -941,6 +1041,27 @@ bool cassandra_to_dyncol_strStr(const ch
value->x.string.nonfreeable= TRUE; // do not try to free
return 0;
}
+
+bool dyncol_to_cassandraStr(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem, CHARSET_INFO *cs)
+{
+ DYNAMIC_STRING tmp;
+ if (init_dynamic_string(&tmp, NULL, 1024, 1024))
+ return 1;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_str(&tmp, value, cs, FALSE);
+ if (rc < 0)
+ {
+ dynstr_free(&tmp);
+ return 1;
+ }
+ *cass_data_len= tmp.length;
+ *(cass_data)= tmp.str;
+ *freemem= tmp.str;
+ return 0;
+}
+
bool cassandra_to_dyncol_strBytes(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
@@ -948,6 +1069,15 @@ bool cassandra_to_dyncol_strBytes(const
return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value,
&my_charset_bin);
}
+
+bool dyncol_to_cassandraBytes(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ return dyncol_to_cassandraStr(value, cass_data, cass_data_len,
+ buff, freemem, &my_charset_bin);
+}
+
bool cassandra_to_dyncol_strAscii(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
@@ -955,6 +1085,15 @@ bool cassandra_to_dyncol_strAscii(const
return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value,
&my_charset_latin1_bin);
}
+
+bool dyncol_to_cassandraAscii(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ return dyncol_to_cassandraStr(value, cass_data, cass_data_len,
+ buff, freemem, &my_charset_latin1_bin);
+}
+
bool cassandra_to_dyncol_strUTF8(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
@@ -963,6 +1102,14 @@ bool cassandra_to_dyncol_strUTF8(const c
&my_charset_utf8_unicode_ci);
}
+bool dyncol_to_cassandraUTF8(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ return dyncol_to_cassandraStr(value, cass_data, cass_data_len,
+ buff, freemem, &my_charset_utf8_unicode_ci);
+}
+
bool cassandra_to_dyncol_strUUID(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
@@ -982,6 +1129,27 @@ bool cassandra_to_dyncol_strUUID(const c
return 0;
}
+bool dyncol_to_cassandraUUID(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ DYNAMIC_STRING tmp;
+ if (init_dynamic_string(&tmp, NULL, 1024, 1024))
+ return true;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_str(&tmp, value, &my_charset_latin1_bin, FALSE);
+ if (rc < 0 || tmp.length != 36 || convert_string2uuid((char *)buff, tmp.str))
+ {
+ dynstr_free(&tmp);
+ return true;
+ }
+
+ *cass_data_len= tmp.length;
+ *(cass_data)= tmp.str;
+ *freemem= tmp.str;
+ return 0;
+}
+
bool cassandra_to_dyncol_intBool(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
@@ -991,6 +1159,23 @@ bool cassandra_to_dyncol_intBool(const c
return 0;
}
+bool dyncol_to_cassandraBool(DYNAMIC_COLUMN_VALUE *value,
+ char **cass_data, int *cass_data_len,
+ void* buff, void **freemem)
+{
+ longlong tmp;
+ enum enum_dyncol_func_result rc=
+ dynamic_column_val_long(&tmp, value);
+ if (rc < 0)
+ return true;
+ ((char *)buff)[0]= (tmp ? 1 : 0);
+ *cass_data_len= 1;
+ *(cass_data)= (char *)buff;
+ *freemem= 0;
+ return 0;
+}
+
+
const char * const validator_bigint= "org.apache.cassandra.db.marshal.LongType";
const char * const validator_int= "org.apache.cassandra.db.marshal.Int32Type";
const char * const validator_counter= "org.apache.cassandra.db.marshal.CounterColumnType";
@@ -1016,47 +1201,58 @@ static CASSANDRA_TYPE_DEF cassandra_type
{
{
validator_bigint,
- &cassandra_to_dyncol_intLong
+ &cassandra_to_dyncol_intLong,
+ &dyncol_to_cassandraLong
},
{
validator_int,
- &cassandra_to_dyncol_intInt32
+ &cassandra_to_dyncol_intInt32,
+ &dyncol_to_cassandraInt32
},
{
validator_counter,
- cassandra_to_dyncol_intCounter
+ cassandra_to_dyncol_intCounter,
+ &dyncol_to_cassandraCounter
},
{
validator_float,
- &cassandra_to_dyncol_doubleFloat
+ &cassandra_to_dyncol_doubleFloat,
+ &dyncol_to_cassandraFloat
},
{
validator_double,
- &cassandra_to_dyncol_doubleDouble
+ &cassandra_to_dyncol_doubleDouble,
+ &dyncol_to_cassandraDouble
},
{
validator_blob,
- &cassandra_to_dyncol_strBytes
+ &cassandra_to_dyncol_strBytes,
+ &dyncol_to_cassandraBytes
},
{
validator_ascii,
- &cassandra_to_dyncol_strAscii
+ &cassandra_to_dyncol_strAscii,
+ &dyncol_to_cassandraAscii
},
{
validator_text,
- &cassandra_to_dyncol_strUTF8
+ &cassandra_to_dyncol_strUTF8,
+ &dyncol_to_cassandraUTF8
},
{
validator_timestamp,
- &cassandra_to_dyncol_intLong
+ &cassandra_to_dyncol_intLong,
+ &dyncol_to_cassandraLong
},
{
validator_uuid,
- &cassandra_to_dyncol_strUUID
+ &cassandra_to_dyncol_strUUID,
+ &dyncol_to_cassandraUUID
},
{
validator_boolean,
- &cassandra_to_dyncol_intBool
+ &cassandra_to_dyncol_intBool,
+ &dyncol_to_cassandraBool
}
};
@@ -1446,6 +1642,23 @@ void free_strings(DYNAMIC_COLUMN_VALUE *
}
+CASSANDRA_TYPE_DEF * ha_cassandra::get_cassandra_field_def(char *cass_name,
+ int cass_name_len)
+{
+ CASSANDRA_TYPE_DEF *type= default_type_def;
+ for(uint i= 0; i < n_special_type_fields; i++)
+ {
+ if (cass_name_len == (int)special_type_field_names[i].length &&
+ memcmp(cass_name, special_type_field_names[i].str,
+ cass_name_len) == 0)
+ {
+ type= special_type_field_converters + i;
+ break;
+ }
+ }
+ return type;
+}
+
int ha_cassandra::read_cassandra_columns(bool unpack_pk)
{
char *cass_name;
@@ -1496,18 +1709,8 @@ int ha_cassandra::read_cassandra_columns
{
DYNAMIC_COLUMN_VALUE val;
LEX_STRING nm;
- CASSANDRA_TYPE_DEF *type= default_type_def;
- for(uint i= 0; i < n_special_type_fields; i++)
- {
- if (cass_name_len == (int)special_type_field_names[i].length &&
- memcmp(cass_name, special_type_field_names[i].str,
- cass_name_len) == 0)
- {
- type= special_type_field_converters + i;
- break;
- }
- }
-
+ CASSANDRA_TYPE_DEF *type= get_cassandra_field_def(cass_name,
+ cass_name_len);
nm.str= cass_name;
nm.length= cass_name_len;
if ((*(type->cassandra_to_dynamic))(cass_value, cass_value_len, &val) ||
@@ -1569,6 +1772,69 @@ err:
return res;
}
+int ha_cassandra::write_dynamic_row()
+{
+ DYNAMIC_ARRAY vals, names;
+ String valcol, *strcol;
+ DYNAMIC_COLUMN col;
+ char *free_names;
+ uint i;
+ enum enum_dyncol_func_result rc;
+ DBUG_ENTER("ha_cassandra::write_dynamic_row");
+ DBUG_ASSERT(dyncol_set);
+
+ Field *field= table->field[dyncol_field];
+ DBUG_ASSERT(field->type() == MYSQL_TYPE_BLOB);
+ /* It is blob and it does not use buffer */
+ strcol= field->val_str(NULL, &valcol);
+ /*
+ dynamic_column_vals only read the string so we can
+ cheat here with assignment
+ */
+ bzero(&col, sizeof(col));
+ col.str= (char *)strcol->ptr();
+ col.length= strcol->length();
+ if ((rc= dynamic_column_vals(&col, &names, &vals, &free_names)) < 0)
+ {
+ dynamic_column_error_message(rc);
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
+ }
+ DBUG_ASSERT(names.elements == vals.elements);
+ for (i= 0; i < names.elements; i++)
+ {
+ char buff[16], stringname[256];
+ CASSANDRA_TYPE_DEF *type;
+ void *freemem= NULL;
+ char *cass_data;
+ int cass_data_len;
+ LEX_STRING *name= dynamic_element(&names, i, LEX_STRING*);
+ DYNAMIC_COLUMN_VALUE *val= dynamic_element(&vals, i, DYNAMIC_COLUMN_VALUE*);
+
+ DBUG_PRINT("info", ("field %*s", (int)name->length, name->str));
+ type= get_cassandra_field_def(name->str, (int) name->length);
+ if ((*type->dynamic_to_cassandra)(val, &cass_data, &cass_data_len,
+ buff, &freemem))
+ {
+ my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0),
+ name->str, insert_lineno);
+ DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
+ }
+ /* prepare \0 ending name */
+ DBUG_ASSERT(name->length < sizeof(stringname) - 1);
+ memcpy(stringname, (name->str), name->length);
+ stringname[name->length]= '\0';
+ se->add_insert_column(stringname,
+ cass_data, cass_data_len);
+ if (freemem)
+ my_free(freemem);
+ }
+
+ delete_dynamic(&names);
+ delete_dynamic(&vals);
+ if (free_names)
+ my_free(free_names);
+ DBUG_RETURN(0);
+}
int ha_cassandra::write_row(uchar *buf)
{
@@ -1599,15 +1865,26 @@ int ha_cassandra::write_row(uchar *buf)
{
char *cass_data;
int cass_data_len;
- if (field_converters[i]->mariadb_to_cassandra(&cass_data, &cass_data_len))
+ if (dyncol_set && dyncol_field == i)
{
- my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0),
- field_converters[i]->field->field_name, insert_lineno);
- dbug_tmp_restore_column_map(table->read_set, old_map);
- DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
+ int rc;
+ DBUG_ASSERT(field_converters[i] == NULL);
+ if ((rc= write_dynamic_row()))
+ return rc;
+ }
+ else
+ {
+ if (field_converters[i]->mariadb_to_cassandra(&cass_data,
+ &cass_data_len))
+ {
+ my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0),
+ field_converters[i]->field->field_name, insert_lineno);
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+ DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
+ }
+ se->add_insert_column(field_converters[i]->field->field_name,
+ cass_data, cass_data_len);
}
- se->add_insert_column(field_converters[i]->field->field_name,
- cass_data, cass_data_len);
}
dbug_tmp_restore_column_map(table->read_set, old_map);
=== modified file 'storage/cassandra/ha_cassandra.h'
--- a/storage/cassandra/ha_cassandra.h 2012-09-25 10:56:58 +0000
+++ b/storage/cassandra/ha_cassandra.h 2012-09-26 19:09:23 +0000
@@ -46,10 +46,15 @@ struct st_dynamic_column_value;
typedef bool (* CAS2DYN_CONVERTER)(const char *cass_data,
int cass_data_len,
struct st_dynamic_column_value *value);
+typedef bool (* DYN2CAS_CONVERTER)(struct st_dynamic_column_value *value,
+ char **cass_data,
+ int *cass_data_len,
+ void *buf, void **freemem);
struct cassandra_type_def
{
const char *name;
CAS2DYN_CONVERTER cassandra_to_dynamic;
+ DYN2CAS_CONVERTER dynamic_to_cassandra;
};
typedef struct cassandra_type_def CASSANDRA_TYPE_DEF;
@@ -222,6 +227,9 @@ private:
bool source_exhausted;
bool mrr_start_read();
int check_field_options(Field **fields);
+ int write_dynamic_row();
+ CASSANDRA_TYPE_DEF * get_cassandra_field_def(char *cass_name,
+ int cass_name_length);
public:
/*
More information about the commits
mailing list