Commit 22e71e4c authored by Sergey Petrunya's avatar Sergey Petrunya

Cassandra SE

- Add mapping for INT datatype
- Primary key column should now be named like CQL's primary key, 
  or 'rowkey' if CF has key_alias.
parent c34b24ff
drop table if exists t0, t1; drop table if exists t0, t1;
create table t1 (a int) engine=cassandra create table t1 (a int) engine=cassandra
thrift_host='localhost' keyspace='foo' column_family='colfam'; thrift_host='localhost' keyspace='foo' column_family='colfam';
ERROR 42000: Incorrect column name 'First column must be named 'rowkey'' ERROR 42000: Incorrect column name 'First column must be NOT NULL'
create table t1 (a int primary key, b int) engine=cassandra create table t1 (a int primary key, b int) engine=cassandra
thrift_host='localhost' keyspace='foo' column_family='colfam'; thrift_host='localhost' keyspace='foo' column_family='colfam';
ERROR 42000: Incorrect column name 'First column must be named 'rowkey'' ERROR HY000: Unable to connect to foreign data source: Default TException. [Keyspace foo does not exist]
create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra
thrift_host='127.0.0.2' keyspace='foo' column_family='colfam'; thrift_host='127.0.0.2' keyspace='foo' column_family='colfam';
ERROR HY000: Unable to connect to foreign data source: connect() failed: Connection refused [1] ERROR HY000: Unable to connect to foreign data source: connect() failed: Connection refused [1]
...@@ -15,36 +15,36 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra ...@@ -15,36 +15,36 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra
thrift_host='localhost' keyspace='no_such_keyspace'; thrift_host='localhost' keyspace='no_such_keyspace';
ERROR HY000: Unable to connect to foreign data source: thrift_host, keyspace, and column_family table options must be s ERROR HY000: Unable to connect to foreign data source: thrift_host, keyspace, and column_family table options must be s
# Now, create a table for real and insert data # Now, create a table for real and insert data
create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra
thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1';
# Just in case there were left-overs from previous: # Just in case there were left-overs from previous:
delete from t1; delete from t1;
select * from t1; select * from t1;
rowkey data1 data2 pk data1 data2
insert into t1 values ('rowkey10', 'data1-value', 123456); insert into t1 values ('rowkey10', 'data1-value', 123456);
insert into t1 values ('rowkey11', 'data1-value2', 34543); insert into t1 values ('rowkey11', 'data1-value2', 34543);
insert into t1 values ('rowkey12', 'data1-value3', 454); insert into t1 values ('rowkey12', 'data1-value3', 454);
select * from t1; select * from t1;
rowkey data1 data2 pk data1 data2
rowkey12 data1-value3 454 rowkey12 data1-value3 454
rowkey10 data1-value 123456 rowkey10 data1-value 123456
rowkey11 data1-value2 34543 rowkey11 data1-value2 34543
explain explain
select * from t1 where rowkey='rowkey11'; select * from t1 where pk='rowkey11';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 38 const 1 1 SIMPLE t1 const PRIMARY PRIMARY 38 const 1
select * from t1 where rowkey='rowkey11'; select * from t1 where pk='rowkey11';
rowkey data1 data2 pk data1 data2
rowkey11 data1-value2 34543 rowkey11 data1-value2 34543
delete from t1 where rowkey='rowkey11'; delete from t1 where pk='rowkey11';
select * from t1; select * from t1;
rowkey data1 data2 pk data1 data2
rowkey12 data1-value3 454 rowkey12 data1-value3 454
rowkey10 data1-value 123456 rowkey10 data1-value 123456
rowkey11 NULL NULL rowkey11 NULL NULL
delete from t1; delete from t1;
select * from t1; select * from t1;
rowkey data1 data2 pk data1 data2
# #
# A query with filesort (check that table_flags() & HA_REC_NOT_IN_SEQ, # A query with filesort (check that table_flags() & HA_REC_NOT_IN_SEQ,
# also check ::rnd_pos() # also check ::rnd_pos()
...@@ -53,7 +53,7 @@ insert into t1 values ('rowkey10', 'data1-value', 123456); ...@@ -53,7 +53,7 @@ insert into t1 values ('rowkey10', 'data1-value', 123456);
insert into t1 values ('rowkey11', 'data1-value2', 34543); insert into t1 values ('rowkey11', 'data1-value2', 34543);
insert into t1 values ('rowkey12', 'data1-value3', 454); insert into t1 values ('rowkey12', 'data1-value3', 454);
select * from t1 order by data2; select * from t1 order by data2;
rowkey data1 data2 pk data1 data2
rowkey12 data1-value3 454 rowkey12 data1-value3 454
rowkey11 data1-value2 34543 rowkey11 data1-value2 34543
rowkey10 data1-value 123456 rowkey10 data1-value 123456
...@@ -183,3 +183,19 @@ count(*) ...@@ -183,3 +183,19 @@ count(*)
delete from t1; delete from t1;
drop table t1; drop table t1;
drop table t0; drop table t0;
# 32-bit INT type support
CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, intcol INT) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3';
insert into t1 values (10,10);
insert into t1 values (12,12);
delete from t1;
drop table t1;
#
# Try accessing column family w/o explicitly defined columns
#
CREATE TABLE t1 (my_primary_key varchar(10) PRIMARY KEY) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10';
ERROR HY000: Internal error: 'target column family has no key_alias defined, PRIMARY KEY column must be named 'rowkey''
CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10';
DROP TABLE t1;
...@@ -12,7 +12,7 @@ drop table if exists t0, t1; ...@@ -12,7 +12,7 @@ drop table if exists t0, t1;
create table t1 (a int) engine=cassandra create table t1 (a int) engine=cassandra
thrift_host='localhost' keyspace='foo' column_family='colfam'; thrift_host='localhost' keyspace='foo' column_family='colfam';
--error ER_WRONG_COLUMN_NAME --error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
create table t1 (a int primary key, b int) engine=cassandra create table t1 (a int primary key, b int) engine=cassandra
thrift_host='localhost' keyspace='foo' column_family='colfam'; thrift_host='localhost' keyspace='foo' column_family='colfam';
...@@ -45,13 +45,22 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint); ...@@ -45,13 +45,22 @@ create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint);
create columnfamily cf2 (rowkey bigint primary key, a bigint); create columnfamily cf2 (rowkey bigint primary key, a bigint);
create columnfamily cf3 (rowkey bigint primary key, intcol int);
./cassandra-cli
CREATE COLUMN FAMILY cf10
WITH comparator = UTF8Type
AND key_validation_class=UTF8Type
AND default_validation_class = UTF8Type;
--enable_parsing --enable_parsing
############################################################################ ############################################################################
## Cassandra initialization ends ## Cassandra initialization ends
############################################################################ ############################################################################
--echo # Now, create a table for real and insert data --echo # Now, create a table for real and insert data
create table t1 (rowkey varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra create table t1 (pk varchar(36) primary key, data1 varchar(60), data2 bigint) engine=cassandra
thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1'; thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1';
--echo # Just in case there were left-overs from previous: --echo # Just in case there were left-overs from previous:
...@@ -64,8 +73,8 @@ insert into t1 values ('rowkey12', 'data1-value3', 454); ...@@ -64,8 +73,8 @@ insert into t1 values ('rowkey12', 'data1-value3', 454);
select * from t1; select * from t1;
explain explain
select * from t1 where rowkey='rowkey11'; select * from t1 where pk='rowkey11';
select * from t1 where rowkey='rowkey11'; select * from t1 where pk='rowkey11';
# Deletion functions weirdly: it sets all columns to NULL # Deletion functions weirdly: it sets all columns to NULL
# but when If I do this in cassandra-cli: # but when If I do this in cassandra-cli:
...@@ -80,7 +89,7 @@ select * from t1 where rowkey='rowkey11'; ...@@ -80,7 +89,7 @@ select * from t1 where rowkey='rowkey11';
# #
# CQL seems to simply ignore all "incomplete" records. # CQL seems to simply ignore all "incomplete" records.
delete from t1 where rowkey='rowkey11'; delete from t1 where pk='rowkey11';
select * from t1; select * from t1;
delete from t1; delete from t1;
...@@ -189,6 +198,27 @@ select count(*) from t1 where a=12345; ...@@ -189,6 +198,27 @@ select count(*) from t1 where a=12345;
delete from t1; delete from t1;
drop table t1; drop table t1;
drop table t0; drop table t0;
--echo # 32-bit INT type support
CREATE TABLE t1 (rowkey BIGINT PRIMARY KEY, intcol INT) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3';
insert into t1 values (10,10);
insert into t1 values (12,12);
delete from t1;
drop table t1;
--echo #
--echo # Try accessing column family w/o explicitly defined columns
--echo #
--error ER_INTERNAL_ERROR
CREATE TABLE t1 (my_primary_key varchar(10) PRIMARY KEY) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10';
CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf10';
DROP TABLE t1;
############################################################################ ############################################################################
## Cassandra cleanup ## Cassandra cleanup
############################################################################ ############################################################################
......
...@@ -342,23 +342,16 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, ...@@ -342,23 +342,16 @@ int ha_cassandra::create(const char *name, TABLE *table_arg,
ha_table_option_struct *options= table_arg->s->option_struct; ha_table_option_struct *options= table_arg->s->option_struct;
DBUG_ENTER("ha_cassandra::create"); DBUG_ENTER("ha_cassandra::create");
DBUG_ASSERT(options); DBUG_ASSERT(options);
//psergey-todo: This is called for CREATE TABLE... check options here.
/*
if (table_arg->s->fields != 2)
{
my_error(ER_WRONG_COLUMN_NAME, MYF(0), "The table must have two fields");
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
*/
Field **pfield= table_arg->s->field; Field **pfield= table_arg->s->field;
/*
if (strcmp((*pfield)->field_name, "rowkey")) if (strcmp((*pfield)->field_name, "rowkey"))
{ {
my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be named 'rowkey'"); my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be named 'rowkey'");
DBUG_RETURN(HA_WRONG_CREATE_OPTION); DBUG_RETURN(HA_WRONG_CREATE_OPTION);
} }
*/
if (!((*pfield)->flags & NOT_NULL_FLAG)) if (!((*pfield)->flags & NOT_NULL_FLAG))
{ {
my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be NOT NULL"); my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be NOT NULL");
...@@ -369,11 +362,11 @@ int ha_cassandra::create(const char *name, TABLE *table_arg, ...@@ -369,11 +362,11 @@ int ha_cassandra::create(const char *name, TABLE *table_arg,
table_arg->key_info[0].key_parts != 1 || table_arg->key_info[0].key_parts != 1 ||
table_arg->key_info[0].key_part[0].fieldnr != 1) table_arg->key_info[0].key_part[0].fieldnr != 1)
{ {
my_error(ER_WRONG_COLUMN_NAME, MYF(0), "Table must have one PRIMARY KEY(rowkey)"); my_error(ER_WRONG_COLUMN_NAME, MYF(0),
"Table must have PRIMARY KEY defined over the first column");
DBUG_RETURN(HA_WRONG_CREATE_OPTION); DBUG_RETURN(HA_WRONG_CREATE_OPTION);
} }
#ifndef DBUG_OFF #ifndef DBUG_OFF
/* /*
DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\ DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\
...@@ -519,6 +512,36 @@ class BigintDataConverter : public ColumnDataConverter ...@@ -519,6 +512,36 @@ class BigintDataConverter : public ColumnDataConverter
}; };
class Int32DataConverter : public ColumnDataConverter
{
int32_t buf;
public:
void flip(const char *from, char* to)
{
to[0]= from[3];
to[1]= from[2];
to[2]= from[1];
to[3]= from[0];
}
void cassandra_to_mariadb(const char *cass_data, int cass_data_len)
{
int32_t tmp;
DBUG_ASSERT(cass_data_len == sizeof(int32_t));
flip(cass_data, (char*)&tmp);
field->store(tmp);
}
void mariadb_to_cassandra(char **cass_data, int *cass_data_len)
{
int32_t tmp= field->val_int();
flip((const char*)&tmp, (char*)&buf);
*cass_data= (char*)&buf;
*cass_data_len=sizeof(int32_t);
}
~Int32DataConverter(){}
};
class StringCopyConverter : public ColumnDataConverter class StringCopyConverter : public ColumnDataConverter
{ {
String buf; String buf;
...@@ -557,15 +580,16 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ ...@@ -557,15 +580,16 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_
switch(field->type()) { switch(field->type()) {
case MYSQL_TYPE_TINY: case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT: case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_LONGLONG:
if (!strcmp(validator_name, validator_bigint)) if (!strcmp(validator_name, validator_bigint))
res= new BigintDataConverter; res= new BigintDataConverter;
break; break;
case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_FLOAT:
if (!strcmp(validator_name, validator_float)) if (!strcmp(validator_name, validator_float))
res= new FloatDataConverter; res= new FloatDataConverter;
break; break;
case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_DOUBLE:
if (!strcmp(validator_name, validator_double)) if (!strcmp(validator_name, validator_double))
res= new DoubleDataConverter; res= new DoubleDataConverter;
...@@ -581,6 +605,12 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_ ...@@ -581,6 +605,12 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_
res= new StringCopyConverter; res= new StringCopyConverter;
} }
break; break;
case MYSQL_TYPE_LONG:
if (!strcmp(validator_name, validator_int))
res= new Int32DataConverter;
break;
default:; default:;
} }
return res; return res;
...@@ -601,11 +631,6 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) ...@@ -601,11 +631,6 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields)
bzero(field_converters, memsize); bzero(field_converters, memsize);
n_field_converters= n_fields; n_field_converters= n_fields;
/*
TODO: what about mapping the primary key? It has a 'type', too...
see CfDef::key_validation_class ? see also CfDef::key_alias?
*/
se->first_ddl_column(); se->first_ddl_column();
uint n_mapped= 0; uint n_mapped= 0;
while (!se->next_ddl_column(&col_name, &col_name_len, &col_type, while (!se->next_ddl_column(&col_name, &col_name_len, &col_type,
...@@ -634,10 +659,23 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields) ...@@ -634,10 +659,23 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields)
return true; return true;
/* /*
Setup type conversion for row_key. It may also have a name, but we ignore Setup type conversion for row_key.
it currently
*/ */
se->get_rowkey_type(&col_name, &col_type); se->get_rowkey_type(&col_name, &col_type);
if (col_name && strcmp(col_name, (*field_arg)->field_name))
{
se->print_error("PRIMARY KEY column must match Cassandra's name '%s'", col_name);
my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str());
return true;
}
if (!col_name && strcmp("rowkey", (*field_arg)->field_name))
{
se->print_error("target column family has no key_alias defined, "
"PRIMARY KEY column must be named 'rowkey'");
my_error(ER_INTERNAL_ERROR, MYF(0), se->error_str());
return true;
}
if (col_type != NULL) if (col_type != NULL)
{ {
if (!(rowkey_converter= map_field_to_validator(*field_arg, col_type))) if (!(rowkey_converter= map_field_to_validator(*field_arg, col_type)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment