Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
6cce5204
Commit
6cce5204
authored
Aug 31, 2012
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cassandra SE
- add support for Cassandra's UUID datatype. We map it to CHAR(36).
parent
29e9406a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
222 additions
and
17 deletions
+222
-17
mysql-test/r/cassandra.result
mysql-test/r/cassandra.result
+34
-0
mysql-test/t/cassandra.test
mysql-test/t/cassandra.test
+49
-0
storage/cassandra/cassandra_se.cc
storage/cassandra/cassandra_se.cc
+1
-2
storage/cassandra/ha_cassandra.cc
storage/cassandra/ha_cassandra.cc
+135
-15
storage/cassandra/ha_cassandra.h
storage/cassandra/ha_cassandra.h
+3
-0
No files found.
mysql-test/r/cassandra.result
View file @
6cce5204
...
...
@@ -226,3 +226,37 @@ inserts insert_batches
delete from t2;
drop table t2;
drop table t0;
#
# UUID datatype support
#
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
delete from t2;
insert into t2 values(1,'9b5658dc-f32f-11e1-94cd-f46d046e9f09');
insert into t2 values(2,'not-an-uuid');
ERROR 22003: Out of range value for column 'uuidcol' at row 1
insert into t2 values(3,'9b5658dc-f32f-11e1=94cd-f46d046e9f09');
ERROR 22003: Out of range value for column 'uuidcol' at row 1
insert into t2 values(4,'9b5658dc-fzzf-11e1-94cd-f46d046e9f09');
ERROR 22003: Out of range value for column 'uuidcol' at row 1
insert into t2 values
(5,'9b5658dc-f11f-11e1-94cd-f46d046e9f09'),
(6,'9b5658dc-f11f011e1-94cd-f46d046e9f09');
ERROR 22003: Out of range value for column 'uuidcol' at row 2
select * from t2;
rowkey uuidcol
1 9b5658dc-f32f-11e1-94cd-f46d046e9f09
5 9b5658dc-f11f-11e1-94cd-f46d046e9f09
delete from t2;
drop table t2;
CREATE TABLE t2 (rowkey char(36) PRIMARY KEY, col1 int) ENGINE=CASSANDRA
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf6';
delete from t2;
insert into t2 values('9b5658dc-f32f-11e1-94cd-f46d046e9f09', 1234);
insert into t2 values('not-an-uuid', 563);
ERROR 22003: Out of range value for column 'rowkey' at row 1
select * from t2;
rowkey col1
9b5658dc-f32f-11e1-94cd-f46d046e9f09 1234
delete from t2;
drop table t2;
mysql-test/t/cassandra.test
View file @
6cce5204
...
...
@@ -49,6 +49,10 @@ create columnfamily cf3 (rowkey bigint primary key, intcol int);
create
columnfamily
cf4
(
rowkey
bigint
primary
key
,
datecol
timestamp
);
create
columnfamily
cf5
(
rowkey
bigint
primary
key
,
uuidcol
uuid
);
create
columnfamily
cf6
(
rowkey
uuid
primary
key
,
col1
int
);
./
cassandra
-
cli
CREATE
COLUMN
FAMILY
cf10
...
...
@@ -277,12 +281,57 @@ delete from t2;
drop
table
t2
;
drop
table
t0
;
--
echo
#
--
echo
# UUID datatype support
--
echo
#
#create columnfamily cf5 (rowkey bigint primary key, uuidcol uuid);
CREATE
TABLE
t2
(
rowkey
bigint
PRIMARY
KEY
,
uuidcol
char
(
36
))
ENGINE
=
CASSANDRA
thrift_host
=
'localhost'
keyspace
=
'mariadbtest2'
column_family
=
'cf5'
;
delete
from
t2
;
insert
into
t2
values
(
1
,
'9b5658dc-f32f-11e1-94cd-f46d046e9f09'
);
--
error
ER_WARN_DATA_OUT_OF_RANGE
insert
into
t2
values
(
2
,
'not-an-uuid'
);
--
error
ER_WARN_DATA_OUT_OF_RANGE
insert
into
t2
values
(
3
,
'9b5658dc-f32f-11e1=94cd-f46d046e9f09'
);
--
error
ER_WARN_DATA_OUT_OF_RANGE
insert
into
t2
values
(
4
,
'9b5658dc-fzzf-11e1-94cd-f46d046e9f09'
);
--
error
ER_WARN_DATA_OUT_OF_RANGE
insert
into
t2
values
(
5
,
'9b5658dc-f11f-11e1-94cd-f46d046e9f09'
),
(
6
,
'9b5658dc-f11f011e1-94cd-f46d046e9f09'
);
select
*
from
t2
;
delete
from
t2
;
drop
table
t2
;
# create columnfamily cf6 (rowkey uuid primary key, col1 int);
CREATE
TABLE
t2
(
rowkey
char
(
36
)
PRIMARY
KEY
,
col1
int
)
ENGINE
=
CASSANDRA
thrift_host
=
'localhost'
keyspace
=
'mariadbtest2'
column_family
=
'cf6'
;
delete
from
t2
;
insert
into
t2
values
(
'9b5658dc-f32f-11e1-94cd-f46d046e9f09'
,
1234
);
--
error
ER_WARN_DATA_OUT_OF_RANGE
insert
into
t2
values
(
'not-an-uuid'
,
563
);
select
*
from
t2
;
delete
from
t2
;
drop
table
t2
;
############################################################################
## Cassandra cleanup
############################################################################
--
disable_parsing
drop
columnfamily
cf1
;
drop
columnfamily
cf2
;
drop
columnfamily
cf3
;
drop
columnfamily
cf4
;
--
enable_parsing
############################################################################
## Cassandra cleanup ends
...
...
storage/cassandra/cassandra_se.cc
View file @
6cce5204
...
...
@@ -416,9 +416,8 @@ bool Cassandra_se_impl::get_range_slices(bool last_key_as_start_key)
cparent
.
column_family
=
column_family
;
/* SlicePredicate can be used to limit columns we will retrieve */
// Try passing nothing...
KeyRange
key_range
;
// Try passing nothing, too.
KeyRange
key_range
;
key_range
.
__isset
.
start_key
=
true
;
key_range
.
__isset
.
end_key
=
true
;
...
...
storage/cassandra/ha_cassandra.cc
View file @
6cce5204
...
...
@@ -302,6 +302,7 @@ int ha_cassandra::open(const char *name, int mode, uint test_if_locked)
}
info
(
HA_STATUS_NO_LOCK
|
HA_STATUS_VARIABLE
|
HA_STATUS_CONST
);
insert_lineno
=
0
;
DBUG_RETURN
(
0
);
}
...
...
@@ -407,6 +408,7 @@ int ha_cassandra::create(const char *name, TABLE *table_arg,
my_error
(
ER_CONNECT_TO_FOREIGN_DATA_SOURCE
,
MYF
(
0
),
"setup_field_converters"
);
DBUG_RETURN
(
HA_ERR_NO_CONNECTION
);
}
insert_lineno
=
0
;
DBUG_RETURN
(
0
);
}
...
...
@@ -430,8 +432,13 @@ class ColumnDataConverter
/*
This will get data from the Field pointer, store Cassandra's form
in internal buffer, and return pointer/size.
@return
false - OK
true - Failed to convert value (completely, there is no value to insert
at all).
*/
virtual
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
=
0
;
virtual
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
=
0
;
virtual
~
ColumnDataConverter
()
{};
};
...
...
@@ -447,11 +454,12 @@ class DoubleDataConverter : public ColumnDataConverter
field
->
store
(
*
pdata
);
}
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
{
buf
=
field
->
val_real
();
*
cass_data
=
(
char
*
)
&
buf
;
*
cass_data_len
=
sizeof
(
double
);
return
false
;
}
~
DoubleDataConverter
(){}
};
...
...
@@ -468,11 +476,12 @@ class FloatDataConverter : public ColumnDataConverter
field
->
store
(
*
pdata
);
}
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
{
buf
=
field
->
val_real
();
*
cass_data
=
(
char
*
)
&
buf
;
*
cass_data_len
=
sizeof
(
float
);
return
false
;
}
~
FloatDataConverter
(){}
};
...
...
@@ -501,12 +510,13 @@ class BigintDataConverter : public ColumnDataConverter
field
->
store
(
tmp
);
}
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
{
longlong
tmp
=
field
->
val_int
();
flip64
((
const
char
*
)
&
tmp
,
(
char
*
)
&
buf
);
*
cass_data
=
(
char
*
)
&
buf
;
*
cass_data_len
=
sizeof
(
longlong
);
return
false
;
}
~
BigintDataConverter
(){}
};
...
...
@@ -531,12 +541,13 @@ class Int32DataConverter : public ColumnDataConverter
field
->
store
(
tmp
);
}
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
{
int32_t
tmp
=
field
->
val_int
();
flip32
((
const
char
*
)
&
tmp
,
(
char
*
)
&
buf
);
*
cass_data
=
(
char
*
)
&
buf
;
*
cass_data_len
=
sizeof
(
int32_t
);
return
false
;
}
~
Int32DataConverter
(){}
};
...
...
@@ -551,11 +562,12 @@ class StringCopyConverter : public ColumnDataConverter
field
->
store
(
cass_data
,
cass_data_len
,
field
->
charset
());
}
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
{
String
*
pstr
=
field
->
val_str
(
&
buf
);
*
cass_data
=
(
char
*
)
pstr
->
c_ptr
();
*
cass_data_len
=
pstr
->
length
();
return
false
;
}
~
StringCopyConverter
(){}
};
...
...
@@ -579,7 +591,7 @@ class TimestampDataConverter : public ColumnDataConverter
((
Field_timestamp
*
)
field
)
->
store_TIME
(
tmp
/
1000
,
(
tmp
%
1000
)
*
1000
);
}
void
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
bool
mariadb_to_cassandra
(
char
**
cass_data
,
int
*
cass_data_len
)
{
my_time_t
ts_time
;
ulong
ts_microsec
;
...
...
@@ -592,10 +604,85 @@ class TimestampDataConverter : public ColumnDataConverter
*
cass_data
=
(
char
*
)
&
buf
;
*
cass_data_len
=
8
;
return
false
;
}
~
TimestampDataConverter
(){}
};
static
int
convert_hex_digit
(
const
char
c
)
{
int
num
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
num
=
c
-
'0'
;
else
if
(
c
>=
'A'
&&
c
<=
'F'
)
num
=
c
-
'A'
+
10
;
else
if
(
c
>=
'a'
&&
c
<=
'f'
)
num
=
c
-
'a'
+
10
;
else
return
-
1
;
/* Couldn't convert */
return
num
;
}
const
char
map2number
[]
=
"0123456789abcdef"
;
class
UuidDataConverter
:
public
ColumnDataConverter
{
char
buf
[
16
];
/* Binary UUID representation */
String
str_buf
;
public:
void
cassandra_to_mariadb
(
const
char
*
cass_data
,
int
cass_data_len
)
{
DBUG_ASSERT
(
cass_data_len
==
16
);
char
str
[
37
];
char
*
ptr
=
str
;
/* UUID arrives as 16-byte number in network byte order */
for
(
uint
i
=
0
;
i
<
16
;
i
++
)
{
*
(
ptr
++
)
=
map2number
[(
cass_data
[
i
]
>>
4
)
&
0xF
];
*
(
ptr
++
)
=
map2number
[
cass_data
[
i
]
&
0xF
];
if
(
i
==
3
||
i
==
5
||
i
==
7
||
i
==
9
)
*
(
ptr
++
)
=
'-'
;
}
*
ptr
=
0
;
field
->
store
(
str
,
36
,
field
->
charset
());
}
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
)
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
;
}
~
UuidDataConverter
(){}
};
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"
;
...
...
@@ -609,6 +696,8 @@ const char * const validator_text= "org.apache.cassandra.db.marshal.UTF8Type"
const
char
*
const
validator_timestamp
=
"org.apache.cassandra.db.marshal.DateType"
;
const
char
*
const
validator_uuid
=
"org.apache.cassandra.db.marshal.UUIDType"
;
ColumnDataConverter
*
map_field_to_validator
(
Field
*
field
,
const
char
*
validator_name
)
{
ColumnDataConverter
*
res
=
NULL
;
...
...
@@ -617,8 +706,7 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_
case
MYSQL_TYPE_TINY
:
case
MYSQL_TYPE_SHORT
:
case
MYSQL_TYPE_LONGLONG
:
if
(
!
strcmp
(
validator_name
,
validator_bigint
)
||
0
/*!strcmp(validator_name, validator_timestamp)*/
)
if
(
!
strcmp
(
validator_name
,
validator_bigint
))
res
=
new
BigintDataConverter
;
break
;
...
...
@@ -637,9 +725,18 @@ ColumnDataConverter *map_field_to_validator(Field *field, const char *validator_
res
=
new
TimestampDataConverter
;
break
;
case
MYSQL_TYPE_VAR_STRING
:
case
MYSQL_TYPE_STRING
:
// these are space padded CHAR(n) strings.
if
(
!
strcmp
(
validator_name
,
validator_uuid
)
&&
field
->
real_type
()
==
MYSQL_TYPE_STRING
&&
field
->
field_length
==
36
)
{
// UUID maps to CHAR(36), its text representation
res
=
new
UuidDataConverter
;
break
;
}
/* fall through: */
case
MYSQL_TYPE_VARCHAR
:
case
MYSQL_TYPE_
STRING
:
// these are space padded strings.
case
MYSQL_TYPE_
VAR_STRING
:
if
(
!
strcmp
(
validator_name
,
validator_blob
)
||
!
strcmp
(
validator_name
,
validator_ascii
)
||
!
strcmp
(
validator_name
,
validator_text
))
...
...
@@ -698,7 +795,11 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields)
}
if
(
n_mapped
!=
n_fields
-
1
)
{
se
->
print_error
(
"Some of SQL fields were not mapped to Cassandra's fields"
);
my_error
(
ER_INTERNAL_ERROR
,
MYF
(
0
),
se
->
error_str
());
return
true
;
}
/*
Setup type conversion for row_key.
...
...
@@ -775,7 +876,11 @@ int ha_cassandra::index_read_map(uchar *buf, const uchar *key,
old_map
=
dbug_tmp_use_all_columns
(
table
,
table
->
read_set
);
rowkey_converter
->
mariadb_to_cassandra
(
&
cass_key
,
&
cass_key_len
);
if
(
rowkey_converter
->
mariadb_to_cassandra
(
&
cass_key
,
&
cass_key_len
))
{
/* We get here when making lookups like uuid_column='not-an-uuid' */
DBUG_RETURN
(
HA_ERR_KEY_NOT_FOUND
);
}
dbug_tmp_restore_column_map
(
table
->
read_set
,
old_map
);
...
...
@@ -858,10 +963,18 @@ int ha_cassandra::write_row(uchar *buf)
old_map
=
dbug_tmp_use_all_columns
(
table
,
table
->
read_set
);
insert_lineno
++
;
/* Convert the key */
char
*
cass_key
;
int
cass_key_len
;
rowkey_converter
->
mariadb_to_cassandra
(
&
cass_key
,
&
cass_key_len
);
if
(
rowkey_converter
->
mariadb_to_cassandra
(
&
cass_key
,
&
cass_key_len
))
{
my_error
(
ER_WARN_DATA_OUT_OF_RANGE
,
MYF
(
0
),
rowkey_converter
->
field
->
field_name
,
insert_lineno
);
dbug_tmp_restore_column_map
(
table
->
read_set
,
old_map
);
DBUG_RETURN
(
HA_ERR_AUTOINC_ERANGE
);
}
se
->
start_row_insert
(
cass_key
,
cass_key_len
);
/* Convert other fields */
...
...
@@ -869,7 +982,13 @@ int ha_cassandra::write_row(uchar *buf)
{
char
*
cass_data
;
int
cass_data_len
;
field_converters
[
i
]
->
mariadb_to_cassandra
(
&
cass_data
,
&
cass_data_len
);
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
);
}
...
...
@@ -892,7 +1011,7 @@ int ha_cassandra::write_row(uchar *buf)
if
(
res
)
my_error
(
ER_INTERNAL_ERROR
,
MYF
(
0
),
se
->
error_str
());
DBUG_RETURN
(
res
?
HA_ERR_INTERNAL_ERROR
:
0
);
}
...
...
@@ -1060,6 +1179,7 @@ int ha_cassandra::rnd_pos(uchar *buf, uchar *pos)
int
ha_cassandra
::
reset
()
{
doing_insert_batch
=
false
;
insert_lineno
=
0
;
return
0
;
}
...
...
storage/cassandra/ha_cassandra.h
View file @
6cce5204
...
...
@@ -48,6 +48,9 @@ class ha_cassandra: public handler
bool
doing_insert_batch
;
ha_rows
insert_rows_batched
;
/* Used to produce 'wrong column %s at row %lu' warnings */
ha_rows
insert_lineno
;
public:
ha_cassandra
(
handlerton
*
hton
,
TABLE_SHARE
*
table_arg
);
~
ha_cassandra
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment