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;
create table t1 (a int) engine=cassandra
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
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
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]
......@@ -15,36 +15,36 @@ create table t1 (rowkey char(10) primary key, column1 char(10)) engine=cassandra
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
# 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';
# Just in case there were left-overs from previous:
delete from t1;
select * from t1;
rowkey data1 data2
pk data1 data2
insert into t1 values ('rowkey10', 'data1-value', 123456);
insert into t1 values ('rowkey11', 'data1-value2', 34543);
insert into t1 values ('rowkey12', 'data1-value3', 454);
select * from t1;
rowkey data1 data2
pk data1 data2
rowkey12 data1-value3 454
rowkey10 data1-value 123456
rowkey11 data1-value2 34543
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
1 SIMPLE t1 const PRIMARY PRIMARY 38 const 1
select * from t1 where rowkey='rowkey11';
rowkey data1 data2
select * from t1 where pk='rowkey11';
pk data1 data2
rowkey11 data1-value2 34543
delete from t1 where rowkey='rowkey11';
delete from t1 where pk='rowkey11';
select * from t1;
rowkey data1 data2
pk data1 data2
rowkey12 data1-value3 454
rowkey10 data1-value 123456
rowkey11 NULL NULL
delete from t1;
select * from t1;
rowkey data1 data2
pk data1 data2
#
# A query with filesort (check that table_flags() & HA_REC_NOT_IN_SEQ,
# also check ::rnd_pos()
......@@ -53,7 +53,7 @@ insert into t1 values ('rowkey10', 'data1-value', 123456);
insert into t1 values ('rowkey11', 'data1-value2', 34543);
insert into t1 values ('rowkey12', 'data1-value3', 454);
select * from t1 order by data2;
rowkey data1 data2
pk data1 data2
rowkey12 data1-value3 454
rowkey11 data1-value2 34543
rowkey10 data1-value 123456
......@@ -183,3 +183,19 @@ count(*)
delete from t1;
drop table t1;
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;
create table t1 (a int) engine=cassandra
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
thrift_host='localhost' keyspace='foo' column_family='colfam';
......@@ -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 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
############################################################################
## Cassandra initialization ends
############################################################################
--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';
--echo # Just in case there were left-overs from previous:
......@@ -64,8 +73,8 @@ insert into t1 values ('rowkey12', 'data1-value3', 454);
select * from t1;
explain
select * from t1 where rowkey='rowkey11';
select * from t1 where rowkey='rowkey11';
select * from t1 where pk='rowkey11';
select * from t1 where pk='rowkey11';
# Deletion functions weirdly: it sets all columns to NULL
# but when If I do this in cassandra-cli:
......@@ -80,7 +89,7 @@ select * from t1 where rowkey='rowkey11';
#
# CQL seems to simply ignore all "incomplete" records.
delete from t1 where rowkey='rowkey11';
delete from t1 where pk='rowkey11';
select * from t1;
delete from t1;
......@@ -189,6 +198,27 @@ select count(*) from t1 where a=12345;
delete from t1;
drop table t1;
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
############################################################################
......
......@@ -342,23 +342,16 @@ int ha_cassandra::create(const char *name, TABLE *table_arg,
ha_table_option_struct *options= table_arg->s->option_struct;
DBUG_ENTER("ha_cassandra::create");
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;
/*
if (strcmp((*pfield)->field_name, "rowkey"))
{
my_error(ER_WRONG_COLUMN_NAME, MYF(0), "First column must be named 'rowkey'");
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
*/
if (!((*pfield)->flags & NOT_NULL_FLAG))
{
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,
table_arg->key_info[0].key_parts != 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);
}
#ifndef DBUG_OFF
/*
DBUG_PRINT("info", ("strparam: '%-.64s' ullparam: %llu enumparam: %u "\
......@@ -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
{
String buf;
......@@ -557,15 +580,16 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_
switch(field->type()) {
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
if (!strcmp(validator_name, validator_bigint))
res= new BigintDataConverter;
break;
case MYSQL_TYPE_FLOAT:
if (!strcmp(validator_name, validator_float))
res= new FloatDataConverter;
break;
case MYSQL_TYPE_DOUBLE:
if (!strcmp(validator_name, validator_double))
res= new DoubleDataConverter;
......@@ -581,6 +605,12 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_
res= new StringCopyConverter;
}
break;
case MYSQL_TYPE_LONG:
if (!strcmp(validator_name, validator_int))
res= new Int32DataConverter;
break;
default:;
}
return res;
......@@ -601,11 +631,6 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields)
bzero(field_converters, memsize);
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();
uint n_mapped= 0;
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)
return true;
/*
Setup type conversion for row_key. It may also have a name, but we ignore
it currently
Setup type conversion for row_key.
*/
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 (!(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